BaseDexClassLoader 中的意外崩溃 [英] Unexpected crash in BaseDexClassLoader
问题描述
此崩溃发生在我们应用的 1800 名用户中,每月活跃用户为 1.2 名(根据 Google 开发者控制台).非常罕见,但确实会发生.
Android 4.1 到 6,但报告中没有 Android 7.
BaseDexClassLoader 中这个 ClassNotFoundException 的性质可能是什么.我们可以避免吗?
<块引用>java.lang.RuntimeException:在 android.app.LoadedApk.makeApplication(LoadedApk.java:572) 在android.app.ActivityThread.handleBindApplication(ActivityThread.java:4831)在 android.app.ActivityThread.access$1500(ActivityThread.java:178)
在android.app.ActivityThread$H.handleMessage(ActivityThread.java:1531)
在 android.os.Handler.dispatchMessage(Handler.java:111) 在android.os.Looper.loop(Looper.java:194) 在android.app.ActivityThread.main(ActivityThread.java:5637) 在java.lang.reflect.Method.invoke(Method.java:0) 在java.lang.reflect.Method.invoke(Method.java:372) 在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)
引起:java.lang.ClassNotFoundException:在dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)在 java.lang.ClassLoader.loadClass(ClassLoader.java:511) 在java.lang.ClassLoader.loadClass(ClassLoader.java:469) 在android.app.Instrumentation.newApplication(Instrumentation.java:985)
在 android.app.LoadedApk.makeApplication(LoadedApk.java:567)
注意:以下答案可能不准确且无法验证,因为在测试中模拟这个异常是非常不可能的环境.如果有人有关于该主题的更多信息,或者可能是最终解决方案请在此处发布.如果这些信息被证明是错误的,我提前道歉,但它们是基于我的经验和对事情的理解
Android中java.lang.ClassNotFoundException
有多种变种,其中大部分是由错误的Proguard配置,IDE在构建时没有正确关闭之前启动的设备实例等引起的...
所有这些正常"的 ClassNotFoundException
都是可区分的,因为在异常的某些部分中存在与应用程序本身相关的内容,例如:
java.lang.RuntimeException:无法实例化应用程序 com.my.package.CustomApplication:java.lang.NullPointerException
或
java.lang.RuntimeException:无法实例化活动 ComponentInfo{com.my.package/com.my.package.MyClass}:java.lang.ClassNotFoundException:找不到类com.my.package.MyClass" 路径:DexPathList[[zip file "/data/app/com.my.package-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.my.package-1,/vendor/库,/系统/库]]
虽然您面对的是与您的应用程序完全不相关的东西,因为很明显没有对您的应用程序组件的引用.当您的应用因更新而被卸载并重新安装时,系统如何加载 APK 并尝试执行您的一些代码(如接收器)是一个错误.
我认为这里发生的是:
<块引用>- 应用已安装
- 系统想要启动您的某个组件(例如
<receiver>
) - 应用因有新更新而被卸载(此步骤应仅持续几秒钟)
- 系统无法再找到您的应用并抛出您发布的错误
- 更新已安装,您的应用再次开始运行
这些因素的组合可以解释为什么考虑到活跃用户总数,您只有很少"崩溃.
你能做些什么呢?我认为没什么,因为系统处理这种特殊情况的方式有问题.此评论在多个相关问题之一中具有相同的结论.
您可以尝试创建一个自定义的 ClassLoader
,您可以在其中自己处理异常并静默终止应用程序进程而不会导致应用程序崩溃,这样您的用户就不会注意到任何事情(我不知道'不知道用户是否真的注意到这一点,可能是系统处理的内部异常,用户什么都看不到)
您没有遇到有关 Android 7 的报告这一事实可能表明他们已在最新的 Android 版本 LoadedApk 类
PS:我真的不认为这与多索引有关,但您可以执行一些测试来确定
This crash has happened to 1800 users of our app with 1.2 monthly active users (according to Google Developer Console). Quite rare, but it occurs.
Android 4.1 up to 6, but NO Android 7 in reports.
What might be the nature of this ClassNotFoundException in BaseDexClassLoader. Can we avoid it?
java.lang.RuntimeException: at android.app.LoadedApk.makeApplication(LoadedApk.java:572) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4831) at android.app.ActivityThread.access$1500(ActivityThread.java:178)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1531)
at android.os.Handler.dispatchMessage(Handler.java:111) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5637) at java.lang.reflect.Method.invoke(Method.java:0) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)Caused by: java.lang.ClassNotFoundException: at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) at java.lang.ClassLoader.loadClass(ClassLoader.java:511) at java.lang.ClassLoader.loadClass(ClassLoader.java:469) at android.app.Instrumentation.newApplication(Instrumentation.java:985)
at android.app.LoadedApk.makeApplication(LoadedApk.java:567)
NOTE: The answer below could be inaccurate and not verifiable, because this Exception is pretty impossibile to simulate in a test environment. If someone has more informations on the topic or maybe a definitive solution please post it here. I apologize in advance if this informations will be proved to be false at all but they are based on my experience and understanding of the thing
There are multiple variants of the java.lang.ClassNotFoundException
in Android, most of them are caused by a wrong Proguard configuration, IDE not closing correctly the previous launched instance of the device during build time etc...
All of this "normal" ClassNotFoundException
s are distinguishable because in some part of the exception there is something related to the app itself like:
java.lang.RuntimeException: Unable to instantiate application com.my.package.CustomApplication: java.lang.NullPointerException
or
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.my.package/com.my.package.MyClass}: java.lang.ClassNotFoundException: Didn't find class "com.my.package.MyClass" on path: DexPathList[[zip file "/data/app/com.my.package-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.my.package-1, /vendor/lib, /system/lib]]
While the one you are facing it's something not related at all with your application because it's clear there are no references to your app components. It's a bug in how the system load the APKs and try to execute some of your code (like a Receiver) when your app is uninstalled and reinstalled because of an update.
What i think it's happening here is:
- The app is installed
- The system wants to start one of your components (for example a
<receiver>
)- The app is uninstalled because of a new update (this step should last only few seconds)
- The system is not able to find anymore your app and throw the error you posted
- The update is installed and your app start working again
This combination of factors could explain why you have only "few" crashes considering the total active users.
What can you do about this? I think pretty nothing because it's a fault in how the system handle this special case. This comment in one of the multiple related issues has the same conclusion.
You could try to create a custom ClassLoader
where you can handle the Exception by yourself and terminate the app process silently without crashing the app, in this way your users shouldn't noticing anything (i don't know if the user is really noticing this, maybe it's an internal exception handled by the system and the user doesn't see nothing)
The fact that you did not encounter reports for Android 7 could be a sign that they fixed the problem in the latest Android version of LoadedApk class
PS: Sincerely i don't think this is related to multidexing, but you can perform some tests to be sure
这篇关于BaseDexClassLoader 中的意外崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!