【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( 测试 lib7zr.so 动态库调用 )

网友投稿 832 2022-05-30

文章目录

一、拷贝 p7zip 源码中的头文件到 android studio 项目中

二、完整代码示例

1、Java 层代码

2、JNI 层代码

3、日志头文件

4、执行结果

四、参考资料

前置博客 :

【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

【Android 安装包优化】使用 lib7zr.so 动态库处理压缩文件 ( 测试 lib7zr.so 动态库调用 )

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

2、JNI 层代码

#include #include #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 #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

Android

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:疯狂Java学习笔记(89)-----------Java习惯用法总结
下一篇:Vue实践案例
相关文章