2012-07-12 15 views
7

Mi FragmentActivity (singleTop) me está dando IllegalStateException si trato de cambiar la pestaña de navegación en el método onNewIntent.Cambiar la pestaña onNewIntent causa IllegalStateException

Más específicamente, Mi aplicación usa SherlockActionBar con tres pestañas, una pestaña se actualiza cuando se recibe una notificación automática (y se llama a la intención) si la aplicación se suspendió en otra pestaña cuando recibo el intento (en onNewIntent) Cambio la pestaña (y, por lo tanto, el fragmento) a la tercera pestaña con bar.setSelectedNavigationItem() y esto me está causando el problema. Si la aplicación se suspendió en la tercera pestaña, no se produce ninguna excepción.

Código:

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

La intención notificación de inserción:

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; 

El método TabListener (con el comentario en la línea 56 en el 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 
     } 

La excepción detallada :

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) 

Respuesta

10

Encontré una solución para esto, algo feo de todos modos. Yo sólo cambia de ficha en el lugar de onResume onNewIntent:

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

Y en el onNewIntent() me acaba de establecer la switchToTab = true. Espero que alguien venga con una mejor solución.

+1

Tuve el mismo problema. Intenté hackear la implementación de ActionBar.TabListener, agregando un ft.commitAllowingStateLoss(), sin embargo, Sharlock también llamará a ft.commit(), no se puede comprometer dos veces. También probé la respuesta en http://stackoverflow.com/a/10261438/245345, pero no será de ayuda. Finalmente encontré tu solución, que funciona bien. Gracias. –

0

Creo que no debe invocar commit en el métodoTabSelected. Ya lo hizo el marco.

Ah, y usa la transacción que recibes, no crees una nueva.

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

El TabListener fue token del ejemplo de Google, así que supongo que es correcto. ¿Qué quieres decir con usar la transacción que recibo? – Wizche

+0

Gracias por la actualización, getSupportFragmentManager() debería estar ahí para admitir múltiples plataformas (uso la biblioteca de soporte), si elimino commit/beginTransaction funciona en el caso normal pero aún así me da la misma excepción en la pestaña de cambio después de reanudar. Supongo que no puedo realizar esta acción desde el método onNewIntent porque FragmentManager aún no está listo. – Wizche

Cuestiones relacionadas