【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( 测试 lib7zr.so 动态库调用 )
前置博客 :
- 【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( 修改 7zr 交叉编译脚本 Android.mk | 交叉编译 lib7zr.so 动态库 )
- 【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( 拷贝 lib7zr.so 动态库到 Android Studio 工程 | 配置 build.gradle 构建脚本 )
- 【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( 拷贝 lib7zr.so 动态库头文件到 Android 工程中 | 配置 CMakeLists.txt 构建脚本 )
一、拷贝 p7zip 源码中的头文件到 Android Studio 项目中
在上一篇博客 【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( 拷贝 lib7zr.so 动态库头文件到 Android 工程中 | 配置 CMakeLists.txt 构建脚本 ) 中 , 将 lib7zr.so 动态库需要的头文件都拷贝到了 Android Studio 工程中 , 并配置了 CMakeLists.txt 构建脚本 ;
本篇博客开发 JNI 类 , 验证 lib7zr.so 动态库 ;
在 【Android 安装包优化】Android 中使用 7zr 可执行程序 解压缩文件 博客的 Android 项目的基础上进行开发 ;
首先加载 libnative-lib.so 动态库 , 这是 CMakeLists.txt 编译出来的动态库 , 声明 native 方法 ;
class MainActivity : AppCompatActivity() {
companion object {
init {
System.loadLibrary("native-lib")
}
}
external fun executeCmd(cmd: String): Unit
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
在 JNI 层的 C++ 文件中实现上述 native 方法 , MainActivity 类的包名是 kim.hsl.a7_zip , 因此 executeCmd 方法对应的 JNI 层的方法是 Java_kim_hsl_a7_1zip_MainActivity_executeCmd ;
extern "C"
JNIEXPORT void JNICALL
Java_kim_hsl_a7_1zip_MainActivity_executeCmd(JNIEnv* env, jobject thiz, jstring cmd) {
LOGI("7zTypes SZ_OK = %d", SZ_OK );
}
- 1
- 2
- 3
- 4
- 5
二、完整代码示例
1、Java 层代码
Java 层代码 :
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"
init {
System.loadLibrary("native-lib")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
copy7zr()
compress7z()
uncompress7z()
executeCmd("7z")
}
/**
* 将 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 file_7z = File("${filesDir.absolutePath}/files.7z")
if(file_7z.exists()){
file_7z.delete()
}
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
}
}
/**
* 使用 7zr 进行解压缩
*/
fun uncompress7z() {
// /data/user/0/kim.hsl.a7_zip/files/7zr
var exeFile = File(filesDir, "7zr")
// 执行前赋予可执行权限
exeFile.setExecutable(true)
// 删除解压目录
var unzip_file = File("${filesDir.absolutePath}/unzip_file")
if(unzip_file.exists()){
recursionDeleteFile(unzip_file)
}
var cmd = "${exeFile.absolutePath} x ${filesDir.absolutePath}/files.7z -o${filesDir.absolutePath}/unzip_file"
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")
}
/**
* 递归删除文件
*/
fun recursionDeleteFile(file: File) {
if (file.isDirectory) {
// 如果是目录 , 则递归删除
file.listFiles().forEach {
// ForEach 循环删除目录
recursionDeleteFile(it)
}
} else {
// 如果是文件直接删除
file.delete()
}
}
external fun executeCmd(cmd: String): Unit
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
2、JNI 层代码
#include <jni.h>
#include <string>
#include <7zTypes.h>
#include "logging_macros.h"
extern "C"
JNIEXPORT void JNICALL
Java_kim_hsl_a7_1zip_MainActivity_executeCmd(JNIEnv* env, jobject thiz, jstring cmd) {
LOGI("7zTypes SZ_OK = %d", SZ_OK );
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
3、日志头文件
日志打印头文件 :
//
// Created by octop on 2021/5/6.
//
#ifndef INC_7_ZIP_LOGGING_MACROS_H
#define INC_7_ZIP_LOGGING_MACROS_H
#include <android/log.h>
#if 1
#ifndef MODULE_NAME
#define MODULE_NAME "octopus"
#endif
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, MODULE_NAME, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, MODULE_NAME, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, MODULE_NAME, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,MODULE_NAME, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,MODULE_NAME, __VA_ARGS__)
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,MODULE_NAME, __VA_ARGS__)
#define ASSERT(cond, ...) if (!(cond)) {__android_log_assert(#cond, MODULE_NAME, __VA_ARGS__);}
#else
#define LOGV(...)
#define LOGD(...)
#define LOGI(...)
#define LOGW(...)
#define LOGE(...)
#define LOGF(...)
#define ASSERT(cond, ...)
#endif
#endif //INC_7_ZIP_LOGGING_MACROS_H
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
4、执行结果
执行结果 :
2021-05-06 20:44:57.920 8966-8966/kim.hsl.a7_zip I/MainActivity: 开始拷贝 7zr 文件
2021-05-06 20:44:57.921 8966-8966/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-05-06 20:44:57.924 8966-8966/kim.hsl.a7_zip I/MainActivity: 内置存储空间存在该 /data/user/0/kim.hsl.a7_zip/files/7zr 文件
2021-05-06 20:44:57.925 8966-8966/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-05-06 20:45:00.074 8966-8966/kim.hsl.a7_zip I/MainActivity: 7-Zip (a) [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
2021-05-06 20:45:00.074 8966-8966/kim.hsl.a7_zip I/MainActivity: p7zip Version 16.02 (locale=utf8,Utf16=on,HugeFiles=on,64 bits,8 CPUs LE)
2021-05-06 20:45:00.074 8966-8966/kim.hsl.a7_zip I/MainActivity: Scanning the drive:
2021-05-06 20:45:00.074 8966-8966/kim.hsl.a7_zip I/MainActivity: 13 folders, 6 files, 5965824 bytes (5826 KiB)
2021-05-06 20:45:00.074 8966-8966/kim.hsl.a7_zip I/MainActivity: Creating archive: /data/user/0/kim.hsl.a7_zip/files/files.7z
2021-05-06 20:45:00.075 8966-8966/kim.hsl.a7_zip I/MainActivity: Items to compress: 19
2021-05-06 20:45:00.075 8966-8966/kim.hsl.a7_zip I/MainActivity: Files read from disk: 6
2021-05-06 20:45:00.075 8966-8966/kim.hsl.a7_zip I/MainActivity: Archive size: 309075 bytes (302 KiB)
2021-05-06 20:45:00.075 8966-8966/kim.hsl.a7_zip I/MainActivity: Everything is Ok
2021-05-06 20:45:00.075 8966-8966/kim.hsl.a7_zip I/MainActivity: 压缩文件 , 执行完毕 , exitValue = 0
2021-05-06 20:45:00.078 8966-8966/kim.hsl.a7_zip I/MainActivity: 解压缩命令 : /data/user/0/kim.hsl.a7_zip/files/7zr x /data/user/0/kim.hsl.a7_zip/files/files.7z -o/data/user/0/kim.hsl.a7_zip/files/unzip_file
2021-05-06 20:45:00.088 8966-8966/kim.hsl.a7_zip I/MainActivity: 7-Zip (a) [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
2021-05-06 20:45:00.088 8966-8966/kim.hsl.a7_zip I/MainActivity: p7zip Version 16.02 (locale=utf8,Utf16=on,HugeFiles=on,64 bits,8 CPUs LE)
2021-05-06 20:45:00.088 8966-8966/kim.hsl.a7_zip I/MainActivity: Scanning the drive for archives:
2021-05-06 20:45:00.088 8966-8966/kim.hsl.a7_zip I/MainActivity: 1 file, 309075 bytes (302 KiB)
2021-05-06 20:45:00.088 8966-8966/kim.hsl.a7_zip I/MainActivity: Extracting archive: /data/user/0/kim.hsl.a7_zip/files/files.7z
2021-05-06 20:45:00.135 8966-8966/kim.hsl.a7_zip I/MainActivity: --
2021-05-06 20:45:00.135 8966-8966/kim.hsl.a7_zip I/MainActivity: Path = /data/user/0/kim.hsl.a7_zip/files/files.7z
2021-05-06 20:45:00.135 8966-8966/kim.hsl.a7_zip I/MainActivity: Type = 7z
2021-05-06 20:45:00.135 8966-8966/kim.hsl.a7_zip I/MainActivity: Physical Size = 309075
2021-05-06 20:45:00.135 8966-8966/kim.hsl.a7_zip I/MainActivity: Headers Size = 298
2021-05-06 20:45:00.135 8966-8966/kim.hsl.a7_zip I/MainActivity: Method = LZMA2:6m
2021-05-06 20:45:00.135 8966-8966/kim.hsl.a7_zip I/MainActivity: Solid = +
2021-05-06 20:45:00.135 8966-8966/kim.hsl.a7_zip I/MainActivity: Blocks = 1
2021-05-06 20:45:00.135 8966-8966/kim.hsl.a7_zip I/MainActivity: Everything is Ok
2021-05-06 20:45:00.135 8966-8966/kim.hsl.a7_zip I/MainActivity: Folders: 13
2021-05-06 20:45:00.135 8966-8966/kim.hsl.a7_zip I/MainActivity: Files: 6
2021-05-06 20:45:00.135 8966-8966/kim.hsl.a7_zip I/MainActivity: Size: 5965824
2021-05-06 20:45:00.135 8966-8966/kim.hsl.a7_zip I/MainActivity: Compressed: 309075
2021-05-06 20:45:00.135 8966-8966/kim.hsl.a7_zip I/MainActivity: 解压缩文件 , 执行完毕 , exitValue = 0
2021-05-06 20:45:00.135 8966-8966/kim.hsl.a7_zip I/octopus: 7zTypes SZ_OK = 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
四、参考资料
参考资料 :
- 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
博客资源 : 源码 , 编译后的可执行文件, 在 7zip\p7zip_16.02\CPP\ANDROID\7zr\libs\ 目录下 ;
- 下载地址 : https://download.csdn.net/download/han1202012/18215890
- GitHub 项目源码 : https://github.com/han1202012/7-Zip
文章来源: hanshuliang.blog.csdn.net,作者:韩曙亮,版权归原作者所有,如需转载,请联系作者。
原文链接:hanshuliang.blog.csdn.net/article/details/116455961
- 点赞
- 收藏
- 关注作者
评论(0)