A reference to the destroyed activity, although the WeakReference method was used

In Action onCreate

Check some deleted data first if it hasn't been verified yet, then refresh the interface:

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 application 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)

      

Line 1358 matches exactly one:

private void updateUi(Bundle savedInstanceState) {

      

So, WeakReference

(pattern) doesn't get rid of me by AsyncTask

returning the result to another MainActivity.

What's the best approach in this case? ServiceIntent

?

+3


source to share


2 answers


The WeakReference will not be set to null until the activity is GC'd, which may be some time after it is destroyed. After isFinishing () add a check for isDestroyed (). This requires API level 17, so you may need to implement it yourself (boolean field set to false in onDestroy).



Also, for neatness, use only one call to WeakReference.get (). In theory, GC can run between the two calls, giving you a NullPointerException.

+2


source


Your private, non-static InitTask class contains a link to your activity. You can read this about it.



0


source







All Articles