Android-APK体积优化与dex方法数超出解决

版权声明:本博客仅用于学习交流,欢迎转载,但请注明作者和出处 https://blog.csdn.net/weixin_37577039/article/details/82596291

一、Android APK体积优化

1 开启混淆 则可以去除一些不需要的文件
minifyEnabled 开启混淆
shrinkResources 删除无效的Resource
shrinkResources依赖于minifyEnabled,必须和minifyEnabled一起用

2 图片压缩
(1)对于没有透明区域的png图片,可以转成jpg格式
(2)对于体积特别大(超过50k)的图片资源可以考虑有损压缩:jpg采用优图压缩,png尝试采用pngquant压缩,输出视觉判断是否可行
(3)对assets中的图片资源也使用aapt的crunch做图片预处理,crunch有可能会使图片变大,在这种情况,我们可以替换成原图
需要注意的是对于.9.png,由于crunch过程中去除了黑边,所以不能替换 并且.9图是可调整大小的压缩图 不需要压缩的

3 语言包压缩
语言包动态加载 程序中继承Resource实现getString方式读取即可

4 插件化
动态加载功能模块

5 SO文件体积优化所以一般不可取
默认使用的压缩方式是 ZIP 可以改成 LZMA方式压缩
具体使用:
1 将SO文件使用LZMA算法进行压缩放进Assets目录下,并在程序第一次加载的时候解压到应用的私有目录
2 需要将所有的System.loadlibrary()方式调用改为 通过System.load(path)的方式调用,并将所有使用路径加载或读取so文件的代码进行路径的重新设置
(LZMA库 本身只有39KB的大小) 一种7ZIP压缩算法
如果so文件存在对其他文件的依赖,或者被其他库隐式地调用,使用这种方式压缩会导致运行时错误


二、dex不超过65535个方法数 (线性分配)
一个DEX文件中method个数采用使用原生类型short来索引文件中的方法 即16位 (2^16 = 65536) 因此不能超过这个数

LinearAlloc问题的原因
安装时会提示INSTALL_FAILED_DEXOPT
因为应用在安装时,系统会通过dexopt来优化dex文件,
在优化过程中dexopt采用一个固定大小的缓冲区LinearAlloc来存储应用所有信息,LinearAlloc缓冲区在新版本Android系统中默认大小是8MB或16MB,但在Android2.2和2.3中只有5M,当待安装apk方法数较多时,
尽管方法数没有达到65536,可能存储空间超过上限,这种情况dexopt程序就会报错,从而导致安装失败

查看项目的dex方法数:
android-studio 有内置apk Analyzer工具 (Build->AnalyzeApk)
可以查看apk大小 dex大小 dex方法数


解决以上问题:

多dex文件方式
通过自定义类加载工具
一、
1 在defaultConfig中添加multiDexEnabled true
2
compile ‘com.android.support:multidex:1.0.0’
or
compile ‘org.robolectric:shadows-multidex:3.3.1’
3 Application,继承MulitDexApplication 或者重写 Application的attachBaseContext()

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(this);     
}

参考:
https://blog.csdn.net/S1107432915SL/article/details/51036816
https://developer.android.com/studio/build/multidex?utm_campaign=io16&utm_source=anddev&utm_medium=blog
http://blog.csdn.net/zylc369/article/details/44660007

二、
1 将 附加dex文件从 asset resource 拷贝 到 应用存储空间中
2 实例化 DexClassLoader to load the library from the extracted secondary dex file
至于要调用方法 可以
(1) 类实例被强制转换为一个接口,通过该接口直接调用该方法
(2) 反射方式 但是该方式会降低性能
3 修改编译脚本
参考:https://android-developers.googleblog.com/2011/07/custom-class-loading-in-dalvik.html

插件化方式: 参考:


线性内存(LinearAlloc)限制: 系统读取dex数据时不超过 5-16M
解决:
1 FaceBook提供了一个修改系统线性内存的值 (但是兼容性可能会有问题 因为直接改虚拟机的属性 如三星手机)
https://www.facebook.com/notes/facebook-engineering/under-the-hood-dalvik-patch-for-facebook-for-android/10151345597798920

猜你喜欢

转载自blog.csdn.net/weixin_37577039/article/details/82596291