2012-07-12 20 views
7

My FragmentActivity (singleTop) mi dà IllegalStateException se provo a cambiare la scheda di navigazione nel metodo onNewIntent.Scheda Switch onNewIntent causa IllegalStateException

In particolare, la mia applicazione utilizza SherlockActionBar con tre schede, una scheda viene aggiornata quando viene ricevuta una notifica push (e viene chiamato l'intento), se l'app è stata sospesa su un'altra scheda, quando ricevo l'intento (nel onNewIntent) Cambio la scheda (e quindi il frammento) nella terza scheda con bar.setSelectedNavigationItem() e questo mi sta causando il problema. Se l'app è stata sospesa nella terza scheda, non si verifica alcuna eccezione.

Codice:

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

L'intento notifica 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; 

Il metodo TabListener (con il commento sulla linea 56 nella 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 
     } 

L'eccezione dettagliata :

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) 

risposta

10

Ho trovato una soluzione per questo, una specie di brutto comunque. Ho appena passare la linguetta nella onResume invece di onNewIntent:

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

E nel onNewIntent() Ho appena impostare lo switchToTab = true. Spero che qualcuno arriverà con una soluzione migliore.

+1

Ho avuto lo stesso problema. Stavo cercando di hackerare l'implementazione ActionBar.TabListener, aggiungendo un ft.commitAllowingStateLoss(), tuttavia Sharlock stesso chiamerà anche ft.commit(), non può essere eseguito due volte. Ho anche provato la risposta su http://stackoverflow.com/a/10261438/245345, ma non sarà di aiuto. Finalmente ho trovato la soluzione, che funziona bene. Grazie. –

0

Penso che non dovresti chiamare il commit nel metodo onTabSelected. È già fatto dal framework.

Oh, e utilizzare la transazione ricevuta, non crearne una nuova.

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

Il TabListener era token dell'esempio di Google, quindi suppongo sia corretto. Cosa intendi per usare la transazione che ricevo? – Wizche

+0

Grazie per l'aggiornamento, il getSupportFragmentManager() dovrebbe essere lì per supportare più piattaforme (io uso la libreria di supporto), se rimuovo il commit/beginTransaction funziona nel caso normale, ma ancora mi danno la stessa eccezione sulla scheda dello switch dopo il curriculum. Suppongo di non poter eseguire questa azione dal metodo onNewIntent perché FragmentManager non è ancora pronto. – Wizche

Problemi correlati