使用TargetApi注释无法从较新的API中找到方法

时间:2012-11-18 20:29:32

标签: android eclipse

从4开始,我想使用下一个代码为所有Android API应用SharedPreferences。

/**
 * The apply method was introduced 
 * in Android API level 9.<br> Calling it causes a safe asynchronous write 
 * of the SharedPreferences.Editor object to be performed. Because
 * it is asynchronous, it is the preferred technique for saving SharedPreferences.<br> 
 * So we should use appropriate method if we doesn`t need confirmation of success.
 * In this case we should use old commit method.
 */
@TargetApi(9)
    public static void applySharedPreferences(SharedPreferences.Editor editor){
    if (Build.VERSION.SDK_INT < 9){
        editor.commit();
    } else {
        editor.apply();
    }
}

项目目标API为10(在“项目属性”中设置)。 它在API 8上工作正常,但是当我尝试在API 4上运行时,它会在下一条消息中崩溃:

11-18 20:21:45.782: E/dalvikvm(323): Could not find method android.content.SharedPreferences$Editor.apply, referenced from method my.package.utils.Utils.applySharedPreferences

它通常安装在设备上但在启动期间崩溃。为什么在此API中没有使用此方法(apply)时会发生这种情况?

由于

2 个答案:

答案 0 :(得分:5)

  

它在API 8上工作正常,但是当我尝试在API 4上运行时,它会在下一条消息中崩溃:

在Android 1.x中,Dalvik非常保守,如果您尝试加载包含无法解析的引用的类(在本例中为apply()),则会崩溃。您的选择是:

  1. 放弃对Android 1.x的支持,或

  2. 请勿使用apply(),但只需在自己的后台主题中使用commit(),或

  3. 使用静态GingerbreadHelper方法创建另一个类(例如apply()),该方法将SharedPreferences.Editor作为参数并在其上调用apply()。然后,将applySharedPreferences()更改为使用GingerbreadHelper.apply(editor)而不是editor.apply()。只要您从未在Android 1.x设备上加载GingerbreadHelper,就可以避免使用VerifyError

答案 1 :(得分:1)

这不是错误的方式吗?

不应该是:

@TargetApi(9)
public static void applySharedPreferences(SharedPreferences.Editor editor)
{
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD)
    {
        editor.apply();
    }
    else
    {
        editor.commit();
    }
}

这将解决你的问题!

虽然更好!

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public static void applySharedPreferences(final SharedPreferences.Editor editor)
{
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD)
    {
        editor.apply();
    }
    else
    {
        new AsyncTask<Void, Void, Void>(){
            @Override
            protected Void doInBackground(Void... params)
            {
                editor.commit();
                return null;
            }
        }.execute();
    }
}

它现在总是异步!