BaseDexClassLoader 意外崩溃
Unexpected crash in BaseDexClassLoader
我们的应用程序的 1800 名用户(每月活跃用户数为 1.2)发生了此崩溃(根据 Google 开发者控制台)。
非常罕见,但它确实发生了。
Android 4.1 最多 6,但报告中没有 Android 7。
BaseDexClassLoader 中这个 ClassNotFoundException 的性质可能是什么。
我们能避免吗?
java.lang.RuntimeException:
at android.app.LoadedApk.makeApplication(LoadedApk.java:572) at
android.app.ActivityThread.handleBindApplication(ActivityThread.java:4831)
at android.app.ActivityThread.access00(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
Android 中的 java.lang.ClassNotFoundException
有多种变体,其中大部分是由于 Proguard 配置错误造成的,IDE 期间未正确关闭之前启动的设备实例构建时间等...
所有这些 "normal" ClassNotFoundException
都是可以区分的,因为在异常的某些部分,有一些与应用程序本身相关的东西,例如:
java.lang.RuntimeException: Unable to instantiate application com.my.package.CustomApplication: java.lang.NullPointerException
或
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]]
虽然您面对的是与您的应用程序完全无关的东西,因为很明显没有对您的应用程序组件的引用。当您的应用程序因更新而卸载并重新安装时,系统加载 APK 并尝试执行您的某些代码(如 Receiver)的方式存在错误。
我认为这里发生的事情是:
- 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
这些因素的组合可以解释为什么考虑到活跃用户总数,您只有 "few" 次崩溃。
对此你能做些什么?我认为没什么,因为这是系统处理这种特殊情况的错误。 This comment在多个相关问题之一中有相同的结论。
您可以尝试创建自定义 ClassLoader
,您可以在其中自行处理异常并静默终止应用程序进程而不会导致应用程序崩溃,这样您的用户就不会注意到任何事情(我不不知道用户是否真的注意到这一点,也许这是系统处理的内部异常,用户什么也没看到)
您没有遇到 Android 7 的报告这一事实可能表明他们已在 LoadedApk Android 的最新 Android 版本中解决了该问题 class
PS:老实说,我认为这与多索引无关,但您可以进行一些测试以确保
我们的应用程序的 1800 名用户(每月活跃用户数为 1.2)发生了此崩溃(根据 Google 开发者控制台)。 非常罕见,但它确实发生了。
Android 4.1 最多 6,但报告中没有 Android 7。
BaseDexClassLoader 中这个 ClassNotFoundException 的性质可能是什么。 我们能避免吗?
java.lang.RuntimeException: at android.app.LoadedApk.makeApplication(LoadedApk.java:572) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4831) at android.app.ActivityThread.access00(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
Android 中的 java.lang.ClassNotFoundException
有多种变体,其中大部分是由于 Proguard 配置错误造成的,IDE 期间未正确关闭之前启动的设备实例构建时间等...
所有这些 "normal" ClassNotFoundException
都是可以区分的,因为在异常的某些部分,有一些与应用程序本身相关的东西,例如:
java.lang.RuntimeException: Unable to instantiate application com.my.package.CustomApplication: java.lang.NullPointerException
或
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]]
虽然您面对的是与您的应用程序完全无关的东西,因为很明显没有对您的应用程序组件的引用。当您的应用程序因更新而卸载并重新安装时,系统加载 APK 并尝试执行您的某些代码(如 Receiver)的方式存在错误。
我认为这里发生的事情是:
- 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
这些因素的组合可以解释为什么考虑到活跃用户总数,您只有 "few" 次崩溃。
对此你能做些什么?我认为没什么,因为这是系统处理这种特殊情况的错误。 This comment在多个相关问题之一中有相同的结论。
您可以尝试创建自定义 ClassLoader
,您可以在其中自行处理异常并静默终止应用程序进程而不会导致应用程序崩溃,这样您的用户就不会注意到任何事情(我不不知道用户是否真的注意到这一点,也许这是系统处理的内部异常,用户什么也没看到)
您没有遇到 Android 7 的报告这一事实可能表明他们已在 LoadedApk Android 的最新 Android 版本中解决了该问题 class
PS:老实说,我认为这与多索引无关,但您可以进行一些测试以确保