Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android 6 auto restore not initializing app

Been testing the new Android 6 auto backup/restore function, and run into a problem with my app crashing immediately after a restore. Further investigation revealed that the Application.onCreate() initialization method was not being called before the main Activity.onCreate() method. This strikes me as a likely bug in the new autorestore logic. But I thought I would ask for advice here before reporting it as an official bug.

The sequence of events I go through is

  1. Run the app, always open a main activity window.
  2. Force a backup of app data by entering

    adb shell bmgr fullbackup net.anei.cadpage

  3. Use the app manager to force close the app and to clear all app and cache data
  4. Restore app information with

    adb shell bmgr restore

  5. Manually launch the app

Resulting logs show that the Activity.onCreate() method is called before the Application.onCreate() is. The app crashes because some critical initialization was not performed by the Application.onCreate() method.

Is there something obvious that I am missing???

FWIW, launching the app a second time after the crash works perfectly.

like image 803
kencorbin Avatar asked Mar 28 '16 05:03

kencorbin


1 Answers

It's actually intentional, though intrusive.

For full-data backup and restore operations, the package is launched with a base class Application instance, not your manifest-declared subclass. This is because, unfortunately, many apps open files or databases via Application subclasses, and this blocks the ability of the backup machinery to correctly read/write the underlying files. Similarly, your app's content providers are not automatically instantiated for full-data backup/restore operations. The app process is then destroyed following the operation, because of course your app cannot continue to run normally without its expected Application subclass or content providers.

You also don't say exactly what command you're using to perform a test restore, but I suspect you're using the bmgr command with this syntax:

adb shell bmgr restore PACKAGE

This doesn't do what you expect. In particular, it invokes the code path that happens when your app calls BackupManager.requestRestore(observer). In this specific code path, the app is NOT shut down following the restore operation, because the app has asked to observe the operation itself. This means that you're left with the app process still running but with a base class Application. It's a power-user API that is pretty much only safe when the app uses the original key/value backup API. You need to test instead using the other bmgr syntax:

adb shell bmgr restore TOKEN PACKAGE

where TOKEN is the identifier for which dataset should be used. At least on the most recent versions of the OS you can see the current and ancestral dataset tokens in the output of adb shell dumpsys backup.

This all needs to be better documented and made less surprising.

Subclassing Application is generally discouraged; this is one reason. Try to use your own lazy-init statics instead of subclassing Application.

like image 127
ctate Avatar answered Nov 10 '22 00:11

ctate