0

モデレーターへの注意 - このトピックが過去に非常に議論されたことを理解しています. しかし、深く掘り下げるほど、私は迷子になりました。そして、私のものは、コミュニティのどこにも見つからなかった 1 回限りの問題だと思います。すでに同様の投稿を見つけた場合は、この質問を閉じる前に共有することをお勧めします.

やあ、

私は、すべての Android バージョンに対して 1 つの 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;
    }


}
}

The preference screen opens up on all android versions > 2.3 However, when I do it on 2.3 emulator, the app throws the following error.

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)

What am I lacking? Any clue?

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.loadHeadersFromResourceapi から利用でき11ますが、デバイスの API レベルが低い場合は使用できません。ここでドキュメントを見つけることができます

于 2013-07-26T10:46:17.190 に答える