In activity's onCreate I first check some remote data, if not already checked and then update the 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);
// ...
}
But, sometimes, my app crashes with this:
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)
The line 1358 is exactly whis one:
private void updateUi(Bundle savedInstanceState) {
So, the WeakReference (pattern) does not save me from AsyncTask returning result to a different MainActivity.
What is the best approach in this case? ServiceIntent?
The WeakReference will not be set to null until the activity is GC'd, which might be a while after it has been destroyed. After "isFinishing()", add a check for "isDestroyed()". This requires API level 17, so you might need to implement it yourself (a boolean field that is set to false in onDestroy).
Also, for neatness, only use a single call to WeakReference.get(). Theoretically, the GC can run in between the two calls, giving you a NullPointerException.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With