Android 4.4 以下multi dex的crash问题

这篇文章的分析和结论有问题,请大家别看了,免的误导大家,需要重新整理和分析

在崩溃统计平台上看到有如下的一种crash

java.lang.RuntimeException:

at android.app.ActivityThread.installProvider (ActivityThread.java:4889)

at android.app.ActivityThread.installContentProviders (ActivityThread.java:4481)

at android.app.ActivityThread.handleBindApplication (ActivityThread.java:4421)

at android.app.ActivityThread.access$1500 (ActivityThread.java:141)

at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1272)

at android.os.Handler.dispatchMessage (Handler.java:102)

at android.os.Looper.loop (Looper.java:136)

at android.app.ActivityThread.main (ActivityThread.java:5113)

at java.lang.reflect.Method.invokeNative (Method.java)

at java.lang.reflect.Method.invoke (Method.java:515)

at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:796)

at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:612)

at dalvik.system.NativeStart.main (NativeStart.java)

Caused by: java.lang.ClassNotFoundException:

at dalvik.system.BaseDexClassLoader.findClass (BaseDexClassLoader.java:56)

at java.lang.ClassLoader.loadClass (ClassLoader.java:497)

at java.lang.ClassLoader.loadClass (ClassLoader.java:457)

at android.app.ActivityThread.installProvider (ActivityThread.java:4874)

at android.app.ActivityThread.installContentProviders (ActivityThread.java:4481)

at android.app.ActivityThread.handleBindApplication (ActivityThread.java:4421)

at android.app.ActivityThread.access$1500 (ActivityThread.java:141)

at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1272)

at android.os.Handler.dispatchMessage (Handler.java:102)

at android.os.Looper.loop (Looper.java:136)

at android.app.ActivityThread.main (ActivityThread.java:5113)

at java.lang.reflect.Method.invokeNative (Method.java)

at java.lang.reflect.Method.invoke (Method.java:515)

at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:796)

at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:612)

at dalvik.system.NativeStart.main (NativeStart.java)

这个异常只存在Android 4.4机子以下的,现在竟然还有人玩4.4.这个老古董不管也不行,毕竟还有用户用.从异常栈分析,ActivityThread.installProvider的时候,加载不到对应的provider,我们去查看源码,源码是28的,和19比有点差距,但原理一样

1.是报错行,意思就是把provider加载到系统中,加载过程就不提了,反正系统找不到,我在项目里找了一遍,我们自己项目没有provider,应该是第三方注册的,反编译apk,发现在清单文件中,有provider注册

这就奇怪了,肯定不是这些类不存在。因为art机型基本没有这个问题,特点就是只dalvik中出现.反编译了查了下dex,我们项目是多dex,这些provider的特点是没有出现在class.dex中,也就是主dex中.但又想到我们在兼容4.4以下的多dex情况,在application中加了

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

这么一句代码,将dex合并,按道理不应该出现问题.分析源码发现,installProvicer的调用时间比app的初始化方法调用要早,dex还没有合并,所以 MultiDex.install(this)不起作用,找到了原因,问题也就解决了一半.将provider类打进入主dex即可.在打包的时候,在build目录下会有maindexlist.txt,拷到app目录下,然后添加一行

然后在app.gradle文件中添加一行,使用改过的maindexlist.txt

这样问题即可解决,如果有不懂的,可以留言,欢迎大家一起讨论.

关于64 k引用限制 Android应用程序(APK)在Dalvik可执行文件的形式包含可执行的字节码文件(DEX)文件,其中包含已编译的代码来运行你的应用程序。Dalvik可执行规格限制一个Dex文件包含65536个方法:包括Android框架方法、Library方法的总数、和你自己的代码方法总数。因为65536等于64×1024,这一限制被称为“64k引用限制”。 这个极限就要求我们配置应用程序的构建过程,需要生成多个DEX文件,所以称为multidex 配置。 分析原因与注意事项 解决方法分Android 5.0及以上系统和5.0以下系统怎么做。客官们不要着急,先看我一个个分析原因,毕竟我要装下逼哈哈。 一、Android 5.0以下的版本 Android 5.0(API leve 21)之前的系统使用Dalvik执行应用程序代码。默认情况下,Dalvik限制一个apk只有一个Dex文件。为了绕过这个限制, 我们可以使用multidex support library,它成为我们APK的主要DEX文件的一部分,负责管理我们APK访问其他DEX文件和代码。 注意: 如果咱的项目minSdkVersion是20或更低,运行到Android 4.4(API leve 20)或者更低版本的设备上时需要禁用AndroidStudio的即时运行 二、Android 5.0和更高版本 Android 5.0(API leve 21)和更高的系统使用runtime是ART ,原生支持从应用的apk文件加载多个DEX文件。ART在安装应用时预编译应用程序,会扫描多个classes(..N).dex文件编译成一个.oat的文件。更多Android5.0 runtime的更多信息,请参见即时运行-instant-run。 注意: 如果你使用即时运行 , AndroidStudio自动配置你的应用程序,你应用程序的minSdkVersion应该设置为21或更高。因为即时只工作在你APP的Debug版本,你任然需要配置你的release版本构建时用multidex避免64k的限制。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值