java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

168,573

Solution 1

You should do the transaction in a Handler as follows:

@Override
protected void onPostExecute(String result) {
    Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute");
    new Handler().post(new Runnable() {
            public void run() {
                fm = getSupportFragmentManager();
                ft = fm.beginTransaction();
                ft.remove(dummyFragment);
                ft.commit();
            }
        });
}

Solution 2

Thanks Oleg Vaskevich. Using a WeakReference of the FragmentActivity solved the problem. My code looks as follows now:

public class MyFragmentActivity extends FragmentActivity implements OnFriendAddedListener {

    private static WeakReference<MyFragmentActivity> wrActivity = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        wrActivity = new WeakReference<MyFragmentActivity>(this);
        ...

    private class onFriendAddedAsyncTask extends AsyncTask<String, Void, String> {

        @Override
        protected void onPreExecute() {
            FragmentManager fm = getSupportFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            DummyFragment dummyFragment = DummyFragment.newInstance();
            ft.add(R.id.dummy_fragment_layout, dummyFragment);
            ft.commit();
        }

        @Override
        protected void onPostExecute(String result) {
            final Activity activity = wrActivity.get();
            if (activity != null && !activity.isFinishing()) {
                FragmentManager fm = activity.getSupportFragmentManager();
                FragmentTransaction ft = fm.beginTransaction();
                DummyFragment dummyFragment = (DummyFragment) fm.findFragmentById(R.id.dummy_fragment_layout);
                ft.remove(dummyFragment);
                ft.commitAllowingStateLoss();
            }
        }

Solution 3

I believe the correct answer to this question is the following method.

public abstract int commitAllowingStateLoss ()

Like commit() but allows the commit to be executed after an activity's state is saved. This is dangerous because the commit can be lost if the activity needs to later be restored from its state, so this should only be used for cases where it is okay for the UI state to change unexpectedly on the user.

The above description relates to this method.

protected void onSaveInstanceState(android.os.Bundle outState)

This problem occurs precisely when the device goes to sleep.

http://developer.android.com/reference/android/app/FragmentTransaction.html

Solution 4

Short And working Solution :

Follow Simple Steps :

Step 1 : Override onSaveInstanceState state in respective fragment. And remove super method from it.

@Override
public void onSaveInstanceState(Bundle outState) {
}

Step 2 : Use CommitAllowingStateLoss(); instead of commit(); while fragment operations.

fragmentTransaction.commitAllowingStateLoss();

Solution 5

Check if the activity isFinishing() before showing the fragment.

Example:

if(!isFinishing()) {
FragmentManager fm = getSupportFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            DummyFragment dummyFragment = DummyFragment.newInstance();
            ft.add(R.id.dummy_fragment_layout, dummyFragment);
            ft.commitAllowingStateLoss();
}
Share:
168,573
samo
Author by

samo

Updated on July 04, 2020

Comments

  • samo
    samo almost 4 years

    I'm using the support library for my app. In my FragmentActivity I'm using an AsyncTask for downloading data from internet. In the onPreExecute() method I add a Fragment and in the onPostExecute() method I remove it again. When the orientation is changed in between, I get the above mentioned exception. Please take a look at the details:

    private class onFriendAddedAsyncTask extends AsyncTask<String, Void, String> {
        DummyFragment dummyFragment; 
        FragmentManager fm;
        FragmentTransaction ft;
    
    @Override
    protected void onPreExecute() {
        Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute");
        dummyFragment = DummyFragment.newInstance();
        fm = getSupportFragmentManager();
        ft = fm.beginTransaction();
        ft.add(dummyFragment, "dummy_fragment");
        ft.commit();
    }
    
    @Override
    protected void onPostExecute(String result) {
        Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute");
        ft = fm.beginTransaction();
        ft.remove(dummyFragment);
        ft.commit();
    }
    
    @Override
    protected String doInBackground(String... name) {
        Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/doInBackground");
        ...
    }
    

    I get following LogCut:

    01-05 23:54:19.958: V/MyFragmentActivity(12783): onFriendAddedAsyncTask/onPreExecute
    01-05 23:54:19.968: V/DummyFragment(12783): onAttach
    01-05 23:54:19.968: V/DummyFragment(12783): onCreate
    01-05 23:54:19.968: V/MyFragmentActivity(12783): onFriendAddedAsyncTask/doInBackground
    01-05 23:54:19.973: V/DummyFragment(12783): onCreateView
    01-05 23:54:19.973: V/DummyFragment(12783): onActivityCreated
    01-05 23:54:19.973: V/DummyFragment(12783): onStart
    01-05 23:54:19.973: V/DummyFragment(12783): onResume
    01-05 23:54:21.933: V/MyFragmentActivity(12783): onSaveInstanceState
    01-05 23:54:21.933: V/DummyFragment(12783): onSaveInstanceState
    01-05 23:54:21.933: V/MyFragmentActivity(12783): onPause
    01-05 23:54:21.933: V/DummyFragment(12783): onPause
    01-05 23:54:21.938: V/MyFragmentActivity(12783): onStop
    01-05 23:54:21.938: V/DummyFragment(12783): onStop
    01-05 23:54:21.938: V/MyFragmentActivity(12783): onDestroy
    01-05 23:54:21.938: V/DummyFragment(12783): onDestroyView
    01-05 23:54:21.938: V/DummyFragment(12783): onDestroy
    01-05 23:54:21.938: V/DummyFragment(12783): onDetach
    01-05 23:54:21.978: V/MyFragmentActivity(12783): onCreate
    01-05 23:54:21.978: V/DummyFragment(12783): onAttach
    01-05 23:54:21.978: V/DummyFragment(12783): onCreate
    01-05 23:54:22.263: V/MyFragmentActivity(12783): onStart
    01-05 23:54:22.313: V/DummyFragment(12783): onCreateView
    01-05 23:54:22.313: V/DummyFragment(12783): onActivityCreated
    01-05 23:54:22.313: V/DummyFragment(12783): onStart
    01-05 23:54:22.323: V/MyFragmentActivity(12783): onResume
    01-05 23:54:22.323: V/MyFragmentActivity(12783): onPostResume
    01-05 23:54:22.323: V/MyFragmentActivity(12783): onResumeFragments
    01-05 23:54:22.323: V/DummyFragment(12783): onResume
    01-05 23:54:27.123: V/MyFragmentActivity(12783): onFriendAddedAsyncTask/onPostExecute
    01-05 23:54:27.123: D/AndroidRuntime(12783): Shutting down VM
    01-05 23:54:27.123: W/dalvikvm(12783): threadid=1: thread exiting with uncaught exception (group=0x4001d7d0)
    01-05 23:54:27.138: E/AndroidRuntime(12783): FATAL EXCEPTION: main
    01-05 23:54:27.138: E/AndroidRuntime(12783): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1314)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1325)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:548)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:532)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at com.xyz.dummy.MyFragmentActivity$onFriendAddedAsyncTask.onPostExecute(MyFragmentActivity.java:447)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at com.xyz.dummy.MyFragmentActivity$onFriendAddedAsyncTask.onPostExecute(MyFragmentActivity.java:1)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at android.os.AsyncTask.finish(AsyncTask.java:417)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at android.os.AsyncTask.access$300(AsyncTask.java:127)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at android.os.Handler.dispatchMessage(Handler.java:99)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at android.os.Looper.loop(Looper.java:123)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at android.app.ActivityThread.main(ActivityThread.java:4627)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at java.lang.reflect.Method.invokeNative(Native Method)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at java.lang.reflect.Method.invoke(Method.java:521)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
    01-05 23:54:27.138: E/AndroidRuntime(12783):    at dalvik.system.NativeStart.main(Native Method)
    

    In other threads about similar problems the reason seems to be that the onPostExecute method is called before the onResume() method is called. But I get the exception even though onResume() is called before.

    Does someone knows what's wrong?

    The Activity looks like this:

    public class MyFragmentActivity extends FragmentActivity implements OnFriendSelectedListener, OnFriendAddedListener, OnFriendOptionSelectedListener, LoaderCallbacks<Cursor> {
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.v("MyFragmentActivity", "onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_activity_layout);
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        FriendListFragment friendListFragment = (FriendListFragment)fm.findFragmentById(R.id.friend_list_fragment_layout);
        if (friendListFragment == null) {
            friendListFragment = new FriendListFragment(); 
            ft.add(R.id.friend_list_fragment_layout, friendListFragment);
            ft.commit();
            fm.executePendingTransactions();
            startService(new Intent(this, MyIntentService.class));
            getSupportLoaderManager().initLoader(CHECK_EMPTY_DATABASE, null, this);
        }
    }
    
        @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.fragment_activity_options_menu, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        super.onOptionsItemSelected(item);
        switch (item.getItemId()) {
        case R.id.add_friend_menu_item:
            AddFriendDialogFragment addFriendDialogFragment = AddFriendDialogFragment.newInstance();
            addFriendDialogFragment.show(getSupportFragmentManager(), "add_friend_dialog_fragment");
            return true;
        default:
            return false;
        }
    }
    
    @Override
    public void onFriendAdded(String name) {
        name = name.trim();
        if (name.length() > 0) {
            new onFriendAddedAsyncTask().execute(name);
        }
    }
    

    When using commitAllowingStateLoss() I get the following exception:

    01-06 14:54:29.548: E/AndroidRuntime(18020): FATAL EXCEPTION: main
    01-06 14:54:29.548: E/AndroidRuntime(18020): java.lang.IllegalStateException: Activity has been destroyed
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1329)
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:548)
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:536)
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at com.xyz.dummy.FadiaFragmentActivity$onFriendAddedAsyncTask.onPostExecute(FadiaFragmentActivity.java:461)
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at com.xyz.dummy.FadiaFragmentActivity$onFriendAddedAsyncTask.onPostExecute(FadiaFragmentActivity.java:1)
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at android.os.AsyncTask.finish(AsyncTask.java:417)
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at android.os.AsyncTask.access$300(AsyncTask.java:127)
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at android.os.Handler.dispatchMessage(Handler.java:99)
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at android.os.Looper.loop(Looper.java:123)
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at android.app.ActivityThread.main(ActivityThread.java:4627)
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at java.lang.reflect.Method.invokeNative(Native Method)
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at java.lang.reflect.Method.invoke(Method.java:521)
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
    01-06 14:54:29.548: E/AndroidRuntime(18020):    at dalvik.system.NativeStart.main(Native Method)
    

    I get the same IllegalStateExeption when I implement the AsynTask as follows, because the findFragmentById() method returns a null pointer.

    private class onFriendAddedAsyncTask extends AsyncTask<String, Void, String> {
    
        protected void onPreExecute() {
            Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute");
            FragmentManager fm = getSupportFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            DummyFragment dummyFragment = DummyFragment.newInstance();
            ft.add(R.id.dummy_fragment_layout, dummyFragment);
            ft.commit();
        }
    
        protected void onPostExecute(String result) {
            Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute");
            FragmentManager fm = getSupportFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            DummyFragment dummyFragment = (DummyFragment) fm.findFragmentById(R.id.dummy_fragment_layout);
            ft.remove(dummyFragment);
            ft.commitAllowingStateLoss();
        }
    

    In the next step I use a handler for the adding and removing the DummyFragment. Additionally I've added some more debug output.

    private class onFriendAddedAsyncTask extends AsyncTask<String, Void, String> {
    
        @Override
        protected void onPreExecute() {
            Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager());
            Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout));
            Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout));
    
            new Handler().post(new Runnable() {
                public void run() {
                    Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager());
                    Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout));
                    Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout));
                    FragmentManager fm = getSupportFragmentManager();
                    FragmentTransaction ft = fm.beginTransaction();
                    DummyFragment dummyFragment = DummyFragment.newInstance();
                    ft.add(R.id.dummy_fragment_layout, dummyFragment);
                    ft.commit();
                }
            });
    
        @Override
        protected void onPostExecute(String result) {
            Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager());
            Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout));
            Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout));
    
            new Handler().post(new Runnable() {
                public void run() {
                    Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager());
                    Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout));
                    Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout));
                    FragmentManager fm = getSupportFragmentManager();
                    FragmentTransaction ft = fm.beginTransaction();
                    DummyFragment dummyFragment = (DummyFragment) fm.findFragmentById(R.id.dummy_fragment_layout);
                    ft.remove(dummyFragment);
                    ft.commitAllowingStateLoss();
                }
            });
    

    I get following LogCut:

    01-07 19:00:17.273: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FragmentManager{45e384a8 in MyFragmentActivity{45e38358}}
    01-07 19:00:17.273: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute null
    01-07 19:00:17.273: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FriendListFragment{45e38ab0 #0 id=0x7f0a0002}
    01-07 19:00:17.283: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FragmentManager{45e384a8 in MyFragmentActivity{45e38358}}
    01-07 19:00:17.288: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/doInBackground
    01-07 19:00:17.288: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute null
    01-07 19:00:17.288: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FriendListFragment{45e38ab0 #0 id=0x7f0a0002}
    01-07 19:00:17.308: V/DummyFragment(4124): onAttach DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:17.308: V/DummyFragment(4124): onCreate DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:17.308: V/DummyFragment(4124): onCreateView DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:17.308: V/DummyFragment(4124): onActivityCreated DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:17.308: V/DummyFragment(4124): onStart DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:17.313: V/DummyFragment(4124): onResume DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:18.098: V/MyFragmentActivity(4124): onSaveInstanceState DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:18.098: V/DummyFragment(4124): onSaveInstanceState DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:18.098: V/MyFragmentActivity(4124): onPause DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:18.098: V/DummyFragment(4124): onPause DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:18.103: V/MyFragmentActivity(4124): onStop DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:18.103: V/DummyFragment(4124): onStop DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:18.103: V/MyFragmentActivity(4124): onDestroy DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:18.103: V/DummyFragment(4124): onDestroyView DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:18.108: V/DummyFragment(4124): onDestroy DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:18.113: V/DummyFragment(4124): onDetach DummyFragment{45dd7498 #2 id=0x7f0a0004}
    01-07 19:00:18.138: V/MyFragmentActivity(4124): onCreate
    01-07 19:00:18.138: V/FriendListFragment(4124): FriendListFragment
    01-07 19:00:18.138: V/FriendListFragment(4124): onAttach FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
    01-07 19:00:18.138: V/FriendListFragment(4124): onCreate FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
    01-07 19:00:18.148: V/DummyFragment(4124): onAttach DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
    01-07 19:00:18.153: V/DummyFragment(4124): onCreate DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
    01-07 19:00:18.523: V/MyFragmentActivity(4124): onStart DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
    01-07 19:00:18.543: V/FriendListFragment(4124): onActivityCreated FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
    01-07 19:00:18.548: V/DummyFragment(4124): onCreateView DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
    01-07 19:00:18.548: V/DummyFragment(4124): onActivityCreated DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
    01-07 19:00:18.548: V/FriendListFragment(4124): onLoadFinished FragmentManager{45d8e478 in MyFragmentActivity{45e4a6d8}}
    01-07 19:00:18.548: V/FriendListFragment(4124): onLoadFinished FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
    01-07 19:00:18.553: V/DummyFragment(4124): onStart DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
    01-07 19:00:18.553: V/FriendListFragment(4124): onLoadFinished FragmentManager{45d8e478 in MyFragmentActivity{45e4a6d8}}
    01-07 19:00:18.553: V/FriendListFragment(4124): onLoadFinished FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
    01-07 19:00:18.558: V/MyFragmentActivity(4124): onResume DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
    01-07 19:00:18.558: V/MyFragmentActivity(4124): onPostResume DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
    01-07 19:00:18.558: V/MyFragmentActivity(4124): onResumeFragments DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
    01-07 19:00:18.558: V/FriendListFragment(4124): onResume FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
    01-07 19:00:18.563: V/FriendListFragment(4124): onCreateLoader FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
    01-07 19:00:18.563: V/DummyFragment(4124): onResume DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
    01-07 19:00:18.723: V/FriendListFragment(4124): onLoadFinished FragmentManager{45d8e478 in MyFragmentActivity{45e4a6d8}}
    01-07 19:00:18.723: V/FriendListFragment(4124): onLoadFinished FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
    01-07 19:00:18.893: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute FragmentManager{45e384a8 in null}}
    01-07 19:00:18.893: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null
    01-07 19:00:18.893: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null
    01-07 19:00:18.923: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute FragmentManager{45e384a8 in null}}
    01-07 19:00:18.923: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null
    01-07 19:00:18.923: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null
    01-07 19:00:18.928: D/AndroidRuntime(4124): Shutting down VM
    01-07 19:00:18.928: W/dalvikvm(4124): threadid=1: thread exiting with uncaught exception (group=0x4001d7d0)
    01-07 19:00:18.938: E/AndroidRuntime(4124): FATAL EXCEPTION: main
    01-07 19:00:18.938: E/AndroidRuntime(4124): java.lang.IllegalStateException: Activity has been destroyed
    01-07 19:00:18.938: E/AndroidRuntime(4124):     at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1329)
    01-07 19:00:18.938: E/AndroidRuntime(4124):     at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:548)
    01-07 19:00:18.938: E/AndroidRuntime(4124):     at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:536)
    01-07 19:00:18.938: E/AndroidRuntime(4124):     at com.xyz.dummy.MyFragmentActivity$onFriendAddedAsyncTask$2.run(MyFragmentActivity.java:476)
    01-07 19:00:18.938: E/AndroidRuntime(4124):     at android.os.Handler.handleCallback(Handler.java:587)
    01-07 19:00:18.938: E/AndroidRuntime(4124):     at android.os.Handler.dispatchMessage(Handler.java:92)
    01-07 19:00:18.938: E/AndroidRuntime(4124):     at android.os.Looper.loop(Looper.java:123)
    01-07 19:00:18.938: E/AndroidRuntime(4124):     at android.app.ActivityThread.main(ActivityThread.java:4627)
    01-07 19:00:18.938: E/AndroidRuntime(4124):     at java.lang.reflect.Method.invokeNative(Native Method)
    01-07 19:00:18.938: E/AndroidRuntime(4124):     at java.lang.reflect.Method.invoke(Method.java:521)
    01-07 19:00:18.938: E/AndroidRuntime(4124):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
    01-07 19:00:18.938: E/AndroidRuntime(4124):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
    01-07 19:00:18.938: E/AndroidRuntime(4124):     at dalvik.system.NativeStart.main(Native Method)
    

    In onPreExecute() the FriendListFragment has the id=0x7f0a0002. Inside the handler the DummyFragment is created with id=0x7f0a0004. In onPostExecute() both IDs are null. In onPreExecute() the address of MyFragmentActivity is 45e38358. but in onPostExecute() it's null. But in both methods the FragmentManager address is 45e384a8. I guess onPostExecute uses an invalid FragmentManager. But why?

  • samo
    samo over 11 years
    It doesn't help. Behaviour is the same like before.
  • Lisa Anne
    Lisa Anne over 11 years
    @samo please have you been able to solve the issue? I have a very similar situation link
  • samo
    samo over 11 years
    No, I'm still searching for a solution
  • Oleg Vaskevich
    Oleg Vaskevich over 11 years
    The reason is that you are leaking your Activity because you're keeping a reference to the FragmentManager. Try my edit above which should require the FragmentManager and make sure to set fm when your Activity is destroyed.
  • samo
    samo over 11 years
    Also with the handler it doesn't work. I guess it's because getSupportFragmentManager() returns the old, but invalid reference. Please see above for details.
  • samo
    samo over 11 years
    How do you keep the reference up-to-date? Do you use additional attach/detach methods to update the reference?
  • Oleg Vaskevich
    Oleg Vaskevich over 11 years
    Consider this code: private static WeakReference<FragmentActivity> mActivity = null;
  • Oleg Vaskevich
    Oleg Vaskevich over 11 years
    In a nutshell WeakReference prevents you from leaking the activity... you need to call mActivity.get() to actually get the instance, and it will be null if the activity was destroyed. To update it, you will need to write mActivity = new WeakReference<FragmentActivity>(this); - a good place is in onCreate() - which will update the reference.
  • Alex Lockwood
    Alex Lockwood over 10 years
    For those of you who are still searching for a solution... see this blog post about this topic for more information.
  • albertosh
    albertosh over 10 years
    Excelent Blog Post @AlexLockwood! That fixed my problem while educating me :). Thanks!
  • Jimmy Ilenloa
    Jimmy Ilenloa about 10 years
    the weak reference idea is indeed a very smart one, this would allow the object be easily garbage collected when necessary. thumbs up samo!
  • Harsh
    Harsh almost 9 years
    Thanks man, you are a hero for me... nothing worked only your answer. keep up the good work
  • wendigo
    wendigo over 7 years
    Thanks. This works for me, but I know that isn't the best solution.
  • vm345
    vm345 about 7 years
  • Bharath
    Bharath almost 7 years
    Why static is used here ? What if I use MyFragmentActivity mActivity = this ? With out static & WeakReference
  • Juan Mendez
    Juan Mendez over 6 years
    removing super method, also disables saving your fragment states.
  • Deepak Ganachari
    Deepak Ganachari about 6 years
    Thanks a lot.it was generating a exception, this solution worked well..
  • Wijay Sharma
    Wijay Sharma almost 6 years
    Great. It solved my problem. But could anyone please explain how?
  • breakline
    breakline almost 6 years
    Static reference is pretty bad engineering, you should rather tie your asynchtask to the lifecycle and cancel when its necessary
  • Irshad Kumail
    Irshad Kumail almost 6 years
    @WijaySharma I suggest you to read this to understand Activity states better - androidclarified.wordpress.com/2018/06/13/…
  • Rohit Nishad
    Rohit Nishad over 3 years
    i am unable to find onSaveInstanceState method. where is this? in my fragment? what is the super class of it.
  • rtsketo
    rtsketo almost 3 years
    I did something similar, but I used lifecycle and execute the transaction only if it's at least resumed. In emulator works fine, but on a real device it crashes. Why did you use lifecycle in your example?
  • Farid
    Farid over 2 years
    A weak reference is still a dumb idea. The weak reference naming misleads a lot of people. Just to be clear; if there is a reference to a weak reference object your view will still leak even if the view is destroyed
  • Farid
    Farid over 2 years
    @IrshadKumail This has nothing to do with activity lifecycles. This can happen when you try to pop a fragment when there is another fragment added to the same fragment manager that hosts the fragment you want to pop.