在活动onCreate
中,我首先检查一些远程数据(如果尚未检查),然后更新用户界面:
private static WeakReference<MainActivity> wrActivity = null;
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
wrActivity = new WeakReference<MainActivity>(this);
// ...
}
private class InitTask extends AsyncTask<Object, Void, Bundle> {
@Override
protected Bundle doInBackground(Object... params) {
// checking some (network) stuff
return (Bundle) params[0];
}
@Override
protected void onPostExecute(final Bundle savedInstanceState) {
if (wrActivity.get() == null || wrActivity.get().isFinishing()) {
return;
}
updateUi(savedInstanceState);
}
}
private void updateUi(Bundle savedInstanceState) {
Log.d(getClass().getSimpleName(), "updateUi()");
if (savedInstanceState == null) {
resetActionBar();
}
initPagerAndTabs(savedInstanceState);
// ...
}
private void initPagerAndTabs(Bundle savedInstanceState) {
Log.d(getClass().getSimpleName(), "initPagerAndTabs()");
mTabNames = getResources().getStringArray(R.array.tabs);
mAdapter = new FragmentAdapter(getSupportFragmentManager());
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mPager.setOnPageChangeListener(mAdapter);
// ...
}
但是,有时,我的应用程序崩溃了:
java.lang.IllegalStateException: Activity has been destroyed
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1376)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:578)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:139)
at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:415)
at com.mypackage.MainActivity.access$9(MainActivity.java:1358)
at com.mypackage.MainActivity$InitTask.onPostExecute(MainActivity.java:1)
第1358行恰好是第一行:
private void updateUi(Bundle savedInstanceState) {
因此,WeakReference
(模式)不会将AsyncTask
返回结果保存为不同的MainActivity。
在这种情况下,最好的方法是什么? ServiceIntent
?
答案 0 :(得分:2)
在活动为GC之后,WeakReference不会设置为null,这可能是在销毁之后的一段时间。在&#34; isFinishing()&#34;之后,添加一个检查&#34; isDestroyed()&#34;。这需要API级别17,因此您可能需要自己实现它(在onDestroy中设置为false的布尔字段)。
另外,为了整洁,只使用一次WeakReference.get()调用。从理论上讲,GC可以在两次调用之间运行,给你一个NullPointerException。
答案 1 :(得分:0)
您的私人非静态类InitTask保留对您的活动的引用。 您可以阅读this。