我只是碰到了同样的问题。这是令人沮丧,因为FileBackupHelper做几乎正是我们想要做的事。
如果你看一下代码FileBackupHelper的restoreEntity功能这里
https://android.googlesource.com/platform/frameworks/base.git/+/android-4.2.2_r1/core/java/android/app/backup/FileBackupHelper.java
public void restoreEntity(BackupDataInputStream data) {
if (DEBUG) Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size());
String key = data.getKey();
if (isKeyInList(key, mFiles)) {
File f = new File(mFilesDir, key);
writeFile(f, data);
}
}
...你可以看到,文件没有被写入的唯一原因是因为他们的不是列表您传递给FileBackupHelper构造函数。
我的第一个解决方案是覆盖isKeyInList总是返回true。这实际上工作,但后来它让我感到奇怪,因为isKeyInList具有默认保护,我的FileBackupHelper子类不在同一个包中。事实证明,这是某种dalvik虚拟机的bug,允许这个,所以我不想依靠它(见Android method with default (package) visibility overriding (shouldn't work, but does - why?))
但后来我意识到我可以只是坚持我传递给文件的数组FileBackupHelper构造函数,然后将第一个元素更改为始终是要创建的文件的名称。这样它总会在列表中找到。
class MyFileBackupHelper extends FileBackupHelper
{
String[] mMyFiles;
MyFileBackupHelper(Context context, String... files)
{
super(context,files);
mMyFiles = files;
}
/* boolean isKeyInList(String key, String[] list)
{
return true;
} */
public void restoreEntity(BackupDataInputStream data)
{
mMyFiles[0] = data.getKey();
super.restoreEntity(data);
}
}
当然,这也依赖于FileBackupHelper保持相同的实现,它不创建文件列表的副本。我不确定他们为什么要花费很多麻烦来防止恢复任意文件,也许他们会在稍后尝试阻止此解决方案。但现在,我称它为好!
哦,是的,使我的解决方案工作的一个额外的细节是,您需要确保恢复时总是有一个文件在列表中。这样总会有一个数组元素0替换。这是我在做BackupAgent
public class MyBackupAgent extends BackupAgentHelper
{
public void AddFileHelper(String files[])
{
FileBackupHelper aHelper = new MyFileBackupHelper(this,files);
addHelper("userfiles", aHelper);
}
@Override
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) throws IOException
{
String[] anArray = GetAllUserFiles(); // I'm not including this function for brevity
AddFileHelper(anArray);
super.onBackup(oldState, data, newState);
}
@Override
public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException
{
AddFileHelper(new String[] { "filename" });
super.onRestore(data, appVersionCode, newState);
}
}
所以你看,我不靠的onCreate()。相反,我将正确的文件放在onBackup的列表中,并且我只在onRestore的列表中放置了一个文件名。然后,MyFileBackupHelper会在每次调用父级restoreEntity之前,替换该列表中的数组元素0。希望谷歌会让这个解决方案继续在他们的图书馆的未来版本中工作,因为它似乎是一个很好的功能!
你解决了这个问题吗?我遇到了同样的问题。你是如何检索所有文件然后将它们添加到FileBackupHelper的?除了使用getApplicationContext.fileList() – coolcool1994
你为什么要用其他方式?这是检索所有文件的方法。如果你不想全部备份,只需跳过不必要的。 这很简单,没有什么棘手的。 诀窍是**在恢复**。但为此,请参阅此主题的答案。 – Zotyi
哦,我看到我误解了那部分。不能,我们只是将文件列表保存为sharedpreference中设置的字符串,并且在我们恢复sharedpreference之后,只需恢复文件?这不会比下面的答案简单。 – coolcool1994