当Android系统启用BackupAgent时出现神秘的ClassNotFoundException

4

我从我的应用程序收到了几个(4个)错误报告,这些报告是在Android系统使用BackupAgent将备份存储到Google云时出现的。我正在使用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中,都会抛出一个ClassNotFoundException异常,但它们都有一个共同点。它们在apk安装目录的包名称目录末尾都带有“-1”或“-2”。
在我的错误报告中,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”在包名称目录末尾代表什么意思?这个问题是否与此有关?我怀疑问题不在我的代码中,因为我只是告诉系统安排备份我的sharedpreferences。然后,Android系统会在将来的适当时间启动备份操作,这就是崩溃发生的地方。查看堆栈跟踪,我的代码甚至没有被提到。所有的系统例程最终都会在apk中搜索我的备份类,但由于某些未知原因找不到它。
我没有在Manifest中的application标签中设置android:name属性,我读到这可能会导致类似的错误。
有人知道这是什么原因吗?或者更好的是,如何避免发生这种情况。

意图是如何注册的?我们可以看到你的清单文件吗? - Ian
<application android:icon="@drawable/icon" android:label="@string/app_name" android:backupAgent=".MyBackupAgent" > ... <meta-data android:name="com.google.android.backup.api_key" android:value="AEdPqrEA...my backup key..." /> </application> - Anders
2个回答

0

我也遇到了同样的崩溃问题。我想知道的一个理论是,指定相对或绝对包名是否有影响。

在我的情况下,我正在使用 "android:name=",因为我的应用程序确实扩展了 Application。所以我使用了: android.name="com.foo.bar.myapp" 而不是: android.name=".myapp"

看起来这不应该有任何影响,但我想知道加载器是否使用了不同的包名,比如带有 "-1" 或 "-2" 后缀的包名。


0

"/mnt/asec" 前缀表示手机已经挂载到电脑上,在此期间,当应用程序尝试运行或备份代理尝试运行(应用程序尚未使用)时,它会崩溃。这是预期的,因为手机已经挂载。


期望的?真的吗?对我来说,这似乎是备份代理中的一个错误。或者我能通过在我的应用程序代码中添加一些内容来避免这个崩溃吗? - Anders
我是说失败是预料之中的。当然这是个 bug。在应用程序升级时更新二进制文件时也会发生同样的事情,我想这就是那些后缀的含义。我也在寻找解决方案,但这就是问题的根源。 - Anatoly Lubarsky
1
回顾我的问题,这实际上就是它的答案。谢谢!我想普通开发人员无法解决这个问题。修复这个漏洞取决于负责BackupAgent的Google开发人员。 - Anders

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接