2013-09-05 10 views
23

EDIT 2FragmentStatePagerAdapter z ChildFragmentManager - wyniki FragmentManagerImpl.getFragment w NullPointerException

I teraz udało się pozbyć tego błędu z użyciem trick stąd https://code.google.com/p/android/issues/detail?id=42601#c10 tak, że to reoson dlaczego moja ostatnia edycja jest umieszczona na górze moje pytanie.

Ale doprowadziło to do następnego błędu:

java.lang.NullPointerException 
at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:569) 
at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:211) 
at android.support.v4.view.ViewPager.onRestoreInstanceState(ViewPager.java:1281) 
at android.view.View.dispatchRestoreInstanceState(View.java:12043) 
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2688) 
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2694) 
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2694) 
at android.view.View.restoreHierarchyState(View.java:12021) 
at android.support.v4.app.Fragment.restoreViewState(Fragment.java:425) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:949) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104) 
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) 
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460) 
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440) 
at android.os.Handler.handleCallback(Handler.java:615) 
at android.os.Handler.dispatchMessage(Handler.java:92) 
at android.os.Looper.loop(Looper.java:137) 
at android.app.ActivityThread.main(ActivityThread.java:4800) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:511) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:798) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:565) 
at dalvik.system.NativeStart.main(Native Method) 

I teraz nie wiem gdzie, aby kontynuować ...

Edit 0 - Pierwsze pytanie

dostaję następujący wyjątek:

java.lang.IllegalStateException: No activity 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1091) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1086) 
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1877) 
at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1492) 
at android.support.v4.app._HoloFragment.performActivityCreated(_HoloFragment.java:251) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104) 
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) 
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460) 
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440) 
at android.os.Handler.handleCallback(Handler.java:615) 
at android.os.Handler.dispatchMessage(Handler.java:92) 
at android.os.Looper.loop(Looper.java:137) 
at android.app.ActivityThread.main(ActivityThread.java:4800) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:511) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:798) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:565) 
at dalvik.system.NativeStart.main(Native Method) 

Nie mam pojęcia Gdzie zacząć. Używam aktualnej biblioteki pomocy technicznej (v4, rev18).

Wszystko działa poprawnie, dopóki nie dodasz Fragment, która posiada ViewPager w połączeniu z FragmentStatePagerAdapter.

używam biblioteki pomocy wszędzie, próbowałem rozwiązań z https://code.google.com/p/android/issues/detail?id=42601 ...

Ale jeszcze nic nie działało ...

nie wiem od czego zacząć, czy ktoś ma Wskazówka?

EDIT 1: tło i kod

1) W moim główną działalność Używam następujący:

Trzecia strona ma viewpager ...

public void setPage(int pos, boolean addToBackStack) 
{ 
    Fragment nextFragment = null; 
    FragmentTransaction transaction = null; 

    switch (pos) 
    { 
     case 0: 
      if (mFragmentAllRoutines == null) 
       mFragmentAllRoutines = new RoutinesListFragment(); 
      if (!mFragmentAllRoutines.isVisible()) 
       nextFragment = mFragmentAllRoutines; 
      break; 
     case 1: 
      if (mFragmentRoutine == null) 
       mFragmentRoutine = new RoutineFragment(); 
      if (!mFragmentRoutine.isVisible()) 
       nextFragment = mFragmentRoutine; 
      break; 
     case 2: 
      if (mFragmentDay == null) 
       mFragmentDay = new RoutineDayFragment(); 
      if (!mFragmentDay.isVisible()) 
       nextFragment = mFragmentDay; 
      break; 
     default: 
      break; 
    } 

    if (nextFragment != null) 
    { 
     // Fragment prevFragment = getSupportFragmentManager().findFragmentById(R.id.fragment); 
     transaction = getSupportFragmentManager().beginTransaction(); 
     // if (prevFragment != null) 
     // transaction.detach(prevFragment); 
     transaction.replace(R.id.fragment, nextFragment, nextFragment.getClass().getName()); 
     // transaction.attach(nextFragment); 
     if (addToBackStack) 
      transaction.addToBackStack(null); 
     transaction.commit(); 
    } 
} 

2) trzeci fragment:

To prosty fragment z ViewPager i Fragmą ntStatePagerAdapter. FragmentStatePagerAdapter otrzymuje nazwę getChildFragmentManager() jako FragmentManager. I gdzieś wydaje się, że jest problem.

+0

opublikuj swój odpowiedni kod –

+0

opublikuj swój kompletny ślad stosu, dane wyjściowe logcat .. i twój kod też. –

+0

Zaktualizowałem moje pytanie i aktualny stan mojego problemu ... – prom85

Odpowiedz

59

Potrzebuję zobaczyć więcej kodu, aby wiedzieć, gdzie to zastosować ... ale ja miałem podobną sytuację jak ty ... Rozwiązałem kwestię ChildFragmentManager w ten sam sposób i otrzymałem ten sam NullPointerException, co ty masz.

Udało mi się go rozwiązać ... Postaram się opisać moje rozwiązanie, ponieważ z podanym kodem nie jestem pewien, gdzie zastosować "naprawę" ... Naprawdę jest to poprawka. To nie jest elegancki sposób na rozwiązanie tego problemu! Pomogło mi to jednak i nie muszę przywracać stanów po opuszczeniu widoku Pager, więc nie mam dla mnie żadnego minusu.

Mam wiele Fragmentów, które implementują statyczny bit kodu i onDetach (na https://code.google.com/p/android/issues/detail?id=42601#c10), każdy fragment ma pager, a onCreateView dołączam adapter rozszerzający FragmentStatePagerAdapter.

na tych adapterów mam przesłonięte metody restoreState zrobić nic

@Override 
public void restoreState(Parcelable arg0, ClassLoader arg1) { 
    //do nothing here! no call to super.restoreState(arg0, arg1); 
} 

Ponownie, to nie jest najlepszy sposób ... ale to nie rozwiąże mój problem.

Powodzenia!

+1

DZIĘKUJEMY !!! Pracował jak urok. – KVISH

+0

Dlaczego tak się dzieje? jakie są konsekwencje? Czy jest to znany problem, który zostanie rozwiązany w przyszłości? –

+6

"Dlaczego tak się dzieje? Jakie są konsekwencje? Czy jest to znany problem, który zostanie rozwiązany w przyszłości?" (a) Nikt nie wie, (b) Nikt nie wie, (c) Prawdopodobnie nie. Ale wydaje się, że działa dla mnie. (witamy na Androidzie) –

1

Po mojej stronie zachowałem odwołanie do fragmentów ViewPager w fragmencie zawierającym i używano onSaveInstanceState do przechowywania ich stanów. Myślę, że wystąpił NPE, ponieważ kolidowało to z własnym mechanizmem ViewPager w celu przywrócenia fragmentów. To, co zrobiłem, zmieniłem swoją architekturę z ViewPagera, aby podzielić transakcje, którymi się zarządzam. (ViewPager nie był odpowiednim rozwiązaniem dla mojej sprawy)

0

Po pierwsze, angielski nie jest moim językiem ojczystym, jeśli mam coś nie tak z gramatyki, proszę powiedz mi. Napotkałem ten problem w moim projekcie. Na początku zrobiłem to, co powiedział Marc, i zadziałało dobrze. Ale kiedy dodałem kolejną ViewPager w fragmencie ojca, nowy ViewPager pokazał taki sam, jak poprzedni, bez względu na rodzaj kodu w tym nowym oknie podglądu. W końcu znalazłem przyczynę. Zawsze tworzymy Fragment za pomocą metody FragmentTrasaction.replace (R.layout.fragment, fragment). Z tego powodu tworzymy nową instancję fragmentu, gdy używamy tej metody. Zamiast używać metody replace() używam metody FragmentTransaction.hide() i show() do zmiany fragmentu. W ten sposób rozwiązałem mój problem. Oto mój kod urywki:

@Override 
public void onClick(View v) { 
    FragmentTransaction transaction = fm.beginTransaction(); 
    switch (v.getId()) { 
     case R.id.tv_schedule_day: 
     hideFragment(transaction); 
     if (dayFragment == null) { 
      dayFragment = new ScheduleDayFragment(); 
      transaction.add(R.id.ll_schedule_content, dayFragment); 
     } else { 
      transaction.show(dayFragment); 
     } 
     transaction.commit(); 
     break; 
     case R.id.tv_schedule_week: 
     hideFragment(transaction); 
     if (weekFragment == null) { 
      weekFragment = new ScheduleWeekFragment(); 
      transaction.add(R.id.ll_schedule_content, weekFragment); 
     } else { 
      transaction.show(weekFragment); 
     } 
     transaction.commit(); 
     break; 
    case R.id.tv_schedule_month: 
     hideFragment(transaction); 
     if (monthFragment == null) { 
      monthFragment = new ScheduleMonthFragment(); 
      transaction.add(R.id.ll_schedule_content, monthFragment); 
     } else { 
      transaction.show(monthFragment); 
     } 
     transaction.commit(); 
     break; 

private void hideFragment(FragmentTransaction transaction) { 
    if (dayFragment != null) { 
     transaction.hide(dayFragment); 
    } 
    if (weekFragment != null) { 
     transaction.hide(weekFragment); 
    } 
    if (monthFragment != null) { 
     transaction.hide(monthFragment); 
    } 
} 

używam hide() i show() metody, aby fragment ojciec przełącznik, więc kiedy używam getChildFragmentManager() w osadzonym fragmencie, to wolud nie zwróci null. To pytanie zadano w 2013 r. Myślę, że nikt nie zobaczyłby tej odpowiedzi, ale nadal cieszę się, że mogę odpowiedzieć na to pytanie.

4

Po prostu natknąłem się na ten sam problem.

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference 
    at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:873) 
    at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:215) 

Rozwiązanie autorstwa Marca działa, ale w moim przypadku spowodowało opóźnienia w Fragmentie z FragmentStatePagerAdapter. Więc nadpisałem restoreState, zwane super, zapakowałem go w try/catch i działało bez lagów.

@Override 
public void restoreState(Parcelable state, ClassLoader loader) { 
    try{ 
     super.restoreState(state, loader); 
    }catch (NullPointerException e){ 
     // null caught 
    } 
} 
+0

Nie mam pojęcia, gdzie był problem, ale ta odpowiedź to naprawi!Dzięki – michgauz

+0

Nie mam pojęcia, czy jest to w jakiś sposób szkodliwe dla aplikacji w jakiś głęboki i tajemniczy sposób. Ale jestem gotów to wypróbować. –

Powiązane problemy