2012-07-12 46 views
7

如果我嘗試切換onNewIntent方法中的導航選項卡,My FragmentActivity(singleTop)給我IllegalStateException。開關選項卡onNewIntent導致IllegalStateException

更具體地說,我的應用程序使用SherlockActionBar有三個選項卡,一個選項卡在接收到推送通知(和意圖被調用)時更新,如果應用程序暫停在另一個選項卡上,當我收到意圖時onNewIntent)我用bar.setSelectedNavigationItem()將選項卡(以及片段)更改爲第三個選項卡,這導致了我的問題。如果應用在第三個標籤上暫停,則不會發生異常。

代碼:

@Override 
    public void onNewIntent(Intent intent) { 
     super.onNewIntent(intent); 
     Bundle bundle = intent.getExtras(); 
     if (bundle != null) { 
      bar.setSelectedNavigationItem(Utils.ORDER_STATUS_TAB_ID); 
     } else { 
     } 
    } 

推送通知意圖:

Intent notificationIntent = new Intent(context, 
      MainActivity.class); 
    notificationIntent.putExtra("orderUpdate", 
      new Gson().toJson(orderUpdate)); 
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 
      | Intent.FLAG_ACTIVITY_SINGLE_TOP); 
    PendingIntent contentIntent = PendingIntent.getActivity(context, 0, 
      notificationIntent, 0); 

    notification.contentIntent = contentIntent; 

的TabListener方法(具有在堆棧跟蹤在管線56中的評論)

@Override 
    public void onTabSelected(Tab tab, FragmentTransaction ft) { 
     ft = activity.getSupportFragmentManager().beginTransaction(); 
     ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); 
     if (mFragment == null) { 
      mFragment = Fragment 
        .instantiate(activity, mClass.getName(), mArgs); 
      ft.add(android.R.id.content, mFragment, tag); 
      ft.commit(); 
     } else { 
      ft.attach(mFragment); 
      ft.commit(); // line 56 
     } 

的詳細的異常:

07-12 20:06:40.959: E/AndroidRuntime(8639): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 
07-12 20:06:40.959: E/AndroidRuntime(8639):  at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299) 
07-12 20:06:40.959: E/AndroidRuntime(8639):  at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310) 
07-12 20:06:40.959: E/AndroidRuntime(8639):  at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541) 
07-12 20:06:40.959: E/AndroidRuntime(8639):  at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525) 
07-12 20:06:40.959: E/AndroidRuntime(8639):  at com.wizche.ui.MyTabListener.onTabSelected(MyTabListener.java:56) 
07-12 20:06:40.959: E/AndroidRuntime(8639):  at com.actionbarsherlock.internal.app.ActionBarImpl.selectTab(ActionBarImpl.java:526) 
07-12 20:06:40.959: E/AndroidRuntime(8639):  at com.actionbarsherlock.internal.app.ActionBarImpl.setSelectedNavigationItem(ActionBarImpl.java:317) 
07-12 20:06:40.959: E/AndroidRuntime(8639):  at com.wizche.MainActivity.onNewIntent(MainActivity.java:205) 

回答

10

我發現了一個這樣的修復,不管怎樣都很醜。我只是切換選項卡中的onResume而不是onNewIntent:

@Override 
    public void onResume() { 
     super.onResume(); 
     if(switchToTab){ 
      bar.setSelectedNavigationItem(Utils.ORDER_STATUS_TAB_ID); 
      switchToTab = false; 
     } 
    } 

而在onNewIntent()我剛纔設置的switchToTab =真。我希望有人會有更好的解決方案。

+1

我有同樣的問題。我試圖嚴格地破解ActionBar.TabListener實現,添加一個ft.commitAllowingStateLoss(),但它自己的Sharlock也會調用ft.commit(),它不能被提交兩次。我也嘗試了http://stackoverflow.com/a/10261438/245345上的答案,但它無濟於事。最後我找到了你的解決方案,效果很好。謝謝。 – 2013-04-30 12:11:39

0

我想你不應該在onTabSelected方法中調用commit。它已經由框架完成了。

哦,並使用您收到的交易,不要創建一個新的。

public void onTabSelected(Tab tab, FragmentTransaction ft) { 
    //remove the first line 
    //ft = activity.getSupportFragmentManager().beginTransaction(); 
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); 
    if (mFragment == null) { 
     mFragment = Fragment 
       .instantiate(activity, mClass.getName(), mArgs); 
     ft.add(android.R.id.content, mFragment, tag); 
     //not sure about this one 
     ft.commit(); 
    } else { 
     ft.attach(mFragment); 
     //not sure about this one neither 
     ft.commit(); // line 56 
    } 
+0

TabListener是來自Google示例的令牌,所以我認爲是正確的。您使用我收到的交易的含義是什麼? – Wizche 2012-07-12 18:50:28

+0

感謝您的更新,getSupportFragmentManager()應該在那裏支持多平臺(我使用支持庫),如果我刪除提交/ beginTransaction它在正常情況下工作,但仍然給我恢復後切換選項卡上的同一個異常。我想我無法從onNewIntent方法執行此操作,因爲FragmentManager還沒有準備好。 – Wizche 2012-07-13 14:10:20