0

版主注意-我知道这个话题在过去被高度讨论过。然而,我越深入,我就越迷失。而且我相信我的问题是我在社区的任何地方都找不到的一次性问题。如果您已经遇到过类似的帖子,我建议您在结束此问题之前分享。

你好,

我喜欢为所有 android 版本使用一个 PreferenceActivity 类。我关注了这个链接

活动课是

public class PreferencesActivity extends PreferenceActivity implements OnPreferenceChangeListener {
protected Method mLoadHeaders;
protected Method mHasHeaders;

public boolean isNewV11Prefs() {
    if(null != mHasHeaders && null != mLoadHeaders) {
        try {
            return (Boolean)mHasHeaders.invoke(this);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    return false;
}

@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
    try {
        mLoadHeaders = getClass().getMethod("loadHeadersFromResource", int.class, List.class);
        mHasHeaders = getClass().getMethod("hasHeaders");
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
    super.onCreate(savedInstanceState);

    if(!isNewV11Prefs()) {
        addPreferencesFromResource(R.xml.preference_account_settings);

        PreferenceManager preferenceManager = getPreferenceManager();  
    }
}

@Override
public void onBuildHeaders(List<Header> aTarget) {
    try {
        mLoadHeaders.invoke(this, new Object[]{R.xml.preference_headers, aTarget});
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
}



@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
    Log.i(TAG_NAME, "preference change..!");

    return true;
}

/**
 * Helper method to forcibly set context to a preference.
 * This is a bug reported for Android TabHost. As a workaround, 
 * a known context is explicitly set to preference.
 * @param context parent context
 * @param p preference instance
 */
private void forceContext(Context context, Preference p){
    try {
        Field field = Preference.class.getDeclaredField("mContext");
        field.setAccessible(true);
        field.set(p, getParent());
    } catch (Exception e) {
        e.printStackTrace();
    }  
}

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
static public class PrefsFragment extends PreferenceFragment implements OnPreferenceChangeListener {
    private CheckBoxPreference searchAllAccounts;
    private ListPreference accountType;
    private ListPreference searchFor;
    private String accountTypeDesc;
    private String searchForDesc;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Context context = getActivity().getApplicationContext();
        int prefResourceId = context.getResources().getIdentifier(getArguments().getString("pref-resource"), "xml", context.getPackageName());

        addPreferencesFromResource(prefResourceId);
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        return true;
    }


}
}

在所有 android 版本 > 2.3 上都会打开首选项屏幕但是,当我在 2.3 模拟器上执行此操作时,应用程序会引发以下错误。

java.lang.NoSuchMethodException: loadHeadersFromResource
at java.lang.ClassCache.findMethodByName(ClassCache.java:247)
at java.lang.Class.getMethod(Class.java:962)
at com.android.mobile.screens.PreferencesFragment.onCreate(PreferencesFragment.java:62)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3683)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)

我缺少什么?有什么线索吗?

4

2 回答 2

1

首先,将您构建的平台设置为 > API 11,然后您将不需要使用反射。但在这种情况下,您需要检查 api probramatically,即

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        ActionBar bar = this.getActionBar();
        bar.setDisplayHomeAsUpEnabled(true);
        bar.setDisplayUseLogoEnabled(true);

        loadHeadersFromResource(R.xml.settings_headers, headersList);
    }

    else {

        addPreferencesFromResource(R.xml.settings);
    }
}
于 2013-07-26T10:52:14.030 回答
0

PreferenceActivity.loadHeadersFromResource从 api 开始可用11,如果您的设备具有较低的 api 级别,则无法使用它。在这里你可以找到文档

于 2013-07-26T10:46:17.190 回答