2012-07-12 19 views
7

Moja funkcja FragmentActivity (singleTop) zapewnia wyjątek IllegalStateException, jeśli spróbuję zmienić kartę nawigacji w metodzie onNewIntent.Przełącznik na karcie Nowa przyczyna Przyczyna IllegalStateException

Mówiąc dokładniej, moja aplikacja używa SherlockActionBar z trzema zakładkami, jedna karta jest aktualizowana po otrzymaniu powiadomienia Push (i nazywa się zamiar), jeśli aplikacja została zawieszona na innej karcie, gdy otrzymam intencję (w onNewIntent) Zmieniam zakładkę (a zatem fragment) na trzecią zakładkę za pomocą bar.setSelectedNavigationItem() i to powoduje problem. Jeśli aplikacja została zawieszona na trzeciej karcie, nie ma wyjątku.

Kod:

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

Intencją powiadomienia Push:

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; 

Sposób TabListener (z komentarzem na linii 56 w stacktrace)

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

Szczegółowy wyjątków :

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) 

Odpowiedz

10

Znalazłem poprawkę na to, coś brzydkiego tak. Ja po prostu przełączyć kartę w onResume zamiast onNewIntent:

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

A w onNewIntent() po prostu ustawić switchToTab = true. Mam nadzieję, że ktoś przyjdzie z lepszym rozwiązaniem.

+1

Miałem ten sam problem. Próbowałem ciężko włamać się do implementacji ActionBar.TabListener, dodając ft.commitAllowingStateLoss(), jednak samo Sharlock będzie również wywoływać ft.commit(), nie może być zatwierdzone dwa razy. Próbowałem również odpowiedzi na http://stackoverflow.com/a/10261438/245345, ale to nie pomoże. W końcu znalazłem twoje rozwiązanie, które działa dobrze. Dzięki. –

0

Myślę, że nie powinieneś wywoływać zatwierdzenia w metodzie onTabSelected. Robi to już framework.

Och, i wykorzystaj otrzymaną transakcję, nie twórz nowej.

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 był tokenem z przykładu Google, więc przypuszczam, że jest poprawny. Co chcesz użyć transakcji, którą otrzymuję? – Wizche

+0

Dzięki za aktualizację, getSupportFragmentManager() powinien być tam, aby obsługiwać wiele platform (korzystam z biblioteki pomocniczej), jeśli usunę commit/beginTransaction, to działa on normalnie, ale nadal daje mi ten sam wyjątek na karcie przełącznika po wznowieniu. Zakładam, że nie mogę wykonać tej akcji z metody onNewIntent, ponieważ FragmentManager nie jest jeszcze gotowy. – Wizche

Powiązane problemy