java.lang.IllegalStateException: onSaveInstanceState के बाद यह क्रिया नहीं कर सकता


135

मैं अपने ऐप के लिए सपोर्ट लाइब्रेरी का उपयोग कर रहा हूं। अपने FragmentActivity में मैं इंटरनेट से डेटा डाउनलोड करने के लिए एक AsyncTask का उपयोग कर रहा हूं। OnPreExecute () विधि में मैं एक फ़्रैगमेंट जोड़ता हूं और onPostExecute () विधि में फिर से निकालता हूं। जब बीच में अभिविन्यास बदल जाता है, तो मुझे उपर्युक्त अपवाद मिलता है। कृपया विवरण देखें:

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");
    ...
}

मैं निम्नलिखित 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)

इसी तरह की समस्याओं के बारे में अन्य थ्रेड्स में कारण लगता है कि onPostExecute विधि को onResume () विधि कहा जाता है। लेकिन मुझे अपवाद मिलता है फिर भी onResume () को पहले कहा जाता है।

क्या किसी को पता है कि क्या गलत है?

गतिविधि इस तरह दिखती है:

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);
    }
}

जब प्रतिबद्धता का उपयोग कर रहा हूँ। StateLoss () मैं निम्नलिखित अपवाद मिलता है:

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)

जब मैं इस प्रकार AsynTask को लागू करता हूं तो मुझे एक ही IllegalStateExeption मिलता है, क्योंकि findFragmentById () विधि एक अशक्त सूचक देता है।

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();
    }

अगले चरण में मैं डमीफ्रेगमेंट को जोड़ने और हटाने के लिए एक हैंडलर का उपयोग करता हूं। इसके अतिरिक्त मैंने कुछ और डीबग आउटपुट जोड़े हैं।

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();
            }
        });

मैं निम्नलिखित 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)

OnPreExecute () में FriendListFragment में id = 0x7f0a0002 है। हैंडलर के अंदर DummyFragment id = 0x7f0a0004 के साथ बनाया गया है। OnPostExecute () में दोनों ID शून्य हैं। OnPreExecute () में MyFragmentActivity का पता 45e38358 है। लेकिन onPostExecute () में यह अशक्त है। लेकिन दोनों विधियों में FragmentManager पता 45e384a8 है। मुझे लगता है कि onPostExecute एक अमान्य FragmentManager का उपयोग करता है। पर क्यों?


1
मैंने एक बार इस मुद्दे को रखा था और इसे इस के साथ प्रतिबद्ध को बदलकर तय किया था: कमेटिंगस्टेटलॉस (), क्या आप यह कोशिश कर सकते हैं?
काटा

मैंने पहले ही यह कोशिश की है, लेकिन सफलता के बिना। लॉजकैट के अनुसार फ्रैगमेंट सही अवस्था में होना चाहिए।
samo

क्या आप कृपया अपना गतिविधि कोड पोस्ट कर सकते हैं?
रॉबर्ट एस्टिविल

जब मैं कमेटिंग का उपयोग करता हूं। StateLateLoss () मुझे एक अलग अपवाद मिलता है (ऊपर देखें)।
समो

6
आप में से जो अभी भी एक समाधान के लिए खोज रहे हैं ... अधिक जानकारी के लिए इस विषय के बारे में इस ब्लॉग पोस्ट को देखें।
एलेक्स लॉकवुड

जवाबों:


97

आपको लेनदेन Handlerइस प्रकार करना चाहिए :

@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();
            }
        });
}

12
यह मदद नहीं करता है। व्यवहार पहले की तरह ही है।
समो

@samo कृपया आप इस मुद्दे को हल करने में सक्षम हैं? मेरे पास एक समान स्थिति लिंक है
लिसा ऐनी

3
इस कोड पर विचार करें:private static WeakReference<FragmentActivity> mActivity = null;
ओलेग वास्केविच

2
संक्षेप में WeakReferenceआपको गतिविधि को लीक करने से रोकता है ... आपको mActivity.get()वास्तव में उदाहरण प्राप्त करने के लिए कॉल करने की आवश्यकता है , और यह शून्य हो जाएगा यदि गतिविधि नष्ट हो गई थी। इसे अपडेट करने के लिए, आपको लिखना होगा mActivity = new WeakReference<FragmentActivity>(this);- एक अच्छी जगह है onCreate()- जो संदर्भ को अपडेट करेगा।
ओलेग वास्केविच

107
आप में से जो अभी भी एक समाधान के लिए खोज रहे हैं ... अधिक जानकारी के लिए इस विषय के बारे में इस ब्लॉग पोस्ट को देखें।
एलेक्स लॉकवुड

55

धन्यवाद ओलेग वासकेविच। एक का प्रयोग WeakReferenceकी FragmentActivityसमस्या हल हो। मेरा कोड इस प्रकार है:

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();
            }
        }

कमजोर संदर्भ विचार वास्तव में एक बहुत ही स्मार्ट है, यह आवश्यक होने पर ऑब्जेक्ट को आसानी से कचरा एकत्र करने की अनुमति देगा। समाओ को अंगूठा!
जिमी इलेनॉला

यहाँ स्थैतिक का उपयोग क्यों किया जाता है? क्या होगा यदि मैं का उपयोग MyFragmentActivity mActivity = this ?के साथ बाहर स्थिर और WeakReference
भरत

स्टेटिक संदर्भ बहुत बुरा इंजीनियरिंग, आप बल्कि जीवन चक्र करने के लिए अपने asynchtask टाई और रद्द कर देना चाहिए है जब इसकी आवश्यक
breakline

38

मेरा मानना ​​है कि इस प्रश्न का सही उत्तर निम्न विधि है।

public abstract int commitAllowingStateLoss ()

जैसा कि प्रतिबद्ध () है, लेकिन किसी गतिविधि की स्थिति को सहेजने के बाद प्रतिबद्ध को निष्पादित करने की अनुमति देता है। यह खतरनाक है क्योंकि कमिट खो सकता है यदि गतिविधि को बाद में अपने राज्य से पुनर्स्थापित करने की आवश्यकता होती है, इसलिए इसका उपयोग केवल उन मामलों के लिए किया जाना चाहिए जहां उपयोगकर्ता पर अप्रत्याशित रूप से बदलने के लिए UI स्थिति के लिए ठीक है।

उपर्युक्त विवरण इस पद्धति से संबंधित है।

protected void onSaveInstanceState(android.os.Bundle outState)

यह समस्या ठीक तब होती है जब डिवाइस सो जाता है।

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


25

लघु और काम कर समाधान:

सरल चरणों का पालन करें:

चरण 1 : onSaveInstanceStateसंबंधित खंड में ओवरराइड स्थिति। और इससे सुपर मेथड को हटा दें।

@Override
public void onSaveInstanceState(Bundle outState) {
}

चरण 2 : खंड संचालन CommitAllowingStateLoss();के commit();दौरान उपयोग करें ।

fragmentTransaction.commitAllowingStateLoss();

2
धन्यवाद। यह मेरे लिए काम करता है, लेकिन मुझे पता है कि सबसे अच्छा समाधान नहीं है।
वेंडीगो

2
सुपर मेथड को हटाकर, आपके टुकड़े करने वाले राज्यों को बचाने में भी अक्षम करता है।
जुआन मेंडेज़

1
बहुत बहुत धन्यवाद। यह एक अपवाद पैदा कर रहा था, इस समाधान ने अच्छी तरह से काम किया ..
दीपक

11

isFinishing()टुकड़ा दिखाने से पहले गतिविधि की जाँच करें ।

उदाहरण:

if(!isFinishing()) {
FragmentManager fm = getSupportFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            DummyFragment dummyFragment = DummyFragment.newInstance();
            ft.add(R.id.dummy_fragment_layout, dummyFragment);
            ft.commitAllowingStateLoss();
}

5

मुझे इसी तरह की समस्या थी, जिसे मैंने कुछ खंड लेनदेन कोड से स्थानांतरित करके तय किया onResume()था onStart()

अधिक सटीक होना: मेरा ऐप एक लॉन्चर है। एंड्रॉइड होम बटन दबाने के बाद, उपयोगकर्ता एक लांचर चुन सकता है जब तक कि उसका निर्णय याद नहीं किया जाता है। जब इस बिंदु पर "वापस" जा रहा है (उदाहरण के लिए ग्रेश क्षेत्र में टैप करके) तो ऐप क्रैश हो गया।

शायद यह किसी की मदद करे।


4

के commitAllowingStateLoss()बजाय का उपयोग करें commit()

जब आप उपयोग करते हैं तो commit()यह एक अपवाद फेंक सकता है यदि राज्य का नुकसान होता है लेकिन commitAllowingStateLoss()राज्य के नुकसान के बिना लेनदेन को बचाता है ताकि राज्य का नुकसान होने पर अपवाद न फेंके।


2

यह मेरे लिए हुआ, क्योंकि मैं commit()सबफ्रैगमेंट से आह्वान कर रहा था जो गतिविधि लीक कर रहा था। यह एक संपत्ति के रूप में गतिविधि रखता था और रोटेशन गतिविधि चर पर अपडेट नहीं किया गया onAttach();था इसलिए मैं (setRetainInstance(true);)खंडित बनाए रखा द्वारा ज़ोंबी गतिविधि पर लेनदेन करने की कोशिश कर रहा था ।


2

अपवाद का कारण FragmentActivity, रनटाइम के दौरान AsyncTaskऔर पिछले तक पहुंच के दौरान फिर से निर्माण है , बाद FragmentActivityमें नष्ट कर दिया onPostExecute()गया।

समस्या नए के लिए एक वैध संदर्भ प्राप्त करना है FragmentActivity। इसके लिए न तो कोई विधि है getActivity()और न ही findById()कुछ समान है। यह फोरम इस मुद्दे (उदाहरण के लिए खोज "Activity context in onPostExecute") के अनुसार थ्रेड्स से भरा है । उनमें से कुछ वर्कअराउंड का वर्णन कर रहे हैं (अब तक मुझे एक अच्छा नहीं मिला)।

शायद यह मेरे उद्देश्य के लिए एक सेवा का उपयोग करने के लिए एक बेहतर समाधान होगा।


2

इस समस्या के लिए एक वैकल्पिक समाधान (सबसे अच्छा समाधान नहीं) है, लेकिन काम करता है। झंडे का उपयोग करके आप इसे नीचे की तरह संभाल सकते हैं

/**
 * Flag to avoid "java.lang.IllegalStateException: Can not perform this action after
 * onSaveInstanceState". Avoid Fragment transaction until onRestoreInstanceState or onResume
 * gets called.
 */
private boolean isOnSaveInstanceStateCalled = false;


@Override
public void onRestoreInstanceState(final Bundle bundle) {
    .....
    isOnSaveInstanceStateCalled = false;
    .....
}

@Override
public void onSaveInstanceState(final Bundle outState) {
    .....
    isOnSaveInstanceStateCalled = true;
    .....
}

@Override
public void onResume() {
    super.onResume();
    isOnSaveInstanceStateCalled = false;
    .....
}

और आप इस booleanमूल्य की जांच कर सकते हैं टुकड़ा लेनदेन करते समय।

private void fragmentReplace(Fragment fragment, String fragmentTag){
    if (!isOnSaveInstanceStateCalled) {
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.layout_container, fragment, fragmentTag)
                .commit();
    }
}

1

हांलांकि इसकी कीमत के बारे निश्चित नहीं हूँ; मेरे पास एक ऐप पर यह त्रुटि थी जो पृष्ठभूमि में सेवाएं चला रहा था। उनमें से एक पर उपयोगकर्ता को एक टाइमआउट संवाद दिखाया जाना था। यह डायलॉग इस त्रुटि का कारण था यदि ऐप अब अग्रभूमि में नहीं चल रहा था।

हमारे मामले में जब ऐप बैकग्राउंड में था तब डायलॉग दिखाना उपयोगी नहीं था इसलिए हमने बस उस पर नज़र रखी (बूलियन ने ऑनपोन एन ऑन इस्सुम को चिह्नित किया) और उसके बाद ही डायलॉग दिखाते हैं जब ऐप वास्तव में उपयोगकर्ता को दिखाई देता है।


1

समाधान 1:onSaveInstanceState() इसमें सुपर कॉल को ओवरराइड और हटाएं।

@Override
public void onSaveInstanceState(Bundle outState) {
}

समाधान 2:onSaveInstanceState() सुपर कॉल से पहले अपने टुकड़े को ओवरराइड और हटा दें

@Override
public void onSaveInstanceState(Bundle outState) {
     // TODO: Add code to remove fragment here
     super.onSaveInstanceState(outState);
}

1

यह समस्या तब होती है जब कोई प्रक्रिया किसी गतिविधि में हेरफेर करने की कोशिश करती है जिसका onStop() जिसे बुलाया गया है। यह जरूरी नहीं है कि यह खंड के लेन-देन से जुड़ा हो, बल्कि अन्य तरीके जैसे onBackPressed ()।

AsyncTask के अलावा, इस तरह की समस्या का एक अन्य स्रोत बस पैटर्न की सदस्यता का गलत स्थान है। आमतौर पर इवेंट बस या RxBus की सदस्यता गतिविधि के onCreate के दौरान पंजीकृत होती है और onDestroy में डी-पंजीकृत होती है। यदि कोई नई गतिविधि प्रारंभ होती है और पिछली गतिविधि के ग्राहकों द्वारा अवरोधित किसी घटना को प्रकाशित करती है तो यह त्रुटि उत्पन्न कर सकती है। यदि ऐसा होता है, तो एक समाधान सदस्यता पंजीकरण और डी-पंजीकरण को स्थानांतरित करना है onStart()और onStop()


1

इससे मेरी समस्या हल हो गई: कोटलिन कोड:

val fragmentTransaction = activity.supportFragmentManager.beginTransaction()
fragmentTransaction.add(dialogFragment, tag)
fragmentTransaction.commitAllowingStateLoss()

commitAllowingStateLoss()से अलग कैसे है commit()?

प्रलेखन के अनुसार:

जैसे कि commit()लेकिन किसी गतिविधि की स्थिति को बचाने के बाद प्रतिबद्ध को निष्पादित करने की अनुमति देता है। https://developer.android.com/reference/android/app/FragmentTransaction#commitAllowingStateLoss ()

पुनश्च: आप इस विधि द्वारा टुकड़े डायलॉग दिखा सकते हैं या टुकड़े लोड कर सकते हैं। दोनों के लिए लागू।


0

3 सेकंड में लोड करने के लिए मेरे ऐप का एक टुकड़ा है, लेकिन जब मुट्ठी स्क्रीन दिखाने की तैयारी कर रही है, तो मैं होम बटन दबाता हूं और इसे फिर से चलाता हूं, यह एक ही त्रुटि दिखाता है, इसलिए यह मेरे कोड को संपादित करता है और यह बहुत सुचारू रूप से चलता है:

new Handler().post(new Runnable() {
        public void run() {
            if (saveIns == null) {
                mFragment = new Fragment_S1_loading();
                getFragmentManager().beginTransaction()
                        .replace(R.id.container, mFragment).commit();
            }
            getActionBar().hide();
            // Loading screen in 3 secs:
            mCountDownTimerLoading = new CountDownTimer(3000, 1000) {

                @Override
                public void onTick(long millisUntilFinished) {

                }

                @Override
                public void onFinish() {
                    if (saveIns == null) {// TODO bug when start app and press home
                                            // button
                        getFragmentManager()
                                .beginTransaction()
                                .replace(R.id.container,
                                        new Fragment_S2_sesstion1()).commitAllowingStateLoss();
                    }
                    getActionBar().show();
                }
            }.start();
        }
    });

नोट: प्रतिबद्ध के बजाय प्रतिबद्ध जोड़ें


0

समर्थन लाइब्रेरी संस्करण 24.0.0 से शुरू करके आप उस FragmentTransaction.commitNow()पद्धति को कॉल कर सकते हैं जो commit()बाद में कॉल करने के बजाय इस लेनदेन को सिंक्रोनाइज़ करती हैexecutePendingTransactions()


0

यदि आपने अपनी स्थिति खो दी है, तो गतिविधि के बाद कोई भी अवैध लेन-देन करने पर IllegalStateException का सामना होता है- गतिविधि अग्रभूमि में नहीं होती है। यह आमतौर पर तब सामने आता है जब आप AsyncTask में या नेटवर्क अनुरोध के बाद कोई भी टुकड़ा करने की कोशिश करते हैं।

इस दुर्घटना से बचने के लिए आपको बस किसी भी खंड के लेन-देन में देरी करने की आवश्यकता है जब तक कि गतिविधि की स्थिति बहाल न हो जाए। इसका पालन कैसे किया जाता है

दो निजी बूलियन चर घोषित करें

public class MainActivity extends AppCompatActivity {

    //Boolean variable to mark if the transaction is safe
    private boolean isTransactionSafe;

    //Boolean variable to mark if there is any transaction pending
    private boolean isTransactionPending;

अब onPostResume () और onPause में हम अपने बूलियन वेरिएबल isTransactionSafe को सेट और अनसेट करते हैं। आइडिया ट्रैसनेशन को तभी सुरक्षित करना है जब गतिविधि अग्रभूमि में हो ताकि स्टेटेलॉस का कोई मौका न हो।

/*
onPostResume is called only when the activity's state is completely restored. In this we will
set our boolean variable to true. Indicating that transaction is safe now
 */
public void onPostResume(){
    super.onPostResume();
    isTransactionSafe=true;
}
/*
onPause is called just before the activity moves to background and also before onSaveInstanceState. In this
we will mark the transaction as unsafe
 */

public void onPause(){
    super.onPause();
    isTransactionSafe=false;

}

private void commitFragment(){
    if(isTransactionSafe) {
        MyFragment myFragment = new MyFragment();
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.frame, myFragment);
        fragmentTransaction.commit();
    }
}

हमने अब तक जो भी किया है वह इललीगलस्टैटेसेप्शन से बचाएगा, लेकिन हमारे लेनदेन को खो दिया जाएगा यदि वे गतिविधि के पृष्ठभूमि में चले जाने के बाद किए जाते हैं, तो इस तरह के कमिटमेंट। उस के साथ मदद करने के लिए हमारे पास ट्रान्सपेंशनिंग बूलियन चर है

public void onPostResume(){
   super.onPostResume();
   isTransactionSafe=true;
/* Here after the activity is restored we check if there is any transaction pending from
the last restoration
*/
   if (isTransactionPending) {
      commitFragment();
   }
}


private void commitFragment(){

 if(isTransactionSafe) {
     MyFragment myFragment = new MyFragment();
     FragmentManager fragmentManager = getFragmentManager();
     FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
     fragmentTransaction.add(R.id.frame, myFragment);
     fragmentTransaction.commit();
     isTransactionPending=false;
 }else {
     /*
     If any transaction is not done because the activity is in background. We set the
     isTransactionPending variable to true so that we can pick this up when we come back to
foreground
     */
     isTransactionPending=true;
 }
}

यह लेख काफी विस्तार से बताता है कि यह अपवाद क्यों है और इसे हल करने के लिए विभिन्न तरीकों की तुलना करता है। अत्यधिक सिफारिशित


0

मेरे पास एक ही अपवाद था और मैंने कई स्निपेट की कोशिश की, जो मुझे इस स्टैकओवरफ्लो चर्चा पर यहां मिला, लेकिन किसी भी स्निपेट ने मेरे लिए काम नहीं किया।

लेकिन मैं सभी मुद्दों को हल करने में सक्षम था, मैं आपके साथ समाधान साझा करूंगा:

  • पहले भाग में: मैंने एक एक्टिविटी पर डायलॉगफ्रैगमेंट दिखाने की कोशिश की, लेकिन दूसरे जावा क्लास से। फिर उस उदाहरण की विशेषता की जाँच करके, मैंने पाया कि यह गतिविधि का एक पुराना उदाहरण था, यह वर्तमान में चलने वाली गतिविधि नहीं थी। [अधिकतापूर्वक मैं socket.io का उपयोग कर रहा था, और मैं एक सॉकेट करना भूल गया था। ताफ़ ("उदाहरण", उदाहरण) ... तो यह गतिविधि के एक पुराने उदाहरण से जुड़ा हुआ है। ]

  • दूसरे भाग में: जब मैं एक इरादे के साथ वापस आता हूं, तो मैं एक गतिविधि में एक डायलॉगफ्रैगमेंट दिखाने की कोशिश कर रहा था, लेकिन जब मैंने अपने लॉग की जांच की, तो मैंने देखा कि जब यह टुकड़ा दिखाने की कोशिश की गई थी, तब भी गतिविधि ऑनस्टार्ट विधि में नहीं थी , इसलिए इसने एप्लिकेशन को क्रैश कर दिया क्योंकि इस पर टुकड़ा दिखाने के लिए गतिविधि वर्ग नहीं मिला।

कुछ युक्तियां: कुछ विशेषताओं के साथ जांच करें कि क्या आप अपनी गतिविधि के पुराने उदाहरण का उपयोग नहीं कर रहे हैं, जिसके साथ आप अपने टुकड़े को दिखाने की कोशिश कर रहे हैं, या अपना टुकड़ा दिखाने से पहले अपनी गतिविधि के जीवन चक्र की जांच करें और सुनिश्चित करें कि आप onStart या onResume में हैं इससे पहले कि ।

मुझे उम्मीद है कि वे स्पष्टीकरण आपकी मदद करेंगे।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.