BaseDexClassLoader 中的意外崩溃 [英] Unexpected crash in BaseDexClassLoader

查看:14
本文介绍了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 并尝试执行您的一些代码(如接收器)是一个错误.

我认为这里发生的是:

<块引用>

  1. 应用已安装
  2. 系统想要启动您的某个组件(例如 <receiver>)
  3. 应用因有新更新而被卸载(此步骤应仅持续几秒钟)
  4. 系统无法再找到您的应用并抛出您发布的错误
  5. 更新已安装,您的应用再次开始运行

这些因素的组合可以解释为什么考虑到活跃用户总数,您只有很少"崩溃.

你能做些什么呢?我认为没什么,因为系统处理这种特殊情况的方式有问题.此评论在多个相关问题之一中具有相同的结论.

您可以尝试创建一个自定义的 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" ClassNotFoundExceptions 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:

  1. The app is installed
  2. The system wants to start one of your components (for example a <receiver>)
  3. The app is uninstalled because of a new update (this step should last only few seconds)
  4. The system is not able to find anymore your app and throw the error you posted
  5. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆