Mam aplikację, która polega na używaniu ActionBarSherlock w trybie tabulacji. Mam 5 zakładek, a zawartość każdej zakładki jest obsługiwana za pomocą fragmentów. Jednak dla tab2 mam fragment, którego plik xml zawiera element ViewPager, który z kolei ma kilka stron fragmentów. Kiedy początkowo uruchamiam aplikację, to mogę bez problemu przełączać się między zakładkami, ale po drugim naciśnięciu tab2 pojawia się wspomniany powyżej błąd. Główna działalność jest następująca:
public class MainActivity extends SherlockFragmentActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar();
ActionBar.Tab tab1 = actionBar.newTab().setText("Tab1");
ActionBar.Tab tab3 = actionBar.newTab().setText("Tab3");
ActionBar.Tab tab2 = actionBar.newTab().setText("Tab2");
ActionBar.Tab tab4 = actionBar.newTab().setText("Tab4");
ActionBar.Tab tab5 = actionBar.newTab().setText("Tab5");
Fragment fragment1 = new Tab1();
Fragment fragment3 = new Tab3();
Fragment fragment2 = new Tab2();
Fragment fragment5 = new Tab5();
Fragment fragment4 = new Tab4();
tab1.setTabListener(new MyTabListener(fragment1));
tab3.setTabListener(new MyTabListener(fragment3));
tab2.setTabListener(new MyTabListener(fragment2));
tab5.setTabListener(new MyTabListener(fragment5));
tab4.setTabListener(new MyTabListener(fragment4));
actionBar.addTab(tab1);
actionBar.addTab(tab2);
actionBar.addTab(tab3);
actionBar.addTab(tab4);
actionBar.addTab(tab5);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
}
class MyTabListener implements ActionBar.TabListener
{
Fragment fragment;
public MyTabListener(Fragment fragment)
{
this.fragment = fragment;
}
@Override
public void onTabSelected(com.actionbarsherlock.app.ActionBar.Tab tab,FragmentTransaction ft)
{
ft.replace(R.id.fragment_container,fragment);
}
@Override
public void onTabUnselected(com.actionbarsherlock.app.ActionBar.Tab tab,FragmentTransaction ft)
{
}
@Override
public void onTabReselected(com.actionbarsherlock.app.ActionBar.Tab tab,FragmentTransaction ft)
{
}
}
}
Klasa fragmentu bez ViewPagera jest następująca:
public class Tab1 extends Fragment
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
return inflater.inflate(R.layout.activity_tab1, container, false);
}
}
Klasa fragmentu z ViewPager jest następująca:
public class Tab2 extends Fragment
{
ViewPager mViewPager;
private MyFragmentPagerAdapter mMyFragmentPagerAdapter;
private static int NUMBER_OF_PAGES = 5;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.activity_tab2, container, false);
return view;
}
@Override
public void onViewCreated(View view,Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
mMyFragmentPagerAdapter = new MyFragmentPagerAdapter(getChildFragmentManager());
mViewPager.setAdapter(mMyFragmentPagerAdapter);
}
private static class MyFragmentPagerAdapter extends FragmentPagerAdapter
{
public MyFragmentPagerAdapter(FragmentManager fm)
{
super(fm);
}
@Override
public Fragment getItem(int index)
{
return PageFragment.newInstance("My Message " + index);
}
@Override
public int getCount()
{
return NUMBER_OF_PAGES;
}
}
}
Z tego, co przeczytałem w różnych miejscach (i proszę mnie poprawić, jeśli się mylę), dzieje się tak, ponieważ menedżer fragmentów w drugim przebiegu próbuje ponownie wykorzystać fragmenty z działania, które już nie istnieje, dając tym samym błąd. Ale nie jestem pewien, dlaczego tak się dzieje tutaj, ponieważ nie używam aktywności fragmentów. Według logcat błąd znajduje się w klasie Tab2, w metodzie onViewCreated w wierszu mViewPager.setAdapter (mMyFragmentPagerAdapter). Każda pomoc jest bardzo ceniona ... Dzięki.
03-04 12:01:05.468: E/AndroidRuntime(2474): FATAL EXCEPTION: main
03-04 12:01:05.468: E/AndroidRuntime(2474): java.lang.IllegalStateException: Activity has been destroyed
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1342)
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:578)
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:139)
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.support.v4.view.ViewPager.populate(ViewPager.java:1011)
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.support.v4.view.ViewPager.populate(ViewPager.java:880)
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:433)
03-04 12:01:05.468: E/AndroidRuntime(2474): at com.example.tabs.Tab2.onViewCreated(Tab2.java:31)
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:925)
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:429)
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.os.Handler.handleCallback(Handler.java:587)
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.os.Handler.dispatchMessage(Handler.java:92)
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.os.Looper.loop(Looper.java:123)
03-04 12:01:05.468: E/AndroidRuntime(2474): at android.app.ActivityThread.main(ActivityThread.java:3687)
03-04 12:01:05.468: E/AndroidRuntime(2474): at java.lang.reflect.Method.invokeNative(Native Method)
03-04 12:01:05.468: E/AndroidRuntime(2474): at java.lang.reflect.Method.invoke(Method.java:507)
03-04 12:01:05.468: E/AndroidRuntime(2474): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
03-04 12:01:05.468: E/AndroidRuntime(2474): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
03-04 12:01:05.468: E/AndroidRuntime(2474): at dalvik.system.NativeStart.main(Native Method)
źródło
Odpowiedzi:
Wydaje się, że jest to błąd w nowo dodanej obsłudze zagnieżdżonych fragmentów. Zasadniczo dziecko
FragmentManager
kończy się złamanym stanem wewnętrznym, gdy jest oderwane od aktywności. Krótkoterminowym obejściem, które rozwiązało problem, jest dodanie następujących elementów doonDetach()
każdego, doFragment
którego dzwoniszgetChildFragmentManager()
:źródło
Mam dokładnie ten sam problem. Jedyne obejście, jakie znalazłem, to zastąpienie fragmentów nową instancją za każdym razem, gdy zmieniane są zakładki.
Nie jest to prawdziwe rozwiązanie, ale nie znalazłem sposobu na ponowne użycie poprzedniej instancji fragmentu ...
źródło
Napotkałem ten sam problem podczas wywoływania
super.onCreate()
na końcu mojej metody. Powód:attachActivity()
jest wywoływany onCreate () elementu FragmentActivity. Podczas zastępowaniaonCreate()
i, na przykład, tworzenia kart, menedżer kart będzie próbował przełączyć się na fragment, nie mając aktywności dołączonej do FragmentManager.Proste rozwiązanie: przenieś wywołanie do
super.onCreate()
nagłówka treści funkcji.Ogólnie wydaje się, że istnieje wiele powodów, dla których ten problem może wystąpić. To tylko kolejny ...
Matthias
źródło
Chciałem dodać, że mój problem był związany z działaniem, w którym próbowałem wykonać
FragmentTransaction
onCreate ZANIM zadzwoniłemsuper.onCreate()
. Właśnie przeszedłemsuper.onCreate()
na szczyt funkcji i działało dobrze.źródło
Wystąpił ten błąd, ponieważ korzystałem z LocalBroadcastManager i tak:
zamiast:
źródło
I napotkał ten sam problem i okazało się, że lateron, mam nieodebrane się
super.onCreate( savedInstanceState );
wonCreate()
od FragmentActivity.źródło
Ten sam błąd wystąpił podczas próby uzyskania dostępu do dziecka,
FragmentManager
zanim fragment został w pełni zainicjowany (tj. Został dołączony do działania lub przynajmniejonCreateView()
wywołany). W przeciwnym razieFragmentManager
zostaje zainicjowanynull
działaniem powodującym wspomniany wyjątek.źródło
Zmuszam fragment zawierający fragment podrzędny do NULL w onPause i to rozwiązuje mój problem
źródło
Wiem, że to stary post, ale sugerowane odpowiedzi nie zadziałały po mojej stronie. Chcę to zostawić tutaj na wypadek, gdyby ktoś uznał to za przydatne.
Co zrobiłem to:
Następnie w:
źródło
Miałem ten problem i nie mogłem znaleźć tutaj rozwiązania, więc chcę udostępnić moje rozwiązanie na wypadek, gdyby ktoś inny miał ten problem ponownie.
Miałem taki kod:
i rozwiązał problem, usuwając wiersz "onDestroy ();"
Powód, dla którego napisałem początkowy kod: Wiem, że kiedy wykonujesz "finish ()", działanie wywołuje "onDestroy ()", ale używam wątków i chciałem się upewnić, że wszystkie wątki zostaną zniszczone przed rozpoczęciem następnej czynności i wygląda na to, że „finish ()” nie zawsze jest natychmiastowa. Potrzebuję przetworzyć / zredukować wiele „Bitmap” i wyświetlać duże „Bitmapy” i pracuję nad poprawieniem wykorzystania pamięci w mojej aplikacji
Teraz zabiję wątki inną metodą i wykonam tę metodę z "onDestroy ();" i kiedy myślę, że muszę zabić wszystkie wątki.
źródło
Miałem ten problem i sobie sprawę, że to dlatego, że dzwoni
setContentView(int id)
dwa razy w moichActivity
„sonCreate
źródło
To doprowadziło mnie do szaleństwa na punkcie platformy Xamarin.
Natknąłem się na to z implementacją ViewPager dla TabLayout WITHIN a Fragment, który jest sam zaimplementowany w DrawerLayout:
Więc musisz zaimplementować następujący kod w swoim DrawerFragment . Pamiętaj, aby wybrać prawidłową ścieżkę FragmentManager. Ponieważ możesz mieć dwie różne referencje FragmentManager:
-> Wybierz ten, którego używasz. Jeśli chcesz skorzystać z ChildFragmentManager, musisz użyć deklaracji klasy Android.App.FragmentManager dla swojego ViewPager!
Android.Support.V4.App.FragmentManager
Zaimplementuj następującą metodę w swoim „głównym” fragmencie - w tym przykładzie: DrawerFragment
Android.App.FragmentManager
Oznacza to, że trzeba było zainicjować ViewPager za pomocą Android.App.FragmentManager.
Zaimplementuj następującą metodę w swoim „głównym” fragmencie - w tym przykładzie: DrawerFragment
źródło
Błąd został naprawiony w najnowszej wersji Androidax. Słynne obejście spowoduje teraz awarię. więc nie potrzebujemy tego teraz.
źródło