文章目录
- 一、Android 中使用 7zr 可执行程序压缩文件
- 二、完整代码示例
- 三、参考资料
一、Android 中使用 7zr 可执行程序压缩文件
在上一篇博客 【Android 安装包优化】Android 应用中 7zr 可执行程序准备 ( Android Studio 导入可执行 7zr 程序 | 从 Assets 资源文件拷贝 7zr 到内置存储 ) 中 , 将 7zr 可执行文件拷贝到了应用内置目录 " /data/user/0/kim.hsl.a7_zip/files/ " 中 , 只有放在该目录下 , 才能执行该 7zr 可执行程序 ;
判定命令是否执行完毕 : 调用 Process 的 exitValue 方法 , 获取退出码 , 如果返回 0 说明执行成功 ; 如果捕获到 IllegalThreadStateException 异常 , 说明命令还在执行中 ;
代码语言:javascript复制 /**
* 判定命令是否执行完毕
* 调用 process.exitValue 方法 , 如果没有执行完毕 , 会抛异常,
* 如果执行完毕会返回一个确定的值
*/
fun isComplete(process: Process): Boolean {
try {
// 已经执行完毕
process.exitValue()
return true
} catch (e: IllegalThreadStateException) {
// 未执行完毕
return false
}
}
拼装 7zr 压缩命令 :
代码语言:javascript复制var cmd = "${exeFile.absolutePath} a ${filesDir.absolutePath}/files.7z ${filesDir.absolutePath} -mx=9 -t7z"
执行命令行 :
代码语言:javascript复制var process: Process = Runtime.getRuntime().exec(cmd)
使用 7zr 命令压缩文件 :
代码语言:javascript复制 /**
* 使用 7zr 进行压缩
*/
fun compress7z() {
// /data/user/0/kim.hsl.a7_zip/files/7zr
var exeFile = File(filesDir, "7zr")
// 执行前赋予可执行权限
exeFile.setExecutable(true)
var cmd = "${exeFile.absolutePath} a ${filesDir.absolutePath}/files.7z ${filesDir.absolutePath} -mx=9 -t7z"
Log.i(TAG, "压缩命令 : $cmd")
var process: Process = Runtime.getRuntime().exec(cmd)
// 读取命令执行过程数据
var reader = BufferedReader(InputStreamReader(process.inputStream))
while (true) {
val line = reader.readLine()
if (line != null) {
Log.i(TAG, "$line")
}else{
break
}
}
val exitValue = process.exitValue()
Log.i(TAG, "执行完毕 , exitValue = $exitValue")
}
二、完整代码示例
完整代码 :
代码语言:javascript复制package kim.hsl.a7_zip
import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import java.io.*
class MainActivity : AppCompatActivity() {
companion object {
val TAG = "MainActivity"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
copy7zr()
compress7z()
}
/**
* 将 7zr 文件拷贝到应用私有目录
*/
fun copy7zr() {
Log.i(TAG, "开始拷贝 7zr 文件")
// /data/user/0/kim.hsl.a7_zip/files/7zr
var exeFile = File(filesDir, "7zr")
Log.i(TAG, "filesDir = ${filesDir.absolutePath} , exeFile = ${exeFile.absolutePath}")
// 查看该文件是否存在, 如果存在设置该文件可执行
// 如果不存在 , 拷贝文件
if (exeFile.exists()) {
exeFile.setExecutable(true)
Log.i(TAG, "内置存储空间存在该 /data/user/0/kim.hsl.a7_zip/files/7zr 文件")
return
} else {
Log.i(TAG, "内置存储空间不存在 7zr 可执行文件 , 开始拷贝文件")
}
// 如果不存在 , 拷贝文件
var inputStream: InputStream = assets.open("libs/arm64-v8a/7zr")
// /data/user/0/kim.hsl.a7_zip/files/7zr
var fileOutputStream: FileOutputStream = FileOutputStream(exeFile)
Log.i(TAG, "Build.CPU_ABI = ${Build.CPU_ABI}")
// 不同 CPU 架构拷贝不同的可执行程序
if (Build.CPU_ABI.startsWith("armeabi-v7a")) {
inputStream = assets.open("libs/armeabi-v7a/7zr")
} else if (Build.CPU_ABI.startsWith("arm64-v8a")) {
inputStream = assets.open("libs/arm64-v8a/7zr")
} else if (Build.CPU_ABI.startsWith("x86")) {
inputStream = assets.open("libs/x86/7zr")
} else if (Build.CPU_ABI.startsWith("x86_64")) {
inputStream = assets.open("libs/x86_64/7zr")
}
// 拷贝文件
var buffer: ByteArray = ByteArray(1024)
var readCount = inputStream.read(buffer);
while (readCount != -1) {
fileOutputStream.write(buffer)
readCount = inputStream.read(buffer);
}
fileOutputStream.flush()
fileOutputStream.close()
Log.i(TAG, "拷贝 7zr 文件结束")
}
/**
* 使用 7zr 进行压缩
*/
fun compress7z() {
// /data/user/0/kim.hsl.a7_zip/files/7zr
var exeFile = File(filesDir, "7zr")
// 执行前赋予可执行权限
exeFile.setExecutable(true)
var cmd = "${exeFile.absolutePath} a ${filesDir.absolutePath}/files.7z ${filesDir.absolutePath} -mx=9 -t7z"
Log.i(TAG, "压缩命令 : $cmd")
var process: Process = Runtime.getRuntime().exec(cmd)
// 读取命令执行过程数据
var reader = BufferedReader(InputStreamReader(process.inputStream))
while (true) {
val line = reader.readLine()
if (line != null) {
Log.i(TAG, "$line")
}else{
break
}
}
val exitValue = process.exitValue()
Log.i(TAG, "执行完毕 , exitValue = $exitValue")
}
/**
* 判定命令是否执行完毕
* 调用 process.exitValue 方法 , 如果没有执行完毕 , 会抛异常,
* 如果执行完毕会返回一个确定的值
*/
fun isComplete(process: Process): Boolean {
try {
// 已经执行完毕
process.exitValue()
return true
} catch (e: IllegalThreadStateException) {
// 未执行完毕
return false
}
}
}
执行结果 :
代码语言:javascript复制2021-04-29 22:07:06.867 8965-8965/kim.hsl.a7_zip I/MainActivity: 开始拷贝 7zr 文件
2021-04-29 22:07:06.869 8965-8965/kim.hsl.a7_zip I/MainActivity: filesDir = /data/user/0/kim.hsl.a7_zip/files , exeFile = /data/user/0/kim.hsl.a7_zip/files/7zr
2021-04-29 22:07:06.869 8965-8965/kim.hsl.a7_zip I/MainActivity: 内置存储空间不存在 7zr 可执行文件 , 开始拷贝文件
2021-04-29 22:07:06.869 8965-8965/kim.hsl.a7_zip I/MainActivity: Build.CPU_ABI = arm64-v8a
2021-04-29 22:07:06.897 8965-8965/kim.hsl.a7_zip I/MainActivity: 拷贝 7zr 文件结束
2021-04-29 22:07:06.897 8965-8965/kim.hsl.a7_zip I/MainActivity: 压缩命令 : /data/user/0/kim.hsl.a7_zip/files/7zr a /data/user/0/kim.hsl.a7_zip/files/files.7z /data/user/0/kim.hsl.a7_zip/files -mx=9 -t7z
2021-04-29 22:07:07.262 8965-8965/kim.hsl.a7_zip I/MainActivity: 7-Zip (a) [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
2021-04-29 22:07:07.262 8965-8965/kim.hsl.a7_zip I/MainActivity: p7zip Version 16.02 (locale=utf8,Utf16=on,HugeFiles=on,64 bits,8 CPUs LE)
2021-04-29 22:07:07.262 8965-8965/kim.hsl.a7_zip I/MainActivity: Scanning the drive:
2021-04-29 22:07:07.262 8965-8965/kim.hsl.a7_zip I/MainActivity: 1 folder, 1 file, 994304 bytes (971 KiB)
2021-04-29 22:07:07.262 8965-8965/kim.hsl.a7_zip I/MainActivity: Creating archive: /data/user/0/kim.hsl.a7_zip/files/files.7z
2021-04-29 22:07:07.262 8965-8965/kim.hsl.a7_zip I/MainActivity: Items to compress: 2
2021-04-29 22:07:07.262 8965-8965/kim.hsl.a7_zip I/MainActivity: Files read from disk: 1
2021-04-29 22:07:07.262 8965-8965/kim.hsl.a7_zip I/MainActivity: Archive size: 308165 bytes (301 KiB)
2021-04-29 22:07:07.262 8965-8965/kim.hsl.a7_zip I/MainActivity: Everything is Ok
2021-04-29 22:07:07.263 8965-8965/kim.hsl.a7_zip I/MainActivity: 执行完毕 , exitValue = 0
三、参考资料
参考资料 :
- 7-Zip 官网 : https://www.7-zip.org/
Android NDK 编译构建脚本参考文档 :
- ndk-build 脚本 : https://developer.android.google.cn/ndk/guides/ndk-build
- Android.mk 构建脚本 : https://developer.android.google.cn/ndk/guides/android_mk
- Application.mk 构建脚本 : https://developer.android.google.cn/ndk/guides/application_mk
博客资源 : 源码 , 编译后的可执行文件, 在 7zipp7zip_16.02CPPANDROID7zrlibs 目录下 ;
- 下载地址 : https://download.csdn.net/download/han1202012/18215890
- GitHub 项目源码 : https://github.com/han1202012/7-Zip
- 博客源码快照 : https://download.csdn.net/download/han1202012/18254613