3

I am trying to use the Data Backup service, in order to save the user shared preferences, as described here. However, I have experienced the following problems when trying to test it in different Android versions.

Android 2.3.4: After extending the BackupAgentHelper, while trying to test the service using the bmgr tool (by following the steps here), in my Motorola Atrix with Android 2.3.4, I see the following messages:

W/BackupTransportService(1618): Unknown package in backup request: @pm@ 
W/BackupTransportService(1618): Not ready for backup request right now: [OperationScheduler: enabledState=false lastSuccess=2013-03-11/20:50:36 moratoriumSet=2013-03-16/22:50:00 moratorium=1970-01-01/02:00:00 trigger=1970-01-01/02:00:00]
W/PerformBackupThread(1618): Backup pass unsuccessful, restaging

Of course, no backup was created and after uninstalling and re-installing my application the onRestore was not invoked.

Android 4.0: I have also tried to test the service on an emulator with API14. Following again the same steps to test the service with the bmgr tool, instead of showing the above message, the onBackup() is actually invoked (xxx.yyy.zzz is my package and XXXXXXXX is the ApplicationInfo):

03-19 18:33:10.932: V/ActivityThread(808): handleCreateBackupAgent: CreateBackupAgentData{appInfo=ApplicationInfo{XXXXXXXX xxx.yyy.zzz} backupAgent=xxx.yyy.zzz.DataBackUpActivity mode=0}
03-19 18:33:10.932: V/ActivityThread(808): Initializing agent class xxx.yyy.zzz.DataBackUpActivity
03-19 18:33:10.943: D/DataBackUpActivity(808): onCreate()
03-19 18:33:10.952: V/BackupServiceBinder(808): doBackup() invoked
03-19 18:33:10.952: D/DataBackUpActivity(808): onBackup()
03-19 18:33:10.952: D/BackupHelperDispatcher(808): handling existing helper 'prefs' android.app.backup.SharedPreferencesBackupHelper@YYYYYYYY
03-19 18:33:10.972: V/ActivityThread(808): handleDestroyBackupAgent: CreateBackupAgentData{appInfo=ApplicationInfo{XXXXXXXX xxx.yyy.zzz} backupAgent=xxx.yyy.zzz.DataBackUpActivity mode=0}

After uninstalling and re-installing my app on the emulator, the onRestore() is invoked, however the MainActivity of my application is not found, thus a ClassNotFoundException is thrown:

V/ActivityThread(2246): Initializing agent class xxx.yyy.zzz.DataBackUpActivity
D/DataBackUpActivity(2246): onCreate()
V/BackupServiceBinder(2246): doRestore() invoked
D/DataBackUpActivity(2246): onRestore()
D/backup_data(2246): SKIP_PADDING FAILED at line 331
V/ActivityThread(2246): handleDestroyBackupAgent: CreateBackupAgentData{appInfo=ApplicationInfo{XXXXXXXX xxx.yyy.zzz} backupAgent=xxx.yyy.zzz.DataBackUpActivity mode=0}
W/dalvikvm(2246): Unable to resolve superclass of Lcom/yyy/zzz/MainActivity; (1164)
W/dalvikvm(2246): Link of class 'Lcom/yyy/zzz/MainActivity;' failed
D/AndroidRuntime(2246): Shutting down VM
W/dalvikvm(2246): threadid=1: thread exiting with uncaught exception (group=0x409961f8)
E/AndroidRuntime(2246): FATAL EXCEPTION: main
E/AndroidRuntime(2246): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{xxx.yyy.zzz/xxx.yyy.zzz.MainActivity}: java.lang.ClassNotFoundException: xxx.yyy.zzz.MainActivity
E/AndroidRuntime(2246):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1879)
E/AndroidRuntime(2246):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980)
E/AndroidRuntime(2246):     at android.app.ActivityThread.access$600(ActivityThread.java:122)
E/AndroidRuntime(2246):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1146)
E/AndroidRuntime(2246):     at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(2246):     at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(2246):     at android.app.ActivityThread.main(ActivityThread.java:4340)
E/AndroidRuntime(2246):     at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(2246):     at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(2246):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
E/AndroidRuntime(2246):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
E/AndroidRuntime(2246):     at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(2246): Caused by: java.lang.ClassNotFoundException: xxx.yyy.zzz.MainActivity
E/AndroidRuntime(2246):     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
E/AndroidRuntime(2246):     at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
E/AndroidRuntime(2246):     at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
E/AndroidRuntime(2246):     at android.app.Instrumentation.newActivity(Instrumentation.java:1023)
E/AndroidRuntime(2246):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1870)
E/AndroidRuntime(2246):     ... 11 more

The interesting thing though is that if I re-launch my app after the ClassNotFoundException, it works fine, including the restored shared preferences!

I have been through similar questions in SO (eg here, here), however they don't fall into the category of my problem. I don't think there is a problem with my app setup in the Manifest file or somewhere else, since in the API14 the onBackup and onRestore methods are invoked, and after the ClassNotFoundException the backup is restored. Finally, I want to note that I am building the Eclipse project with API17 (Google Inc).

Sorry for my long post, but I wanted to state the problem as clearly as possible. If anyone has feedback on why this is happening in these different Android versions, let us know.

EDIT: After reading this post, I also tried to change the backup transport to the so-called LocalTransport with this command command in the bmgr tool:

adb shell bmgr transport android/com.android.internal.backup.LocalTransport

The result was that the user shared preferences were successfully restored in my Android 2.3.4 Atrix phone. However, in the Android 4.0 emulator, the behavior was the same as before, i.e. onRestore() is invoked, the same ClassNotFoundException is thrown, and after an app re-launch, my app works ok and includes the user shared preferences. So on top of the previous question, a new one that pops is why the "LocalTransport" works on Android 2.3.4, and on 4.0 throws an exception (at least in this case). If anyone can share opinion please go ahead.

EDIT2: OK, this is weird. The ClassNotFoundException is thrown only for the MapActivities that I have in my app. More precisely, my app was starting with a MapActivity, hence on its 1st launch a ClassNotFoundException was thrown. What I did, is to create a dummy Activity with two buttons as the launcher Activity, where each button can start my MapActivities (in my app I have 2 in total). Now in this case there was a "could not find class" error, as shown in these messages:

D/DataBackUpActivity(1114): onCreate()
D/DataBackUpActivity(1114): DB path = /data/data/xxx.yyy.zzz/databases/MyDB.db
V/BackupServiceBinder(1114): doRestore() invoked
D/DataBackUpActivity(1114): onRestore()
V/ActivityThread(1114): handleDestroyBackupAgent: CreateBackupAgentData{appInfo=ApplicationInfo{XXXXXXXX xxx.yyy.zzz} backupAgent=xxx.yyy.zzz.DataBackUpActivity mode=0}
W/dalvikvm(1114): Unable to resolve superclass of Lcom/yyy/zzz/MyMapActivity1; (1165)
W/dalvikvm(1114): Link of class 'Lcom/yyy/zzz/MyMapActivity1;' failed
E/dalvikvm(1114): Could not find class 'xxx.yyy.zzz.MyMapActivity1', referenced from method xxx.yyy.zzz.MyMainActivity$6.onClick
W/dalvikvm(1114): VFY: unable to resolve const-class 1927 (Lcom/yyy/zzz/MyMapActivity1;) in Lcom/yyy/zzz/MyMainActivity$6;
W/dalvikvm(1114): Unable to resolve superclass of Lcom/yyy/zzz/MyMapActivity2; (1165)
W/dalvikvm(1114): Link of class 'Lcom/yyy/zzz/MyMapActivity2;' failed
E/dalvikvm(1114): Could not find class 'xxx.yyy.zzz.MyMapActivity2', referenced from method xxx.yyy.zzz.MyMainActivity$7.onClick
W/dalvikvm(1114): VFY: unable to resolve const-class 1835 (Lcom/yyy/zzz/MyMapActivity2;) in Lcom/yyy/zzz/MyMainActivity$7;

As you may see, these errors are only for my MapActivities and ONLY after the restore procedure. If I directly re-launch my app, everything works ok, including the restored data. So does anyone know why a "could not find class" is thrown only for a MapActivity and ONLY after the restore procedure? I should note that this happens only on Android 4. In my Atrix phone with Android 2.3.4 the data restore is working fine (with the LocalTransport). This is really weird... :-|

EDIT3: I have created a small Eclipse project to test the backup/restore service when the launcher activity is a MapActivity. It is built with Google API17. You can download it from here. I have tested this project in an emulator with Google API10, which works fine. However, in an emulator with Google API14, as soon as a restore is done, then a ClassNotFoundException is thrown. The project has a button that saves whatever text you write on an EditText to the user preferences. So to test it:

  1. Enter a text to the EditText
  2. Press the button to save it and exit the app
  3. Force a backup with the bmgr tool
  4. Uninstall the app, and re-install from Eclipse.

After the onRestore is invoked, a ClassNotFoundException will be thrown. Finally, I should note that if you replace the MapActivity with a simple Acitivy, then the restore is done successfully.

Let me know if anyone tries it. By the way, the exact same issue has been posted here, with no answer up to now. Is this a bug? Should it be reported?

EDIT4: As a continuation of EDIT2 where I have added an initial dummy Activity, while digging further into the problem, I found this: If after a restore, I simply start my MapActivity from my dummy Activity, then a NoClassDefFoundError is thrown and the app crashes, but on the next app launch works fine (as described before). However, if I catch the NoClassDefFoundError (and hence do not allow the app to crash), then the NoClassDefFoundError continues to be thrown even if I restart the app! How can it be possible? I have opened an issue in the Android project, you may find it here.

Community
  • 1
  • 1
Dimitris
  • 419
  • 4
  • 19
  • Were you able to resolve this issue? It looks like your Activity's superclass isn't being dexed, either because the (maps?) library isn't "exported" or perhaps Proguard is removing it. AndroidManifest might not be pointing to it correctly. – CodeShane Oct 07 '13 at 18:26
  • Unfortunately, I haven't managed to resolve it yet, and eventually I was forced to remove the backup service, until this issue is resolved. The point is that when I run the app in Android 2.3.4, everything works fine. But when I run the same app in Android 4.0+, it crashes, without any other modification.. – Dimitris Oct 08 '13 at 07:48

0 Answers0