我正在考虑使用自Android 2.2以来可用的新备份API,但需要保持向后兼容(确切地说为1.5)。

文档国家:

您必须使用的备份服务和API仅在运行API级别8(Android 2.2)或更高的设备上可用,因此您还应将Android:Minsdkversion属性设置为“ 8”。但是,如果您在应用程序中实现适当的向后兼容性,则可以为运行API 8或更高的设备支持此功能,同时保持与旧设备的兼容。

我确实是在8级的基础上建立的 targetSdkVersion 与3级 minSdkVersion 并尝试使用包装器类(带有反射)来克服如果您实现扩展不存在的类的类,则应用程序将无法运行。

这是问题:因为我们没有对 BackupHelper 我们自己上课,我们无法预先检查班级是否确实存在。 (如Android向后兼容文档中所述 checkAvailable() 方法。)因此,该类将被实例化并投入到 BackupAgent. 。但是,由于我们使用反射,因此实际上并没有覆盖备份,并且在要求备份时发生了例外:

java.lang.RuntimeException: Unable to create BackupAgent org.transdroid.service.BackupAgent: java.lang.ClassCastException: org.transdroid.service.BackupAgent

这是我向后兼容的方法 BackupAgent: http://code.google.com/p/transdroid/source/browse/#svn/trunk/src/org/transdroid/service 其中backupagent.java是“常规”备份延伸式延伸类,而备份的backupenthelperwrapper是基于反射的包装类。

任何成功实施的人 BackupAgent 兼容性?

有帮助吗?

解决方案

我不明白为什么您会遇到这个问题。

我也有同样的问题:我想支持一个支持1.5(API 3)的应用程序的备份。

创建我的 BackupAgentHelper 班级,因为该课程从未从我自己的代码中调用,而是从 BackupManager 即系统本身。因此,我不需要包装它,也不知道为什么要这样做:

 public class MyBackupAgentHelper extends BackupAgentHelper {
 @override onCreate()
 { 
       \\do something usefull
 }

但是,您确实想进行备份运行,以便您需要打电话 BackupManager.dataChanged() 每当您的数据更改并要通知系统备份它时(使用您的 BackupAgent 或者 BackupAgentHelper).

您确实需要包装该类,因为您从应用程序代码调用它。


public class WrapBackupManager {
private BackupManager wrappedInstance;

static 
{
    try
    {
        Class.forName("android.app.backup.BackupManager");
    }
    catch (Exception e)
    {
        throw new RuntimeException(e);
    }
}
public static void checkAvailable() {}

public void dataChanged()
{
    wrappedInstance.dataChanged();
}

public WrapBackupManager(Context context)
{
    wrappedInstance = new BackupManager(context);
}

}

然后,当您更改偏好或保存一些数据时,您将其从代码中调用。我的应用程序中的一些代码:


private static Boolean backupManagerAvailable = null;

    private static void postCommitAction() {


        if (backupManagerAvailable == null) {
            try {
                WrapBackupManager.checkAvailable();
                backupManagerAvailable = true;
            } catch (Throwable t) {
                backupManagerAvailable = false;
            }
        }

        if (backupManagerAvailable == true) {
            Log.d("Fretter", "Backup Manager available, using it now.");
            WrapBackupManager wrapBackupManager = new WrapBackupManager(
                    FretterApplication.getApplication());
            wrapBackupManager.dataChanged();
        } else {
            Log.d("Fretter", "Backup Manager not available, not using it now.");
        }

因此,希望这对您有用!

(如果您打电话 adb shell bmgr run 每当您想模拟实际的后系统时,当您重新安装应用程序时,都应正确备份并还原。

其他提示

作为替代方案,您可以使用纯反射与Backupmanager交谈:

public void scheduleBackup() {
    Log.d(TAG, "Scheduling backup");
    try {
        Class managerClass = Class.forName("android.app.backup.BackupManager");
        Constructor managerConstructor = managerClass.getConstructor(Context.class);
        Object manager = managerConstructor.newInstance(context);
        Method m = managerClass.getMethod("dataChanged");
        m.invoke(manager);
        Log.d(TAG, "Backup requested");
    } catch(ClassNotFoundException e) {
        Log.d(TAG, "No backup manager found");
    } catch(Throwable t) {
        Log.d(TAG, "Scheduling backup failed " + t);
        t.printStackTrace();
    }
}

指向Android:备用直接在V2.2类中;它永远不会加载到VM前VM上,因此不会存在任何链接问题。

您需要将Minsdk版本设置为以下内容:

<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="8"/>

并将构建目标设置为SDK 8(Eclipse'.default.properties'中的项目属性'):

# Project target.
target=android-8

现在要调用SDK 8中添加的新内容,您必须使用反射: http://developer.android.com/resources/articles/backward-compatibility.html

我遇到了同样的问题,这是我为解决问题所做的。

您不会使用包装器扩展备份,而是将其扩展到包装类别。所以你让你的 真实的 备份课:

public class MyBackup extends BackupAgent {

@Override
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
        ParcelFileDescriptor newState) throws IOException {
    // TODO Auto-generated method stub

}

@Override
public void onRestore(BackupDataInput data, int appVersionCode,
        ParcelFileDescriptor newState) throws IOException {
    // TODO Auto-generated method stub

}

好的,然后您将像Android Developer这样做的包装器向后兼容文章。请注意这个课程 才不是 扩展备份:

public class WrapMyBackup {
private MyBackup wb;

static {
    try {
        Class.forName("MyBackup");
    }
    catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}

/** call this wrapped in a try/catch to see if we can instantiate **/
public static void checkAvailable() {}

public WrapMyBackup() {
    wb = new MyBackup();
}

public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
        ParcelFileDescriptor newState) throws IOException {
    wb.onBackup(oldState, data, newState);

}

public void onRestore(BackupDataInput data, int appVersionCode,
        ParcelFileDescriptor newState) throws IOException {
    wb.onRestore(data, appVersionCode, newState);

}

public void onCreate() {
    wb.onCreate();
}

public void onDestroy() {
    wb.onDestroy();
}

}

最后,在您的清单中,您将包装器声明为您的备份代理:

    <application 
    android:label="@string/app_name"
    android:icon="@drawable/ic_launch_scale"
    android:backupAgent="WrapMyBackup"
    >

由于您的包装器具有正确的定义方法,因此当备份管理器将其投射到备份时,您不会遇到问题。由于较低的API级别不会有备份manager,因此代码永远不会被调用,因此您也不会遇到任何运行时例外。

仅调用backupmanager.datachanged,请检查该类是否首先存在。

   try {
            Class.forName("android.app.backup.BackupManager");
            BackupManager.dataChanged(context.getPackageName());
        } catch (ClassNotFoundException e) {
        }

怎么样

    if (android.os.Build.VERSION.SDK_INT >= 8) 
    {
        BackupManager bm = new BackupManager(this);
        bm.dataChanged();
    }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top