我已将BackupAgentHelper实施到我的Android应用中。我使用自定义助手备份了几个SharedPreferences文件和我自己的一些实体。
我参与API 22并在真实设备上进行测试(Sony Z3 Compact)。
备份和还原的实体部分工作正常,因为您可以通过它断点并添加日志记录,并按预期写出并回读实体。但是,首选项部分实际上仅在重新启动后更改首选项值。
我在调用super.onRestore之前,在调用super.onRestore之后,在我的代理的onRestore方法中注销了pref值,然后在onRestoreFinished中注销了pref值。值不变。但是,如果我在使用它时重新启动并记录值,它们就是预期的。
我已使用Context.MODE_MULTI_PROCESS标志打开我的日志记录首选项,但它没有任何区别。
其他一些有趣的事情是我注册了一个只记录更改值的OnSharedPreferenceChangeListener,但它永远不会被触发。
我已经看了一段时间了,我已经看过人们在检索错误的偏好值时遇到的各种问题,但他们似乎都指向使用MODE_MULTI_PROCESS标志。我试过了它并没有用。此外,这个标志在API 23中已弃用,因此无论如何看起来都不是长期解决方案。
我的代码如下所示:
public void onCreate()
{
super.onCreate();
SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, MyApplication.PREFS_A)
{
@Override
public void restoreEntity(BackupDataInputStream data)
{
super.restoreEntity(data);
Logger.debug(FQCN, "Prefs A restore done. Current value A = {0}", getPrefValue("A"));
}
};
addHelper(KEY_PREFS_A, helper);
SharedPreferencesBackupHelper entityControllerPrefsHelper = new SharedPreferencesBackupHelper(this, MyApplication.PREFS_B)
{
@Override
public void restoreEntity(BackupDataInputStream data)
{
super.restoreEntity(data);
Logger.debug(FQCN, "Prefs B restore done. Current value B = {0}", getPrefValue("B"));
}
};
addEntityHelpers();
}
public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException
{
Logger.debug(FQCN, "About to restore. Current value A = {0}", getPrefValue("A"));
SharedPreferences.OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener()
{
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
Logger.stack(FQCN, "onRestore.onSharedPreferenceChanged. Key = {0}, Value = {1}", key, sharedPreferences.getString(key, ""));
}
};
prefs.registerOnSharedPreferenceChangeListener(listener);
Logger.debug(FQCN, "About to restore. Current value B = {0}", getPrefValue("B"));
super.onRestore(data, appVersionCode, newState);
//Just to make sure the listener isn't GC'd while we're restoring.
Logger.debug(FQCN, "listener hashcode. Not interesting. {0}", listener.hashCode());
}
public void onRestoreFinished()
{
super.onRestoreFinished();
Logger.debug(FQCN, "Restore finished. Current value A = {0}", getPrefValue("A"));
Logger.debug(FQCN, "Restore finished. Current value B = {0}", getPrefValue("B"));
}
public String getPrefValue(String name)
{
SharedPreferences prefs = MyApplication.get().getSharedPreferences("prefs", Context.MODE_MULTI_PROCESS);
return prefs.getString(name, "");
}
日志记录就像这样......
Application.onCreate() Current value A = def
Application.onCreate() Current value B = uvw
<Backup>
<Uninstall via ADB>
<Install via ADB, following logging comes out when install completes>
D/BackupManagerService: initiateOneRestore packageName=blah
BackupAgentHelper.onRestore() About to restore. Current value A = abc
BackupAgentHelper.onRestore() About to restore. Current value B = xyz
SharedPreferencesBackupHelper.restoreEntity() Prefs A restore done. Current value A = abc
SharedPreferencesBackupHelper.restoreEntity() Prefs B restore done. Current value B = xyz
BackupAgentHelper.onRestoreFinished() Restore finished. Current value A = abc
BackupAgentHelper.onRestoreFinished() Restore finished. Current value B = xyz
I/BackupRestoreController: restoreFinished for 0
I/BackupManagerService: Restore complete.
<Restart>
Application.onCreate() Current value A = def
Application.onCreate() Current value B = uvw