2012-07-12 6 views
7

Meine FragmentActivity (singleTop) gibt mir IllegalStateException, wenn ich versuche, die Navigationsregisterkarte in der OnNewIntent-Methode zu wechseln.Registerkarte wechseln onNewIntent Ursache IllegalStateException

Genauer gesagt, Meine Anwendung SherlockActionBar mit drei Registerkarten verwenden, eine Registerkarte aktualisiert wird, wenn eine Push-Benachrichtigung empfangen wird (und die Absicht aufgerufen wird), wenn die App auf einer anderen Registerkarte ausgesetzt wurde, wenn ich die Absicht (in der onNewIntent) Ich ändere die Registerkarte (und daher das Fragment) auf die dritte Registerkarte mit bar.setSelectedNavigationItem() und dies verursacht mir das Problem. Wenn die App auf der dritten Registerkarte angehalten wurde, tritt keine Ausnahme auf.

Code:

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

Die Push-Benachrichtigung Absichten:

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; 

Die TabListener Methode (mit dem Kommentar auf der Linie 56 in der 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 
     } 

Die detaillierte Ausnahme :

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) 

Antwort

10

Ich fand eine Lösung für diese, irgendwie hässlich sowieso. Ich schalte nur die Registerkarte in der onResume statt onNewIntent:

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

Und im onNewIntent() Ich habe gerade die switchToTab = true. Ich hoffe, dass jemand mit einer besseren Lösung kommt.

+1

Ich hatte das gleiche Problem. Ich habe versucht, die ActionBar.TabListener-Implementierung zu hacken, indem ich eine ft.commitAllowingStateLoss() hinzufügte, aber Sharlock it self wird auch ft.commit() aufrufen, es kann nicht zweimal committed werden. Ich versuchte auch die Antwort bei http://stackoverflow.com/a/10261438/245345, aber es wird nicht helfen. Endlich habe ich deine Lösung gefunden, die gut funktioniert. Vielen Dank. –

0

Ich denke, Sie sollten nicht Commit in onTabSelected Methode aufrufen. Es ist bereits durch das Framework getan.

Oh, und verwenden Sie die Transaktion, die Sie erhalten, erstellen Sie keine neue.

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

Der TabListener war Token von Google Beispiel, also nehme ich an, ist richtig. Was meinen Sie damit, die Transaktion, die ich erhalte, zu nutzen? – Wizche

+0

Danke für das Update, sollte der getSupportFragmentManager() da sein, um mehrere Plattformen zu unterstützen (ich benutze die Support-Bibliothek), wenn ich die commit/beginTransaction entfernen funktioniert es im Normalfall, aber immer noch die gleiche Ausnahme auf der Registerkarte nach dem Fortsetzen. Ich nehme an, dass ich diese Aktion nicht mit der onNewIntent-Methode ausführen kann, da der FragmentManager noch nicht bereit ist. – Wizche