java.lang.IllegalStateException: onSaveInstanceState öğesinden sonra bu eylem gerçekleştirilemiyor


135

Uygulamam için destek kitaplığını kullanıyorum. FragmentActivity'de internetten veri indirmek için bir AsyncTask kullanıyorum. OnPreExecute () yönteminde bir Fragment eklerim ve onPostExecute () yönteminde yeniden kaldırırım. Oryantasyon aralarında değiştirildiğinde, yukarıda belirtilen istisnayı alıyorum. Lütfen ayrıntılara bir göz atın:

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 takip ediyorum:

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)

Benzer sorunlar hakkında diğer iş parçacıkları onResume () yöntemi çağrılmadan önce onPostExecute yöntemi çağrılıyor gibi görünüyor. Ancak onResume () daha önce çağrılmış olsa bile istisna alıyorum.

Birisi neyin yanlış olduğunu biliyor mu?

Etkinlik şöyle görünür:

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

CommitAllowingStateLoss () kullanırken aşağıdaki özel durumu alıyorum:

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)

FindFragmentById () yöntemi boş bir işaretçi döndürdüğü için AsynTask'ı aşağıdaki gibi uyguladığımda aynı IllegalStateExeption'ı alıyorum.

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

Bir sonraki adımda DummyFragment eklemek ve kaldırmak için bir işleyici kullanıyorum. Ayrıca bazı hata ayıklama çıktıları ekledim.

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 takip ediyorum:

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 () öğesinde FriendListFragment, = 0x7f0a0002 kimliğine sahiptir. İşleyicinin içinde DummyFragment id = 0x7f0a0004 ile oluşturulur. OnPostExecute () öğesinde her iki kimlik de boştur. OnPreExecute () içinde MyFragmentActivity adresi 45e38358'dir. ancak onPostExecute () içinde null. Ancak her iki yöntemde de FragmentManager adresi 45e384a8'dir. Sanırım onPostExecute geçersiz bir FragmentManager kullanıyor. Ama neden?


1
Ben bu sorunu bir kez vardı ve bu yerine taahhüt ile düzeltti: commitAllowingStateLoss (), bunu deneyebilir misiniz?
Kata

Bunu zaten denedim, ama başarılı olamadım. LogCat'e göre Parça doğru durumda olmalıdır.
samo

Etkinlik kodunuzu gönderebilir misiniz?
Robert Estivill

CommitAllowingStateLoss () kullandığımda farklı bir istisna alıyorum (yukarıya bakın).
samo

6
Hala çözüm arayanlarınız için ... daha fazla bilgi için bu konuyla ilgili bu blog yayınına bakın .
Alex Lockwood

Yanıtlar:


97

İşlemi Handleraşağıdaki gibi yapmanız gerekir :

@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
Yardımcı olmuyor. Davranış eskisi gibi.
samo

@samo lütfen sorunu çözebildiniz mi? Çok benzer bir durum bağlantım var
Lisa Anne

3
Bu kodu düşünün:private static WeakReference<FragmentActivity> mActivity = null;
Oleg Vaskevich

2
Özetle WeakReference, aktiviteyi sızdırmanızı önler ... mActivity.get()örneği almak için çağırmanız gerekir ve aktivite yok edilirse boş olacaktır. Güncellemek için, referansı güncelleyecek - mActivity = new WeakReference<FragmentActivity>(this);iyi bir yer var - yazmanız gerekir onCreate().
Oleg Vaskevich

107
Hala çözüm arayanlarınız için ... daha fazla bilgi için bu konuyla ilgili bu blog yayınına bakın .
Alex Lockwood

55

Teşekkürler Oleg Vaskevich. Bir Kullanarak WeakReferencebir FragmentActivitysorunu çözdü. Kodum şu anda aşağıdaki gibi görünüyor:

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

zayıf referans fikri gerçekten çok akıllı bir fikirdir, bu, gerektiğinde nesnenin kolayca çöp toplanmasına izin verir. samo Yaşasın!
Jimmy Ilenloa

Burada neden statik kullanılır? Ne kullanırsanız MyFragmentActivity mActivity = this ?ile dışarı statik ve WeakReference
Bharath

Statik referans oldukça kötü bir mühendisliktir, zaman uyumsuzluğunuzu yaşam döngüsüne
bağlamalı

38

Bu sorunun doğru cevabının aşağıdaki yöntem olduğuna inanıyorum.

public abstract int commitAllowingStateLoss ()

Commit () gibi ancak bir etkinliğin durumu kaydedildikten sonra taahhüdün yürütülmesine izin verir. Bu tehlikelidir, çünkü aktivitenin daha sonra durumundan geri yüklenmesi gerektiğinde taahhüt kaybedilebilir, bu nedenle bu sadece kullanıcı arayüzünün kullanıcı üzerinde beklenmedik bir şekilde değişmesinin uygun olduğu durumlarda kullanılmalıdır.

Yukarıdaki açıklama bu yöntemle ilgilidir.

protected void onSaveInstanceState(android.os.Bundle outState)

Bu sorun, aygıt uyku moduna geçtiğinde oluşur.

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


25

Kısa Ve Çalışma Çözümü:

Basit Adımları İzleyin:

Adım 1 : İlgili parçadaki onSaveInstanceStatedurumu geçersiz kılın . Ve süper yöntemi ondan kaldırın.

@Override
public void onSaveInstanceState(Bundle outState) {
}

Adım 2 : fragment işlemleri CommitAllowingStateLoss();yerine kullanın commit();.

fragmentTransaction.commitAllowingStateLoss();

2
Teşekkürler. Bu benim için işe yarıyor, ama bunun en iyi çözüm olmadığını biliyorum.
wendigo

2
süper yöntem kaldırıldığında, parça durumlarınızı kaydetmeyi de devre dışı bırakır.
Juan Mendez

1
Çok teşekkürler. Bir istisna üretiyordu, bu çözüm iyi çalıştı ..
Deepak

11

isFinishing()Parçayı göstermeden önce aktivitenin olup olmadığını kontrol edin .

Misal:

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

5

Bazı parça işlem kodunu onResume()içine taşıyarak giderdim benzer bir sorun vardı onStart().

Daha kesin olmak gerekirse: Uygulamam bir başlatıcı. Android Ana Ekran düğmesine bastıktan sonra kullanıcı, kararı hatırlanana kadar bir başlatıcı seçebilir. Bu noktada "geri" giderken (örneğin grimsi alana dokunarak) uygulama çöktü.

Belki bu birine yardım eder.


4

Yerine commitAllowingStateLoss()kullanın commit().

kullandığınızda commit(), durum kaybı meydana gelirse bir istisna fırlatabilir ancak commitAllowingStateLoss()durum kaybı olmadan işlemi kaydeder, böylece durum kaybı meydana gelirse istisna atmaz.


2

Bu benim için oldu, çünkü commit()aktiviteyi sızdıran alt parçadan çağırıyordum . Bir özellik olarak aktivite tuttu ve bir rotasyon aktivite değişkeni tarafından güncellenmedi onAttach();Bu yüzden tutulan (setRetainInstance(true);)parça tarafından zombi Aktivite üzerinde işlem yapmaya çalışıyordu .


2

İstisna nedeni yeniden yaratılmasıdır FragmentActivityçalışma zamanı sırasında AsyncTasktahrip ve önceki erişimde, FragmentActivityiçinde onPostExecute()sonradan.

Sorun, yeniye geçerli bir referans almaktır FragmentActivity. Bunun için ne bir yöntem ne getActivity()de findById()buna benzer bir yöntem yoktur . Bu forum, bu konuya göre dizelerle doludur (örneğin ara "Activity context in onPostExecute"). Bazıları geçici çözümleri anlatıyor (şimdiye kadar iyi bir tane bulamadım).

Belki de Hizmet'i benim amacım için kullanmak daha iyi bir çözüm olabilir.


2

Bu sorun için bir alternatif çözüm (en iyi çözüm DEĞİL) vardır, ancak çalışır. Bayrağı kullanarak aşağıdaki gibi işleyebilirsiniz

/**
 * 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;
    .....
}

Ve booleanparça işlemi yaparken bu değeri kontrol edebilirsiniz .

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

1

Değeri için; Arka planda hizmetleri çalıştıran bir uygulamada bu hatayı aldım. Bunlardan birinde kullanıcıya zaman aşımı iletişim kutusunun gösterilmesi gerekiyordu. Bu iletişim kutusu, uygulama artık ön planda çalışmıyorsa bu hataya neden olan sorundu.

Bizim durumumuzda, uygulama arka planda olduğunda iletişim kutusunun kullanışlı olmadığını gösterdik, bu yüzden bunu izledik (boolean işaretli onPause en onResume) ve ardından yalnızca uygulama gerçekten kullanıcı tarafından görülebildiğinde iletişim kutusunu gösteririz.


1

1.Çözüm: İçindeki onSaveInstanceState()süper çağrıyı geçersiz kılın ve kaldırın.

@Override
public void onSaveInstanceState(Bundle outState) {
}

2.Çözüm:onSaveInstanceState() Süper aramadan önce parçanızı geçersiz kılın ve kaldırın

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

1

Bu sorun, bir işlem onStop()çağrılan bir etkinliği değiştirmeye çalıştığında oluşur . Parça işlemine değil, aynı zamanda onBackPressed () gibi diğer yöntemlere de bağlı olması gerekir.

AsyncTask'a ek olarak, bu tür bir sorunun kaynağı, veri yolu deseninin aboneliğinin yanlış yerleştirilmesidir. Genellikle Event Bus veya RxBus aboneliği, Activity'nin onCreate sırasında kaydedilir ve onDestroy'da kaydı silinir. Yeni bir Etkinlik başlar ve önceki Etkinlikten aboneler tarafından kesilen bir etkinlik yayınlarsa, bu hataya neden olabilir. Bu daha sonra olursa bir çözüm abonelik kaydı ve de-kayıt taşımaktır onStart()ve onStop().


1

Bu sorunumu çözdü: Kotlin Kodu:

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

Nasıl olduğunu commitAllowingStateLoss()farklıdır commit()?

Belgelere göre:

Beğen commit()ancak bir etkinliğin durumu kaydedildikten sonra taahhüdün yürütülmesine izin verir. https://developer.android.com/reference/android/app/FragmentTransaction#commitAllowingStateLoss ()

Not: Bu yöntemle Parça İletişim Kutularını gösterebilir veya parça yükleyebilirsiniz. Her ikisi için de geçerlidir.


0

Uygulamamın 3 saniyede yüklenecek bir parçası var, ancak yumruk ekranı göstermeye hazırlanırken, ana sayfa düğmesine basıyorum ve çalıştırmaya devam ediyorum, aynı hatayı gösteriyor, bu yüzden kodumu düzenliyor ve çok düzgün çalıştı:

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

NOT: commit () yerine commitAllowingStateLoss () öğesini ekleyin


0

Destek kitaplığı sürüm 24.0.0'dan başlayarak, FragmentTransaction.commitNow()bu işlemi çağırmak yerine eşzamanlı olarak gerçekleştiren yöntemi çağırabilirsiniz commit().executePendingTransactions()


0

Etkinlik durumunu kaybettikten sonra herhangi bir parça işlemi yaparsanız IllegalStateException ile karşılaşılır - Etkinlik ön planda değildir. Bu, AsyncTask'ta herhangi bir parçayı yürütmeye çalıştığınızda veya bir ağ isteğinden sonra genellikle karşılaşılır.

Bu çökmeyi önlemek için, etkinlik durumu geri yükleninceye kadar herhangi bir parça işlemini geciktirmeniz yeterlidir. Aşağıdaki nasıl yapılır

İki özel boole değişkeni bildirin

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;

Şimdi onPostResume () ve onPause'da boole değişkenimizi isTransactionSafe olarak ayarladık ve ayarını kaldırdık. Fikir, eylemi yalnızca etkinlik ön planda olduğunda güvenli bir şekilde işaretlemektir, bu nedenle durum kaybı olasılığı yoktur.

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

Şimdiye kadar yaptığımız şey IllegalStateException uygulamasından kurtaracak, ancak faaliyet arka plana taşındıktan sonra yapıldıysa işlemlerimiz kaybolacaktır, örneğin, commandAllowStateloss () gibi. Buna yardımcı olmak için isTransactionPending boolean değişkenimiz var

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

Bu makalede , bu özel durumun neden karşılaşıldığı ayrıntılı olarak açıklanmaktadır ve bu sorunu gidermek için çeşitli yöntemler karşılaştırılmaktadır. Şiddetle tavsiye edilir


0

Aynı istisnayı yaşadım ve burada bu yığın akışı tartışmasında bulduğum birçok snippet'i denedim, ancak hiçbir snippet benim için çalışmadı.

Ancak tüm sorunları çözebildim, çözümleri sizinle paylaşacağım:

  • İlk bölümde: Bir Faaliyette DialogFragment göstermeye çalıştım ama başka bir java sınıfından. Daha sonra bu örneğin özniteliğini kontrol ederek, eski bir Aktivite örneği olduğunu, şu anda çalışan Aktivite olmadığını buldum. [Daha doğrusu socket.io kullanıyordum ve bir socket.off ("örnek", örnek) yapmayı unuttum ... böylece etkinliğin eski bir örneğine eklenmişti. ]

  • İkinci bölümde: Bir etkinlikte bir DialogFragment'ı bir niyetle geri döndüğümde göstermeye çalışıyordum, ancak günlüklerimi kontrol ettiğimde, parçayı göstermeye çalıştığında etkinliğin hala onStart yönteminde olmadığını gördüm. , bu yüzden uygulamada çöktü çünkü üzerinde parçayı göstermek için Activity sınıfını bulamadı.

Bazı ipuçları: etkinliğinizin parçanızı göstermeye çalıştığınız eski bir örneğini kullanmıyorsanız veya bazı parçanızı göstermeden önce etkinlik yaşam döngünüzü kontrol edin ve göstermeden önce onStart veya onResume'te olduğunuzdan emin olun. .

Umarım bu açıklamalar size yardımcı olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.