我有一个非常简单的偏好设置,其中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
}
}
事情就是这样:在getPreferenceScreen()
上调用PreferenceFragment
,在实例化后立即将其添加到Activity
onCreate
中的PrefsActivity
,然后抛出NullPointerException
。在调用getPreferenceScreen()
之后,PreferenceScreen
似乎onCreate()
开始在PrefsFragment
addPreferencesFromResource()
内返回getPreferenceScreen()
对象。
所以我的问题是:由于PreferenceFragment
在Activity
被添加到onCreate()
后立即抛出NPE,PreferenceFragment
是getPreferenceScreen()
在另一个线程中异步调用?否则我会期望getFragmentManager().beginTransaction().replace(android.R.id.content, pf).commit()
之后{{1}}正常返回。{/ p>
答案 0 :(得分:4)
是在异步/中调用的PreferenceFragment的onCreate() 不同的线程?
不,它在主线程上同步运行。这意味着它必须等到Activity
s onCreate
退出才能运行。 FragmentManager
会调度Fragment
回调,但在活动的当前回调(onCreate
)完成之前不会执行这些回调。
您还有其他几个地方可以访问PreferenceScreen
。用户界面准备好后会调用OnStart
,因此Fragment
就绪了。在onResume
之后调用onStart
并且可能是放置内容的最佳位置,因为它在暂停后也会被调用。