Android系统使用BackupAgent时出现神秘的ClassNotFoundException
当 Android 系统决定使用 BackupAgent 备份到 Google 云时,我的应用程序收到了几 (4) 条错误报告。我正在使用 SharedPreferencesBackupHelper。 堆栈跟踪如下所示(我的真实包名称在下面被替换为 com.xxx.yyy):
java.lang.RuntimeException: Unable to create BackupAgent com.xxx.yyy.MyBackupAgent: java.lang.ClassNotFoundException: com.xxx.yyy.MyBackupAgent in loader dalvik.system.PathClassLoader[/mnt/asec/com.xxx.yyy-1/pkg.apk]
at android.app.ActivityThread.handleCreateBackupAgent(ActivityThread.java:2114)
at android.app.ActivityThread.access$3200(ActivityThread.java:132)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1138)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:4196)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: com.xxx.yyy.MyBackupAgent in loader dalvik.system.PathClassLoader[/mnt/asec/com.xxx.yyy-1/pkg.apk]
at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:240)
at java.lang.ClassLoader.loadClass(ClassLoader.java:551)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at android.app.ActivityThread.handleCreateBackupAgent(ActivityThread.java:2064)
... 10 more
我什至在我自己运行 Android 2.3.3 的手机上遇到过程序崩溃的情况。这个程序崩溃让我困惑的是,我确信知道包中存在“MyBackupAgent”类。我还确信云备份正在我曾经崩溃过的同一部手机上运行。
我在网上搜索了很多解决方案,以了解此问题的原因。我发现的所有类似问题的案例都有一个共同点,即即使该类存在于 apk 中,也会从 PathClassLoader 抛出 ClassNotFoundException。它们都有一个尾随“-1”或“-2”以及安装 apk 的包名目录的末尾。
在我的错误报告中,这些是 dalvik.system.PathClassLoader 搜索我的备份类的不同名称:
/mnt/asec/com.xxx.yyy-1/pkg.apk
/data/app/com.xxx.yyy -1.apk
/mnt/asec/com.xxx.yyy-2/pkg.apk
也许我在错误的湖里钓鱼,但是这些在末尾附加的“-1”和“-2”是什么意思包名目录是什么意思,问题可能与此有关吗?我怀疑问题出在我的代码中,因为只需告诉系统安排我的共享首选项的备份。然后,Android 系统会在未来合适的时间执行备份操作 - 这就是崩溃发生的地方。查看堆栈跟踪,我的代码甚至没有被提及。所有系统例程最终都会在 apk 中搜索我的备份类,但由于某种未知的原因找不到它。
我尚未在清单中的应用程序标记中设置 android:name 属性,我读到该属性可能会导致类似的错误。
有谁知道可能导致此问题的原因吗?或者更好的是,如何避免这种情况发生。
I have got a few (4) error reports on my app from when the Android system decides to do the backup to Google cloud using the BackupAgent. I am using the SharedPreferencesBackupHelper.
The stack trace looks like this (my real package name is replaced below by com.xxx.yyy):
java.lang.RuntimeException: Unable to create BackupAgent com.xxx.yyy.MyBackupAgent: java.lang.ClassNotFoundException: com.xxx.yyy.MyBackupAgent in loader dalvik.system.PathClassLoader[/mnt/asec/com.xxx.yyy-1/pkg.apk]
at android.app.ActivityThread.handleCreateBackupAgent(ActivityThread.java:2114)
at android.app.ActivityThread.access$3200(ActivityThread.java:132)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1138)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:4196)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: com.xxx.yyy.MyBackupAgent in loader dalvik.system.PathClassLoader[/mnt/asec/com.xxx.yyy-1/pkg.apk]
at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:240)
at java.lang.ClassLoader.loadClass(ClassLoader.java:551)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at android.app.ActivityThread.handleCreateBackupAgent(ActivityThread.java:2064)
... 10 more
I have even got the program crash once myself, on my own phone which is running Android 2.3.3. What puzzles me with this program crash is that I for sure knows that the class "MyBackupAgent" IS present in the package. I also know for sure that the backup to cloud is working on the same phone where I once got the crash.
I have searched quite a lot on the net for a solution for what the reason could be for this problem. All cases I have found on similar problems, that is a ClassNotFoundException is thrown from PathClassLoader even though the class is present in the apk, have one thing in common. They all have a trailing "-1" or "-2" and the end of the package name directory where the apk is installed.
In my error reports, these are the different names for where the dalvik.system.PathClassLoader searches for my backup class:
/mnt/asec/com.xxx.yyy-1/pkg.apk
/data/app/com.xxx.yyy-1.apk
/mnt/asec/com.xxx.yyy-2/pkg.apk
Maybe I am fishing in the wrong lake here but what does these appended "-1" and "-2" at the end of the package name directory mean, and could the problem be related to this? I doubt the problem lies in my code, since just tell the system to schedule the backup of my sharedpreferences. Then the Android system engage the backup action at a suitable time in the future - and this is where the crash happens. Looking at the stack trace, my code is not even mentioned. It is all system routines that ends up searching for my backup class in the apk and can for some unknown reason not find it.
I have not set android:name attribute in the application tag in the Manifest, which I read could cause similar error.
Does anyone have a clue for what could cause this? Or better yet, how to avoid that this happens.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
“/mnt/asec”前缀意味着手机已安装到电脑,在应用程序尝试运行或 backupagent 尝试运行(应用程序尚未使用)期间,它会崩溃。这是预期的,因为手机已安装。
"/mnt/asec" prefix means that the phone is mounted to the pc and during that time when the app is trying to run or backupagent is trying to run (the app is not used already) it crashes. It is expected since the phone is mounted.
我正在经历同样的崩溃。我想知道的一个理论是指定相对或绝对包名称是否重要。
就我而言,我使用“android:name=”,因为我的应用程序确实扩展了应用程序。所以我用的是:
android.name="com.foo.bar.myapp"
而不是:
android.name=".myapp"
似乎这应该没有什么区别,但我想知道加载程序是否使用不同的包名称,例如带有“-1”或“-2”后缀的包名称。
I am experiencing the same crash. One theory I'm wondering about is whether specifying a relative or absolute package name matters.
In my case I was using "android:name=" because my app does extend Application. So I was using:
android.name="com.foo.bar.myapp"
instead of:
android.name=".myapp"
Seems like this shouldn't make a difference, but I'm wondering if the loader is using a different package name, like the one with the "-1" or "-2" suffixes.