解决分包后导致安卓5.0以下手机点击应用闪退问题

    先描述一下 我遇到问题的过程。我是负责公司项目的二次开发,之前项目就已经超出64k方法数限制,按照谷歌方法,已经进行了分包处理:

    1.在app gradle的defaultConfig 中配置

multiDexEnabled true

    2.让自己的定义的application继承MulitiDexApplication(这是我项目中采用的方式),如果你的application已经继承了别的Application 你也可以采用一下这种方式,重写attachBaseContext方法,

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

    3.在app gradle的dependencies中配置,这是谷歌提供的解决安卓5.0一下手机分包适配问题的库

compile 'com.android.support:multidex:1.0.1'

    大多数的项目其实采用这些就已经可以正常分包运行了。但是我的项目随着客户的需求增加,引入第三方不断增加,又爆出了    

Error:Error converting bytecode to dex:

Cause: com.android.dex.DexException: Too many classes in --main-dex-list, main dex capacity exceeded
这个错误,明明已经进行分包了,怎么还出现这种方法数还超出的错误那,经过各种百度,总结得出:

我们采用的是谷歌通用分包方案,既然是通用的当然没有那么智能了,所以它感觉你集成的这些第三方都需要分配在main-dex里面,但其实有些是不需要分配在主Dex里面的,所以这时候就造成了主Dex方法数超出的问题,那怎么解决那?当然还是进行百度了,果然还是有大牛的,终于找到了一套方案,采用dexnkife分包:

    1.在project的gradle的defaultConfig 中配置

classpath 'com.ceabie.dextools:gradle-dexknife-plugin:1.5.9'

    2.在app的gradle的开头配置

apply plugin: 'com.ceabie.dexnkife'

    3.在app目录下创建dexnkife.txt文件,加入分包规则:

# 全局过滤, 如果没设置 -filter-suggest 并不会应用到 建议的maindexlist.
# 如果你想要某个包路径在maindex中,则使用 -keep 选项,即使他已经在分包的路径中.
-keep android.support.v4.view.**

# 这条配置可以指定这个包下类在第二dex中.
android.support.v?.**

# 使用.class后缀,代表单个类.
-keep android.support.v7.app.AppCompatDialogFragment.class

# 不包含Android gradle 插件自动生成的miandex列表.
-donot-use-suggest
-split **

# 将 全局过滤配置应用到 建议的maindexlist中, 但 -donot-use-suggest 要关闭.
#-filter-suggest

# 不进行dex分包, 直到 dex 的id数量超过 65536.
-auto-maindex

# dex 扩展参数, 例如 --set-max-idx-number=50000
# 如果出现 DexException: Too many classes in --main-dex-list, main dex capacity exceeded,则需要调大数值
-dex-param --set-max-idx-number=65536

# 显示miandex的日志.
-log-mainlist

# 如果你只想过滤 建议的maindexlist, 使用 -suggest-split 和 -suggest-keep.
# 如果同时启用 -filter-suggest, 全局过滤会合并到它们中.
-suggest-keep android.support.multidex.**

    在这个文件中,我们主要了-donot-use-suggest 和-split ** 这两个方法,就是不使用系统自动给我们分配包的方案,

这也就不会采用之前的主Dex,所以就不会造成主Dex方法数超出问题了,好了,运行一下,没问题,可以正常安装了,你以为

这就完事了?你太单纯了,我刚开始以为这也就Ok了,5.0以上手机运行确实没毛病,但是在5.0以下的手机上安装后,一点应用

就停止运行了。看错误:

Unable to instantiate application com.android.MyApplication:

java.lang.ClassNotFoundException: Didn't find class "com.luck.picture.lib.PictureFileProvider"

on path: DexPathList[dexElements=[zip file "/data/app/com.weyes.focus-1.apk"],

nativeLibraryDirectories=[/data/app-lib/com.weyes.focus-1, /vendor/lib, /system/lib]]

 错误显示,应用入口application类找不到?我就去查,可是在反编译的主Dex文件中明明就有这个类为什么还会报出类找不到那?然后就走了弯路,觉得这个dexnkife分包方案,可能对我这个项目不适用,就又去试了网上好多方案都不行,差点绝望了。后来一想应用入口类找不到,不一定是MyApplication类的问题,也可能是这个类中引用的包确实的问题。那怎样才能保证你的入口类中引用的包都在主Dex中那?然后我们再来看一下dexnkife.txt文件,然后我们看一下下面这两个方法:

# 如果你想要某个包路径在maindex中,则使用 -keep 选项,即使他已经在分包的路径中.

-keep android.support.v4.view.**

# 将 全局过滤配置应用到 建议的maindexlist中, 但 -donot-use-suggest 要关闭.

-filter-suggest

这两个方法是使用建议的maindexlist,然后我们把入口的类中引用的文件,全部采用keep分配到主Dex中,然后运行一下。又爆出

主Dex中方法数超出,采用建议的方法出超出,不采用建议的入口类又找不到。然后又浪费好长时间各种尝试,又采用这个方法

# 这条配置可以指定这个包下类在第二dex中.

android.support.v?.**

maindexlist中感觉启动app用不着的类采用这个方法,主动分配到第二个dex中,可是太多了,,,,最后也是放弃了。最后去

看了一下dexnkife的更新版本日志:惊喜,惊喜,惊喜,,,哈哈哈哈哈

原来在版本1.6.0中支持了如果你在dexnkife.txt中配置了要主动分包到主dex的类,那么maindexlist中就保存这些类。

那么修改一下吧:

在项目的gradle中更改一下引用dexnkife的版本

classpath 'com.ceabie.dextools:gradle-dexknife-plugin:1.6.0'

然后把你入口类MyApplication中类导入的包一个个全部采用keep的方式分配到主Dex中,运行一下。ok了。

    这里把自己采坑的记录记录下来,因为解决这个问题,真的浪费掉很多时间。新年假期还在家研究了两天,其实真正了解真的

很简单就可以解决,1.主要自己一直没搞明白dexknife.txt怎么配置 2.就是没有去看dexknife插件介绍。

希望我的记录可以对大家有帮助!

    多谢这位大神博客分享:https://www.cnblogs.com/tonny-li/p/7151670.html大神博客

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值