2014-03-13 36 views
2

我想备份我的内部文件。这些由我的应用创建:随机数的文件和随机名称。像data1.xml,data7,xml,data13.xml,....Android数据备份:使用BackupAgentHelper的动态文件列表

所以我没有任何固定的文件列表。当我在MyBackupAgentHelper :: onCreate之前运行onBackup()时,我可以通过查询文件getApplicationContext()。fileList()轻松提供文件名。

public class MyBackupAgentHelper extends BackupAgentHelper 
{ 
    @Override 
    public void onCreate() 
    { 
    String[] files = getApplicationContext().fileList(); 
    FileBackupHelper helper = new FileBackupHelper(this, files); 
    addHelper(FILES_BACKUP_KEY, helper);  
    } 
... 

但是,如果OnRestore中准备卸载后运行/重新安装,我不能提供在OnCreate文件名,因为这时候getApplicationContext()的fileList()返回空列表 - 明显。

所以没有什么恢复:(

有没有什么办法,以恢复其进行备份了,而无需指定文件名?只是说:“做这一切”的所有文件。

如果不是,我怎么会用在这种情况下的数据备份?

感谢

+0

你解决了这个问题吗?我遇到了同样的问题。你是如何检索所有文件然后将它们添加到FileBackupHelper的?除了使用getApplicationContext.fileList() – coolcool1994

+0

你为什么要用其他方式?这是检索所有文件的方法。如果你不想全部备份,只需跳过不必要的。 这很简单,没有什么棘手的。 诀窍是**在恢复**。但为此,请参阅此主题的答案。 – Zotyi

+0

哦,我看到我误解了那部分。不能,我们只是将文件列表保存为sharedpreference中设置的字符串,并且在我们恢复sharedpreference之后,只需恢复文件?这不会比下面的答案简单。 – coolcool1994

回答

1

我只是碰到了同样的问题。这是令人沮丧,因为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。希望谷歌会让这个解决方案继续在他们的图书馆的未来版本中工作,因为它似乎是一个很好的功能!

+0

谢谢Brian。那次我跳过备份,我忘了这个线程,只是找到了你的答案。一个问题是,这个解决方案能够正确恢复文件名吗? – Zotyi

+0

是的。文件名确实恢复正常。您传递给onRestore中FileBackupHelper的阵列仅由FileBackupHelper使用,以检查返回的文件是否是您想要的文件。所以诀窍是总是将每个文件的名称放入文件名数组中(我们可以在restoreEntity中执行)。 –

+0

对不起,以后再回复。所以看着你的代码,你将文件名保存到你的private mMyFiles数组的第一项中。但那么它不会在任何地方使用? – Zotyi

0

编辑:你不能备份文件夹 - 你需要单独列出文件助手中的文件来备份这些文件。

+0

将文件夹传递给FileBackupHelper构造函数是否有效?那它是递归的呢?我不知道。 – Zotyi

+0

将文件夹传递给FileBackupHelper构造函数是否有效?你只允许传递文件吗?也许这是为什么我的共享首选项备份而不是我的文件? – coolcool1994

+0

FileBackupHelper只备份并恢复您传递给它的文件。它不会备份整个目录。请参阅https://android.googlesource.com/platform/frameworks/base.git/+/android-4.2.2_r1/core/java/android/app/backup/FileBackupHelper.java –