Aby skupić się na problemie, uprość sprawę do następnej - Mam działanie A i fragment F, który dodaje kolejny fragment Dziecko. Uproszczony kod każdy jestWyjątek podczas próby zapisania stanu zagnieżdżonego fragmentu [Fragment już nie istnieje dla klucza android: target_state]
aktywność na
@Override
protected void onCreate(Bundle savedInstanceState) {
// do some stuff
FragmentManager fm = getSupportFragmentManager();
F f = new F();
fm.beginTransaction()
.add(R.id.content, f)
.commit();
}
fragment F
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// do some stuff
FragmentManager fm = getChildFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
ChildFragment childFragment = new ChildFragment();
childFragment.setTargetFragment(this, 1);
transaction.add(R.id.f, childFragment);
transaction.commit();
return view;
}
Kod fragmentu dziecko nie ma znaczenia dla tego problemu, tak, że po to przyzwyczajenie.
Użycie tego kodu wszystko wydawało się działać poprawnie, dopóki nie zintegrowane Firebase i zacząć Niniejszy raport katastrofie
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.test/com.test.test.A}: java.lang.IllegalStateException: Fragment no longer exists for key android:target_state: index 1
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2377)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2429)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5341)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:825)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641)
at dalvik.system.NativeStart.main(Native Method)
Na początku nie mogłem odtworzyć wyjątek, ale po przetestowaniu przez chwilę znalazłem, że jeśli Opcja programisty Nie kontynuuj działań jest na stanie się prawie za każdym razem, gdy wprowadzam aktywność do tła i wznawiam ją. Myślę, że w normalnym przypadku stanie się to, gdy działanie zostanie umieszczone w tle, a aplikacja zostanie zniszczona.
Po przeprowadzeniu badań dochodzę do wniosku, że faktycznym powodem awarii jest to, że fragment F jest ustawiony jako fragment docelowy dla dziecka. Mogę potwierdzić, że jeśli nie ustawię fragmentu docelowego, awarie się nie pojawią.
Nie jestem absolutnie pewny, ale wydaje się, że przyczyną katastrofy jest to, że Fragment Dziecka i jego fragment docelowy znajdują się w różnych FragmentManagerach. Pierwszą rzeczą, którą próbowałem, było umieszczenie wszystkich fragmentów w menedżerze fragmentów aktywności.
fragment F
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// do some stuff
// I do not want to use private fragment manager but rather use the activity's
// FragmentManager fm = getChildFragmentManager();
FragmentManager fm = getFragmentManager();
// do the other stuff
}
to rozwiązano ten problem. Ale doprowadzić do kolejnego. Po usunięciu fragmentu z działania (chcę go zastąpić innym fragmentem). Fragment potomny nie może zapisać swojego stanu, ponieważ zawiera odniesienie do jego fragmentu macierzystego, który został usunięty z menedżera.
Process: com.test.test, PID: 11047 java.lang.IllegalStateException: Failure saving state: ChildFragment{423c10f0 #1 id=0x7f0b0058} has target not in fragment manager: F{423c0f88}
at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:2618)
at android.support.v4.app.FragmentController.saveAllState(FragmentController.java:134)
at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:571)
at android.support.v7.app.AppCompatActivity.onSaveInstanceState(AppCompatActivity.java:515)
at android.app.Activity.performSaveInstanceState(Activity.java:1157)
at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1229)
mogę spróbować głębiej i usunąć fragment dziecka, gdy jego rodzic zostaje usunięty, ale mam wrażenie, nie jest to dobry sposób, żeby to zrobić, mimo wszystko uważam, że właściwą drogą do tego jest za pomocą metody getChildFragmentManager().
Każda pomoc, sugestie, wytyczne dotyczące tematu będą bardzo mile widziane.
Dlaczego nie tworzysz i nie dodajesz fragmentów tylko z jednego miejsca - działania A? – helleye
To sprawi, że fragment nie będzie można ponownie użyć. Wszystkie czynności, które dodają fragment, muszą również dodać fragment potomny. –
Czy próbowałeś tego https://code.google.com/p/android/issues/detail?id=54520 – Krish