Загадочное исключение ClassNotFoundException, когда система Android задействует BackupAgent

У меня есть несколько (4) отчетов об ошибках в моем приложении, когда система Android решает сделать резервную копию в облаке Google с помощью BackupAgent. Я использую 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" присутствует в пакете. Я также точно знаю, что резервное копирование в облако работает на том же телефоне, на котором у меня когда-то был сбой.

Я довольно много искал в сети решение того, что может быть причиной этой проблемы. Все случаи, которые я нашел по похожим проблемам, то есть ClassNotFoundException выбрасывается из PathClassLoader, даже если класс присутствует в 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 и могут по какой-то неизвестной причине не найти его.

Я не установил атрибут android: name в теге приложения в манифесте, который, как я читал, может вызвать аналогичную ошибку.

Кто-нибудь знает, что может быть причиной этого? Или еще лучше, как этого избежать.


person Anders    schedule 03.10.2011    source источник
comment
как регистрируется умысел? мы можем увидеть ваш манифест?   -  person Ian    schedule 04.10.2011
comment
‹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 ...мой резервный ключ... /› ‹/application›   -  person Anders    schedule 04.10.2011


Ответы (2)


Префикс «/mnt/asec» означает, что телефон подключен к компьютеру, и в то время, когда приложение пытается запуститься или пытается запустить агент резервного копирования (приложение еще не используется), происходит сбой. Это ожидается, так как телефон установлен.

person Anatoly Lubarsky    schedule 28.02.2012
comment
Ожидал? Действительно? Мне кажется, это ошибка в BackupAgent. Или я могу избежать этого сбоя, добавив что-то в код своего приложения? - person Anders; 03.03.2012
comment
Я имею в виду, что ожидается провал. Конечно, это ошибка. То же самое происходит, кстати, при обновлении приложения, когда вы обновляете двоичный файл, я думаю, это значение суффиксов. Я тоже ищу решение, но это корень проблемы. - person Anatoly Lubarsky; 04.03.2012
comment
Рассматривая мой собственный вопрос, это на самом деле ответ на него. Спасибо! Я полагаю, что нормальные разработчики ничего не могут с этим поделать. Разработчики из Google, ответственные за BackupAgent, должны исправить эту ошибку. - person Anders; 06.03.2012

Я испытываю тот же сбой. Одна теория, которая меня интересует, заключается в том, имеет ли значение указание относительного или абсолютного имени пакета.

В моем случае я использовал «android: name =», потому что мое приложение расширяет Application. Поэтому я использовал: android.name="com.foo.bar.myapp" вместо: android.name=".myapp"

Похоже, это не должно иметь значения, но мне интересно, использует ли загрузчик другое имя пакета, например, с суффиксами «-1» или «-2».

person John Roberts    schedule 24.10.2011