【Android 安装包优化】Android 中使用 7zr 可执行程序 压缩文件

简介: 【Android 安装包优化】Android 中使用 7zr 可执行程序 压缩文件

文章目录

一、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 00 说明执行成功 ; 如果捕获到 IllegalThreadStateException 异常 , 说明命令还在执行中 ;


 

/**
     * 判定命令是否执行完毕
     * 调用 process.exitValue 方法 , 如果没有执行完毕 , 会抛异常,
     * 如果执行完毕会返回一个确定的值
     */
    fun isComplete(process: Process): Boolean {
        try {
            // 已经执行完毕
            process.exitValue()
            return true
        } catch (e: IllegalThreadStateException) {
            // 未执行完毕
            return false
        }
    }



拼装 7zr 压缩命令 :


var cmd = "${exeFile.absolutePath} a ${filesDir.absolutePath}/files.7z ${filesDir.absolutePath} -mx=9 -t7z"



执行命令行 :


 
         



使用 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")
    }








二、完整代码示例


完整代码 :


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

       }

   }

}

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
        }
    }
}


执行结果 :


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

image.png






三、参考资料


参考资料 :


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


博客源码快照 : https://download.csdn.net/download/han1202012/18254613


目录
相关文章
|
2月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
313 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
3月前
|
存储 消息中间件 人工智能
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
314 10
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
|
9月前
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
2476 77
|
7月前
|
缓存 编解码 Android开发
Android内存优化之图片优化
本文主要探讨Android开发中的图片优化问题,包括图片优化的重要性、OOM错误的成因及解决方法、Android支持的图片格式及其特点。同时介绍了图片储存优化的三种方式:尺寸优化、质量压缩和内存重用,并详细讲解了相关的实现方法与属性。此外,还分析了图片加载优化策略,如异步加载、缓存机制、懒加载等,并结合多级缓存流程提升性能。最后对比了几大主流图片加载框架(Universal ImageLoader、Picasso、Glide、Fresco)的特点与适用场景,重点推荐Fresco在处理大图、动图时的优异表现。这些内容为开发者提供了全面的图片优化解决方案。
314 1
|
存储 传感器 定位技术
《移动互联网技术》 第四章 移动应用开发: Android Studio开发环境的使用方法:建立工程,编写源程序,编译链接,安装模拟器,通过模拟器运行和调试程序
《移动互联网技术》 第四章 移动应用开发: Android Studio开发环境的使用方法:建立工程,编写源程序,编译链接,安装模拟器,通过模拟器运行和调试程序
489 0
|
Android开发
【Android 逆向】代码调试器开发 ( 等待进程状态改变 | detach 脱离进程调试 PTRACE_DETACH | 调试中继续运行程序 PTRACE_CONT )
【Android 逆向】代码调试器开发 ( 等待进程状态改变 | detach 脱离进程调试 PTRACE_DETACH | 调试中继续运行程序 PTRACE_CONT )
308 0
|
网络协议 Android开发 虚拟化
Android Studio无法运行程序调试程序出现Unable to connect to ADB.Check the Event Log for possible issues.Verify th
Android Studio无法运行程序调试程序出现Unable to connect to ADB.Check the Event Log for possible issues.Verify th
231 0
Android Studio无法运行程序调试程序出现Unable to connect to ADB.Check the Event Log for possible issues.Verify th
|
前端开发 开发工具 Android开发
使用expo在安卓模拟器中运行React Native程序
看完这篇教程你会学到如何在安卓模拟器里运行一个React Native程序。 我的电脑及软件环境 系统: windows10 64 Node:8.5.0 然后安装下面的工具,不分先后。
3548 0
|
Android开发
【Android 逆向】修改运行中的 Android 进程的内存数据 ( Android 系统中调试器进程内存流程 | 编译内存调试动态库以及调试程序 )
【Android 逆向】修改运行中的 Android 进程的内存数据 ( Android 系统中调试器进程内存流程 | 编译内存调试动态库以及调试程序 )
390 0
【Android 逆向】修改运行中的 Android 进程的内存数据 ( Android 系统中调试器进程内存流程 | 编译内存调试动态库以及调试程序 )
|
Java Android开发 关系型数据库
Android Studio运行Hello World程序
老的神舟本本装上了深度LINUX了。。。应该是基于ubuntu的,安装软件用的apt-get而不是yum 想重装学下android原生开发,官网下载了android studio, 发现不用FQ也能下载了,不错不错,支持支持 下载后解压了直接双击那个Android Studio.sh运行就行了,新建一个hello world项目,结果运行不起来,那个调试那个地方都没有绿色三角形, 想了下,好像没有装JAVA,又上ORACLE上下载了JAVA的安装,结果又总是下不了,晕。
1903 0

热门文章

最新文章