4

从 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”类。我也肯定知道备份到云的工作是在我曾经遇到崩溃的同一部手机上工作的。

我在网上搜索了很多解决方案来解决这个问题的原因。我在类似问题上发现的所有案例,即从 PathClassLoader 抛出 ClassNotFoundException 即使该类存在于 apk 中,也有一个共同点。它们都有一个尾随“-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中搜索我的备份类并且由于某种未知原因找不到它的是所有系统例程。

我没有在 Manifest 的应用程序标签中设置 android:name 属性,我读到的可能会导致类似的错误。

有没有人知道可能导致这种情况的原因?或者更好的是,如何避免这种情况发生。

4

2 回答 2

0

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

于 2012-02-28T03:25:33.547 回答
0

我正在经历同样的崩溃。我想知道的一个理论是指定相对或绝对包名称是否重要。

就我而言,我使用的是“android:name=”,因为我的应用确实扩展了 Application. 所以我使用的是:android.name="com.foo.bar.myapp" 而不是:android.name=".myapp"

看起来这应该没什么区别,但我想知道加载器是否使用了不同的包名,比如带有“-1”或“-2”后缀的包名。

于 2011-10-24T23:54:25.457 回答