123

我正在爲我的應用程序使用支持庫。在我的FragmentActivity中,我使用AsyncTask從互聯網下載數據。在onPreExecute()方法中,我添加一個片段,並在onPostExecute()方法中再次移除它。當方向改變時,我得到了上述例外。請看看細節:java.lang.IllegalStateException:onSaveInstanceState後無法執行此操作

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

使用commitAllowingStateLoss()我得到以下異常:

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

在下一步中,我使用處理程序添加和刪除DummyFragment。另外我添加了一些更多的調試輸出。

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。但爲什麼?

+0

我曾經遇到過這個問題,並通過用commit替換commit來解決它:commitAllowingStateLoss(),你可以試試這個嗎? – Cata

+0

我已經試過這個,但沒有成功。根據LogCat,碎片應該處於正確的狀態。 – samo

+0

您可以發佈您的活動代碼嗎? –

回答

90

你應該做的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(); 
      } 
     }); 
} 
+11

它沒有幫助。行爲和以前一樣。 – samo

+0

@samo請問你能解決這個問題嗎?我有一個非常類似的情況[鏈接](http://stackoverflow.com/questions/14182432/on-rotation-i-get-unable-to-destroy-activity-can-not-perform-this-action-af) –

+0

不,我仍然在尋找解決方案 – samo

2

的原因的例外是AsyncTask的運行時間和訪問到以前期間FragmentActivity的再創造,破壞FragmentActivity之後在onPostExecute()

問題是要獲得新的FragmentActivity的有效參考。對於這個既不是getActivity()也不是findById()或類似的東西。本論壇充滿了根據這個問題的線索(例如搜索"Activity context in onPostExecute")。其中一些正在描述解決方法(直到現在我沒有找到一個好的)。

也許這將是一個更好的解決方案,使用服務爲我的目的。

52

謝謝Oleg Vaskevich。使用FragmentActivityWeakReference解決了這個問題。我的代碼看起來如下:

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

非常有用的感謝分享你的解決方案 – ch3rryc0ke

+0

這個弱點的參考思想確實是非常聰明的一個,這樣可以讓對象在必要時很容易被垃圾收集。豎起大拇指薩莫! –

+0

爲什麼在這裏使用靜態?如果我使用 'MyFragmentActivity mActivity = this?'With out static&WeakReference – Bharath

1

它的價值;我在後臺運行服務的應用程序出現此錯誤。在他們中的一個上,必須向用戶顯示超時對話框。該對話框是導致此錯誤的問題,如果應用程序不再在前臺運行。

在我們的例子中,當應用程序處於後臺時,對話框沒有用,所以我們只保留跟蹤(布爾標記onPause en onResume),然後僅在用戶可見時才顯示對話框。

33

我相信這個問題的正確答案是以下方法。

public abstract int commitAllowingStateLoss() 

贊提交(),但允許提交要執行的活動的 狀態保存後。這很危險,因爲如果 該活動需要稍後從其狀態恢復,則該提交可能會丟失,所以這個應該只用於UI狀態在用戶意外改變 的情況。

以上描述涉及這種方法。

protected void onSaveInstanceState(android.os.Bundle outState) 

這個問題正是當設備進入睡眠狀態時。

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

2

這事對我來說,因爲我是從調用小碎片commit()這是泄漏的活動。它保持活動作爲一個屬性和旋轉活動變量沒有更新onAttach();所以我試圖通過保留(setRetainInstance(true);)片段來提交殭屍活動上的交易。

4

我有一個類似的問題,我通過將onResume()中的一些片段事務代碼移動到onStart()來解決。

更確切地說:我的應用程序是一個啓動器。按下Android主頁按鈕後,用戶可以選擇一個啓動器,直到他/她的決定被記住。當此時「回退」(例如通過輕敲灰色區域),應用程序崩潰。

也許這有助於某人。

22

短而有效的解決方案:

按照簡單的步驟:

步驟1:覆蓋在各分段onSaveInstanceState狀態。並從中刪除超級方法。

@Override 
public void onSaveInstanceState(Bundle outState) { 
} 

步驟2:使用CommitAllowingStateLoss();代替commit();而片段操作。

fragmentTransaction.commitAllowingStateLoss(); 
+1

謝謝。這適用於我,但我知道這不是最好的解決方案。 – wendigo

+1

刪除超級方法,也禁用保存你的片段狀態。 –

+1

非常感謝。它正在生成一個異常,此解決方案運行良好.. – Deepak

10

檢查顯示片段前是否有活動isFinishing()

例子:

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

我的應用程序有3秒的片段來裝載,但是當拳頭屏幕正準備表演,我按Home鍵,恢復運行它,它表現出了同樣的錯誤,所以編輯我的代碼,它跑得非常順利:

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

注:添加commitAllowingStateLoss(),而不是提交()

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

從支持庫版本24.0.0開始之前刪除您的片段,你可以調用FragmentTransaction.commitNow()方法,提交本次交易同步,而不是打電話commit()其次executePendingTransactions()

1

這個問題發生在一個進程ess試圖操縱已調用onStop()的活動。它不一定與片段事務綁定,但也可以使用onBackPressed()等其他方法。

除了AsyncTask之外,這種問題的另一個來源是總線模式訂閱的錯位。通常事件總線或RxBus的訂閱在Activity的onCreate中註冊並在onDestroy中註銷。如果一個新的Activity啓動併發佈一個事件被前一個Activity的攔截,那麼它可能會產生這個錯誤。如果發生這種情況,則一種解決方案是將訂閱註冊和註銷註冊到onStart()onStop()

0

對於這個問題,有一種替代解決方案(不是最好的解決方案),但有效。使用標誌,你可以處理它,就像下面

/** 
* 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(); 
    } 
} 
相關問題