我有一个非常简单的首选项设置,其中将 PreferenceFragment
添加到 Activity
。 Activity
也是一个 OnSharedPreferenceChangeListener
,因为我想在特定偏好更新时更新该偏好的摘要。这是 Activity
:
public class PrefsActivity extends Activity implements OnSharedPreferenceChangeListener {
private static final String PREF_KEY = "key goes here";
private PrefsFragment pf;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pf = new PrefsFragment();
getFragmentManager().beginTransaction().replace(android.R.id.content, pf).commit();
// pf.getPreferenceScreen() throws a NullPointerException here
}
@Override
protected void onPause() {
super.onPause();
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
}
@Override
protected void onResume() {
super.onResume();
updateSummary();
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if (key.equals(PREF_KEY)) {
updateSummary();
}
}
private void updateSummary() {
Preference p = pf.getPreferenceScreen().findPreference(PREF_KEY);
p.setSummary("Some string containing the updated value");
}
}
PreferenceFragment 同样简单:
public class PrefsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
// At this point getPreferenceScreen() returns correctly
}
}
事情是这样的:在 PreferenceFragment
被实例化并添加到 中的
,抛出一个 Activity
之后立即调用 getPreferenceScreen()
PrefsActivity
的 onCreateNullPointerException
。似乎 getPreferenceScreen()
在 PrefsFragment
的 onCreate()
中开始返回一个 PreferenceScreen
对象,在调用之后立即addPreferencesFromResource()
返回。
所以我的问题是:由于 getPreferenceScreen()
在 PreferenceFragment
被添加到 Activity
后立即抛出 NPE,是PreferenceFragment
的onCreate()
异步调用/在不同线程中调用?否则我会期望 getPreferenceScreen()
在 getFragmentManager().beginTransaction().replace(android.R.id.content, pf).commit()
之后立即正常返回>.
最佳答案
is the onCreate() of the PreferenceFragment called asynchronously/in a different thread?
不是,它是在主线程上同步运行的。这意味着它必须等到 Activity
的 onCreate
退出才能运行。 FragmentManager
安排了 Fragment
回调,但直到当前回调( Activity 的 onCreate
)完成后才会执行。
您还有一些其他地方可以访问您的PreferenceScreen
。 OnStart
在 UI 准备就绪时调用,因此 Fragment
将准备就绪。 onResume
在 onStart
之后调用,并且可能是放置内容的最佳位置,因为它也是在从暂停回来后调用的。
关于Android Activity/PreferenceFragment 生命周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14473632/