在 Activity 的 onCreate
中,我首先检查一些远程数据,如果尚未检查,然后更新 UI:
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
?
最佳答案
在 Activity 被 GC 之前,WeakReference 不会被设置为 null,这可能是在它被销毁之后的一段时间。在“isFinishing()”之后,添加对“isDestroyed()”的检查。这需要 API 级别 17,因此您可能需要自己实现它(在 onDestroy 中设置为 false 的 bool 字段)。
另外,为了整洁起见,只调用一次 WeakReference.get()。理论上,GC 可以在两次调用之间运行,从而为您提供 NullPointerException。
关于android - 引用已销毁的 Activity,即使使用了 WeakReference,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26220322/