2013-10-18 19 views
9

Bir Android App ile hedef SDK 4.3 derlenmiş ve çalışan bir Sorunum var. App iki Etkinliği, aynı zamanda Launcher Etkinliği ve bir SecondActivity olan bir MainActivity vardır. Her ikisi de Fragments kullanıyor. Daha eski cihazları da desteklemek için, destek lib kullanılır.java.lang.IllegalStateException: Fragment zaten eklendi

Aşağıdaki senaryoda, "IllegalStateException: Fragment zaten eklendi" Hatası geliyor. Uygulamayı başlatın

1) -> MainActivity bir Niyet
3) Basın Ana Düğme
4) 24 saat ile test daha uzun()
5 bekleyiniz ile SecondActivity için
2) anahtarı gösterilir) tekrar uygulama simgesine basın -> İstisna. Zaman kısalırsa, SecondActivity beklenildiği gibi gösterilir.

Fragment kullanımı sırasında çok sayıda İllegalStateExceptions okudum, ancak hepsi bir replace() yöntemiyle ilgili bir soruna işaret etti. Stacktrace'de, kendi kodum asla çağrılmaz.

Fragement Toplantıları Devam onCreate eklenir() Yöntem:

Tamam
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(..); 
    ListFragment listFragment = this.getCaptureListFragment(); 
    FragmentTransaction tx = this.getSupportFragmentManager().beginTransaction(); 
    tx.add(R.id.MainFragmentContainer, listFragment, "list_fragment_tag"); 
    tx.commit(); 
} 

private ListFragment getListFragment() { 
    ListFragment listFragment = (ListFragment) this.getSupportFragmentManager().findFragmentByTag("list_fragment_tag"); 
    if (listFragment == null) { 
     listFragment = new ListFragment(); 
    } 
    return listFragment; 
} 


java.lang.RuntimeException: Unable to start activity ComponentInfo{de.myexample.demo/de.myexample.demo.ui.SecondActivity}: java.lang.IllegalStateException: Fragment already added: ListFragment{42283f58 #0 id=0x7f060094 de.myexample.demo.ui.ListFragment} 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261) 
    at android.app.ActivityThread.access$600(ActivityThread.java:141) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:5103) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:525) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
    at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.IllegalStateException: Fragment already added: ListFragment{42283f58 #0 id=0x7f060094 de.myexample.demo.ui.ListFragment} 
    at android.support.v4.app.FragmentManagerImpl.addFragment(SourceFile:1175) 
    at android.support.v4.app.BackStackRecord.run(SourceFile:616) 
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(SourceFile:1460) 
    at android.support.v4.app.FragmentActivity.onStart(SourceFile:556) 
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171) 
    at android.app.Activity.performStart(Activity.java:5143) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184) 
    ... 11 more 
java.lang.IllegalStateException: Fragment already added: ListFragment{42283f58 #0 id=0x7f060094 de.myexample.demo.ui.ListFragment} 
    at android.support.v4.app.FragmentManagerImpl.addFragment(SourceFile:1175) 
    at android.support.v4.app.BackStackRecord.run(SourceFile:616) 
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(SourceFile:1460) 
    at android.support.v4.app.FragmentActivity.onStart(SourceFile:556) 
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171) 
    at android.app.Activity.performStart(Activity.java:5143) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261) 
    at android.app.ActivityThread.access$600(ActivityThread.java:141) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:5103) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:525) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
    at dalvik.system.NativeStart.main(Native Method) 
+0

nerede aktivite fro setContentView nedir? – Raghunandan

+0

tx.replace (R.id.MainFragmentContainer, listFragment) kullanmayı deneyin; tx.add() yöntemini kullanmak yerine. [Oku] (http://developer.android.com/guide/components/fragments.html). fragmanlarda daha fazlası için –

+0

Teşekkürler @Raghunandan. Gönderide eksik satırı ekledim. – creaity

cevap

12

, başıma çözülmesi.

Tüm Fragment'leri onPause() içine alıyorum ve durumu bazı booleanlarda depolarım. Bu boole bağlı olarak Fragments onResume() içine konur. Etkinliğin ne kadar sürdüğüne bakılmaksızın, etkinlik arka planda kalıyor.

boolean addList = false; 

@Override 
protected void onResume() { 
    FragmentTransaction tx = this.getSupportFragmentManager().beginTransaction(); 
    if (this.addList) { 
     ListFragment list = this.getListFragment(); 
     tx.add(R.id.MainFragmentContainer, list, "list_fragment_tag"); 
    } 

    tx.commit(); 
    super.onResume(); 

    this.addList = false; 

} 

@Override 
protected void onPause() { 
    this.addList = this.getListFragment().isAdded(); 
    ... 
    if (this.addList) { 
     FragmentTransaction tx = this.getSupportFragmentManager().beginTransaction(); 
     tx.remove(this.getListFragment()); 
     tx.commit(); 
    } 
    this.getSupportFragmentManager().executePendingTransactions(); 
    super.onPause(); 

} 

Belki bu Fragment yöneticisi zaman çıkış onun durumunu kaydeder aynı sorunu

0

olan biri yardımcı olur. Böylece parçanızı tekrar eklemeniz gerekmez.

böyle yapın: Bu çoğaltmak amacıyla

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(..); 

    if (savedInstanceState == null) { 
     ListFragment listFragment = this.getCaptureListFragment(); 
     FragmentTransaction tx = this.getSupportFragmentManager().beginTransaction(); 
     tx.add(R.id.MainFragmentContainer, listFragment, "list_fragment_tag"); 
     tx.commit(); 
    } 
} 
+0

Cevabınız için teşekkürler. Tamamen değil, yardımcı oldu. Android 4.1'de hile yapar. Ancak 4.4 KitKat cihazında, etkinlik boş ve hiçbir Fragment görülmedi. Ama görünüşe göre, bu şekilde manuel çıkarmadan çok daha iyi. Belki, parçayı daha yeni cihazlarda el ile kaldırabilirim ... Daha fazla test yapmak zorundayım. Ama çok zaman harcıyorlar, çünkü en az 24 saat beklemeden önce sorunlara gelmeliyim – creaity

8

, tek Ayarlar bölümünde "Etkinlikleri saklama" aktive olabilir -> Geliştirici seçenekleri. Ardından etkinliği duraklatın ve devam ettirin. böylece O veridiliminin ekleyerek durumunun kontrol edilmesi için yeni boolean alan oluşturmak için gerekli değildir :)

+0

Bu benim için çalışmıyor :( –

-3

24 saat beklemek zorunda değil mi

. Parçada bir yöntem de vardır. Sadece kullanın: myFragment.isAdded()

+0

Boole, parçanın durumunu depolamak için değil. durumu daha önce depolayın (onPause() yöntemine bakın). Sorunu anlamadığınızı düşünüyorum. – creaity

+1

Evet, şimdi daha dikkatliüm. Üzgünüm, haklısınız. – serefakyuz

İlgili konular