У меня есть приложение, которое состоит из использования ActionBarSherlock в режиме вкладок. У меня есть 5 вкладок, и содержимое каждой вкладки обрабатывается с помощью фрагментов. Однако для tab2 у меня есть фрагмент, XML-файл которого содержит элемент ViewPager, который, в свою очередь, имеет несколько страниц фрагментов. Когда я сначала запускаю приложение, я могу без проблем переключаться между вкладками, но когда я нажимаю вкладку 2 во второй раз, я получаю указанную выше ошибку. Основная деятельность заключается в следующем:
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)
{
}
}
}
Класс фрагмента без ViewPager выглядит следующим образом:
public class Tab1 extends Fragment
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
return inflater.inflate(R.layout.activity_tab1, container, false);
}
}
Класс фрагмента с ViewPager выглядит следующим образом:
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;
}
}
}
Из того, что я читал в разных местах (и, пожалуйста, поправьте меня, если я ошибаюсь), это происходит потому, что диспетчер фрагментов на втором проходе пытается повторно использовать фрагменты из активности, которой больше не существует, что приводит к ошибке. Но я не уверен, почему это происходит здесь, поскольку я не использую активность фрагментов. Согласно logcat, ошибка находится в классе Tab2, метод onViewCreated в строке, которая говорит mViewPager.setAdapter (mMyFragmentPagerAdapter). Любая помощь приветствуется ... Спасибо.
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)
Ответы:
Похоже, это ошибка недавно добавленной поддержки вложенных фрагментов. В основном, когда ребенок
FragmentManager
отрывается от деятельности, его внутреннее состояние нарушается. Кратковременный обходной путь, который исправил это для меня, - добавить следующее кonDetach()
каждому, кFragment
чему вы обращаетесьgetChildFragmentManager()
:источник
У меня точно такая же проблема. Единственный обходной путь, который я нашел, - это заменять фрагменты новым экземпляром каждый раз, когда вкладки меняются.
Не настоящее решение, но я не нашел способа повторно использовать предыдущий экземпляр фрагмента ...
источник
Я столкнулся с той же проблемой при вызове
super.onCreate()
в конце моего метода. Причина:attachActivity()
вызывается onCreate () FragmentActivity. При переопределенииonCreate()
и, например, создании вкладок, диспетчер вкладок попытается переключиться на фрагмент, не привязав активность к FragmentManager.Простое решение: переместите вызов
super.onCreate()
в заголовок тела функции.В общем, похоже, что эта проблема может возникнуть по множеству причин. Это просто еще один ...
Матиас
источник
Хотел добавить, что моя проблема была
FragmentTransaction
в действии, где я пытался создать onCreate ДО того, как позвонилsuper.onCreate()
. Я просто перешелsuper.onCreate()
в верхнюю часть функции и работал нормально.источник
У меня была эта ошибка, потому что я использовал LocalBroadcastManager, и я сделал:
вместо того:
источник
Я столкнулся с теми же проблемами и Lateron узнал, что я пропустил звонок
super.onCreate( savedInstanceState );
вonCreate()
из FragmentActivity.источник
Я получил ту же ошибку при попытке доступа к дочернему элементу
FragmentManager
до того, как фрагмент был полностью инициализирован (то есть прикреплен к Activity или, по крайней мере,onCreateView()
вызван). В противном случаеFragmentManager
инициализируетсяnull
Activity, вызывающее вышеупомянутое исключение.источник
Я принудительно устанавливаю для фрагмента, содержащего дочерний фрагмент, значение NULL в onPause, и это решает мою проблему.
источник
Я знаю, что это старый пост, но предложенные ответы с моей стороны не сработали. Я хочу оставить это здесь на всякий случай, если кому-то это пригодится.
Что я сделал:
Затем в:
источник
У меня была эта проблема, и я не смог найти здесь решение, поэтому я хочу поделиться своим решением на случай, если у кого-то снова возникнет эта проблема.
У меня был такой код:
и решил проблему, удалив строку "onDestroy ();"
Причина, по которой я написал исходный код: я знаю, что когда вы выполняете "finish ()", действие вызывает "onDestroy ()", но я использую потоки, и я хотел убедиться, что все потоки будут уничтожены перед запуском следующего действия. , и похоже, что "finish ()" не всегда выполняется немедленно. Мне нужно обработать / уменьшить количество «растровых изображений» и отобразить большие «растровые изображения», и я работаю над улучшением использования памяти в моем приложении.
Теперь я убью потоки, используя другой метод, и я выполню этот метод из "onDestroy ();" и когда я думаю, мне нужно убить все потоки.
источник
Я имел этот вопрос и понял , что это было , потому что я звонил
setContentView(int id)
дважды в моемActivity
-хonCreate
источник
Этот сводил меня с ума по Xamarin.
Я столкнулся с этим с реализацией ViewPager для TabLayout ВНУТРИ фрагмента, который сам реализован в DrawerLayout:
Итак, вам нужно реализовать следующий код в своем DrawerFragment . Не забывайте выбирать правильный FragmentManager-Path. Потому что у вас может быть две разные ссылки FragmentManager:
-> Выберите тот, который вы используете. Если вы хотите использовать ChildFragmentManager, вам нужно было использовать объявление класса Android.App.FragmentManager для вашего ViewPager!
Android.Support.V4.App.FragmentManager
Реализуйте следующий метод в своем « основном » фрагменте - в этом примере: DrawerFragment
Android.App.FragmentManager
Это означает, что вам нужно было запустить ViewPager с Android.App.FragmentManager.
Реализуйте следующий метод в своем « основном » фрагменте - в этом примере: DrawerFragment
источник
Ошибка исправлена в последней версии androidx. И знаменитый обходной путь теперь вызовет сбой. так что нам это не нужно сейчас.
источник