打通“任督二脉”:Android 应用安装优化实战
疑问:
(1)了解APK安装流程有什么好处
(2)了解APK安装流程可以解决什么问题
一、可以在安装流程里做什么
安装就分为下面三个阶段,每个阶段可以做些什么工作,可以帮助我们优化安装流程,解决安装后的一些问题呢?
(1)安装前、安装中:这两个阶段,第三方应用做不了什么,一般是应用分发APP应用商店、游戏中心、浏览器、应用宝这些应用会关注这两个状态。
(2)安装后:这个阶段,无论是内置应用还是第三方应用,或多或少的会遇到一些问题,如so文件找不到,图片存储、缓存数据等出现异常等...
二、安装前
安装前无非是根据自己的应用情况,选择一种可以使用的安装方法。
2.1 pm命令安装方法
对于具有系统签名的厂商应用,具备静默安装能力,使用pm命令即可实现。
String cmd = "pm install -r -d /data/data/android.apk" Runtime run = Runtime.getRuntime(); Process process = run.exec(cmd);
2.2 包安装管理器安装
非系统签名的应用宝这种应用,只能使用包安装管理器进行安装。
Intent intent = new Intent(Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android" + ".package-archive"); mContext.startActivity(intent);
2.3 session命令安装
使用session安装的原因,是因为从Android 8.0开始,pm命令无法实现静默安装,否则会直接显示安装失败。但是网上并未发现对静默方法的适配方案,也许这是因为这个兼容只有厂商关注,第三方应用不关注这个方法的兼容。下面给出兼容方案:
int sessionId = packageInstaller.createSession(params); InstallLog.d(TAG, "doPackageStage creat sessionId is : " + sessionId); final byte[] buffer = new byte[65536]; session = packageInstaller.openSession(sessionId); final InputStream in = new FileInputStream(file); final long sizeBytes = file.length(); final OutputStream out = session.openWrite("PackageInstaller", 0, sizeBytes); try { int c; while ((c = in.read(buffer)) != -1) { out.write(buffer, 0, c); } session.fsync(out); } catch (IOException ex) { InstallLog.e(TAG, "doPackageStage ioException : " + ex.getMessage(), ex); } finally { InstallUtils.closeQuietly(in); InstallUtils.closeQuietly(out); }
该方法是从packageManager中抽取出的代码,可实现应用的静默安装。
三、安装中
3.1 APK的结构
APK文件其实是zip格式,一般包含一个或多个dex文件、resources.arsc、AndroidManifest.xml、res目录、META-INF目录及包含so库的lib目录:
3.2 安装过程中涉及的存储目录
-
system/app——内置应用,也就是系统自带的应用程序,无法删除。
-
data/app——用户程序安装的目录,有删除权限。安装时把apk文件复制到此目录。
-
data/data——存放应用程序的数据,比如一些sp缓存数据。
-
data/dalvik-cache——将APK中的dex文件安装到dalvik-cache目录下(dex文件是dalvik虚拟机的可执行文件,其大小约为原始APK文件大小的四分之一)。
3.3 安装主要流程
安装过程概括为:复制APK安装包到/data/app目录下,解压并扫描安装包,向资源管理器注入APK资源,解析AndroidManifest文件,并在/data/data目录下创建对应的应用数据目录,然后针对dalvik/art环境优化dex文件,保存到dalvik-cache目录,将AndroidManifest文件解析出的组件、权限注册到PackageManagerService,完成后发送广播。
3.4 安装中可以优化的点
安装中,这个过程看上去没有什么可以做的,但是对于厂商应用来说,应用的安装速度,却是可以有很大的提升空间的。如应用更新的差分包升级就是一种常见的增量更新方式。
经过一系列测试与验证,发现应用安装的速度,本身与一些因素有关,最主要的是CPU的使用频率。
众所周知,现在的手机较为高端,为8核,但是在应用安装过程中,分析trace文件,可以确认,并不是8核线程全负荷工作去完成一个应用的安装,而是一部分线程运行在高核,一部分在低核。
3.4.1 CPU的工作频率介绍
cpuinfo_max_freq cpuinfo_min_freq :分别给出了 CPU 硬件所支持的最高运行频率及最低运行频率,
-
cpuinfo_cur_freq 则会从CPU 硬件寄存器中读取CPU 当前所处的运行频率。
-
Governor 在选择合适的运行频率时只会在scaling_max_freq 和 scaling_min_freq 所确定的频率范围内进行选择。
-
scaling_cur_freq 返回的是cpufreq 模块缓存的CPU当前运行频率,而不会对CPU 硬件寄存器进行检查。
-
scaling_available_governors 会告诉用户当前有哪些 governors 可供用户使用。
-
scaling_driver 则会显示该 CPU 所使用的变频驱动程序。
-
Scaling_governor 则会显示当前的管理策略,往这个上 echo 其他类型会有相应的转变。
-
scaling_setspeed :需将 governor 类型切换为 userspace ,才会出现,往这个文件 echo 数值,会切换主频。
基于此,可以在应用安装时,提升CPU的工作频率,即可使CPU运行在合适的频率。
2.4.2 提升CPU的工作频率
除了可以直接根据安装速度判断安装速度是否提升外,也可以根据下面日志判断提频是否有效:
adb shell cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq adb shell cat /sys/devices/system/cpu/cpu7/cpufreq/cpuinfo_cur_freq
可以直接看到频率变化:
微信安装速度可以由前面CPU低频时的20s,提升到CPU频率较高时的10s左右。
注意:频率不是越高越好,频率越高,手机耗电会越高,容易发热。
四、安装后
应用安装后,会遇到各种各样的问题,启动失败,合规整改(这个其实在应用开发时就要完成),那么哪些问题又是可能遇到,又可以借助apk的安装流程去解决的
4.1 targetsdkversion=30 不得不做的事情
在《符合 Google Play 的目标 API 级别要求》 一文中,根据google官方要求,需要对隐私权限进行管控,强制执行分区存储,这就要求,每个应用不得在sd卡进行资源存储。那么问题来了,假如你的项目使用了Glide,Glide的存储路径之前设置到了sd卡下面,现在又无法使用外部存储目录,该怎么办?
当了解了apk的安装流程之后,知道应用的数据会存储在data/data/packagename下面,这就给Glide的资源存储提供了一个内部文件夹,唯一要做的事情,就是为了防止data/data占用过大,把Glide的存储目录设置个上限即可。
4.2 libmmkv.so无法找到问题解决
4.2.1 现象
如果你的应用接了腾讯的mmkv,你可能遇到了这样的问题:
java.lang.UnsatisfiedLinkError dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/packagename-Sxe4_uU3WXx-ckI5DyG3UA==/base.apk"],nativeLibraryDirectories=[/data/app/packagename-Sxe4_uU3WXx-ckI5DyG3UA==/lib/arm, /system/fake-libs, /data/app/packagename-Sxe4_uU3WXx-ckI5DyG3UA==/base.apk!/lib/armeabi-v7a, /system/lib, /system/vendor/lib, /system/vendor/lib/hw]]] couldn't find "libmmkv.so" Runtime.java 1011 java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/packagename-Sxe4_uU3WXx-ckI5DyG3UA==/base.apk"],nativeLibraryDirectories=[/data/app/packagename-Sxe4_uU3WXx-ckI5DyG3UA==/lib/arm, /system/fake-libs, /data/app/packagename-Sxe4_uU3WXx-ckI5DyG3UA==/base.apk!/lib/armeabi-v7a, /system/lib, /system/vendor/lib, /system/vendor/lib/hw]]] couldn't find "libmmkv.so" at java.lang.Runtime.loadLibrary0(Runtime.java:1011) at java.lang.System.loadLibrary(System.java:1657) at com.tencent.mmkv.MMKV.a(SourceFile:3)
这个表示应用加载libmmkv.so出现异常。
4.2.2 分析原因
出现问题的原因是什么:根据日志可以确认,是找不到应用data/app/文件夹下面的libmmkv.so文件。
4.2.3 解决问题
前面提到,应用的数据会存储在data/data下面,这个路径下面也包含了应用解压之后的so库,所以可以做一件事情解决上面libmmkv.so的问题,重链接data/data下面的资源到data/app下面,实现资源共享。实践证明该方案完全可行,有效解决了so库找不到的问题。
五、疑问解答
(1)了解APK安装流程有什么好处
从apk发起安装,安装中、一直到安装结束,应用状态的变化,CPU的使用,资源的共享,牵涉到一系列知识点,这些知识点是可以串联起来的,对提升个人的知识体系有帮助。当然,由于文章篇幅有限,本文章只是作为一个引导,大致说明安装过程中存在什么知识点,PMS、文件管理、进程拉起等等安全可以另起一章节进行介绍,后续会介绍这些方面的内容。
(2)了解APK安装流程可以解决什么问题
厂商应用更多的关注安装前、安装中遇到的问题,第三方应用关注安装后遇到的问题。掌握了安装过程中的每一个环节,通过上面的分析,可以知道,能够快速帮助定位问题。
作者:vivo互联网客户端团队-Xu Jie

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Kafka 集群同步工具 MirrorMarker 的应用
前言 kafka 集群消息同步是一个常见的需求,MirrorMarker 是 kafka 官方仓库提供的用于 kafka 各集群间 topic 消息同步的工具,本文旨在通过测验 MirrorMarker 的使用,搞清楚 MirrorMarker 的实现原理,以及通过各种使用场景模拟,验证 MirrorMarker 的可用性。 相关链接 kafka :https://github.com/apache/kafka cmak(kafka-manager) :https://github.com/yahoo/CMAK 本文 kafka-mock-server 源码 :https://github.com/klboke/kafka-mock-server 本文软件版本 spring-boot:2.4.5 spring-kafka\spring-kafka-test:2.7.2 kafka(MirrorMarker):2.5.1 创建 kafka-mock-server 项目 用于搭建测试 kafka 集群,测试 kafka 消息发送、消费,kafka 消息集群同步的项目。有如下模块。 mock...
- 下一篇
获取 Windows 密码「GitHub 热点速览 v.21.28」
作者:HelloGitHub-小鱼干 安全问题一直是 GitHub 的一大热点,因为数据安全问题诞生的各类自托管服务便是。而本周周榜上的 2 个和安全主题相关的项目,有些不同。mimikatz 是个老项目了,很多“黑客”用它从内存中提取明文密码、哈希、PIN 码和 kerberos 凭据(ticket),而同样是“安全主题”的 scorecard 更像是个守护者,它从代码、社区等多个层面帮你检测开源项目的安全健康度。当然,命令行文件共享工具 transfer.sh 的安全点便是支持加密传输数据。 以下内容摘录自微博@HelloGitHub 的 GitHub Trending 及 Hacker News 热帖(简称 HN 热帖),选项标准:新发布 | 实用 | 有趣,根据项目 release 时间分类,发布时间不超过 14 day 的项目会标注 New,无该标志则说明项目 release 超过半月。由于本文篇幅有限,还有部分项目未能在本文展示,望周知 🌝 本文目录 本周特推 1.1 不只是 Netflix:Fakeflix 1.2 脑图学 Linux:Psyduck GitHub Tr...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8安装Docker,最新的服务器搭配容器使用
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7安装Docker,走上虚拟化容器引擎之路
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8编译安装MySQL8.0.19