NullPointerException в FragmentManager
Я использую библиотеку совместимости Android и иногда получаю странный NullPointerException
:
java.lang.NullPointerException
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:960)
at android.support.v4.app.FragmentManagerImpl.performPendingDeferredStart(FragmentManager.java:768)
at android.support.v4.app.FragmentManagerImpl.startPendingDeferredFragments(FragmentManager.java:1104)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:410)
at android.support.v4.content.Loader.deliverResult(Loader.java:103)
at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:81)
at android.support.v4.content.CursorLoader.onStartLoading(CursorLoader.java:126)
at android.support.v4.content.Loader.startLoading(Loader.java:197)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.start(LoaderManager.java:262)
at android.support.v4.app.LoaderManagerImpl.doStart(LoaderManager.java:710)
at android.support.v4.app.Fragment.onStart(Fragment.java:981)
at android.support.v4.app.Fragment.performStart(Fragment.java:1332)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:906)
at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1240)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:612)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:431)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:139)
at android.support.v4.view.ViewPager.populate(ViewPager.java:804)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:433)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:405)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:386)
...
Очевидно, что я делаю что-то неправильно, чтобы позволить FragmentManager
попасть в такое состояние, в котором он может так разбиться, но я не знаю, что. соответствующий код в FragmentManagerImpl
не предлагает мне никаких подсказок. Я предполагаю, что mActivity
есть как-то null
в этой точке кода? Но это кажется невозможным, поскольку активность уже находится на экране, и я не добавляю к ней никаких фрагментов - просто переключаюсь между ними в ViewPager
.
Ответы
Ответ 1
Хорошо, ребята, немного ударившись головой о кирпичную стену, я обнаружил, что это напрямую связано с объявлением моего фрагмента setRetainInstance(true)
. После устранения проблемы проблемы исчезли. Это похоже на ошибку библиотеки совместимости...
Я подниму что-то под соответствующим проектом Google.
Желаем удачи, если вы читаете это медленно, покачиваясь! Надеюсь, это позволит вам решить эту проблему.
Ответ 2
Я получил эту ошибку несколько дней назад и был довольно запутан, но я понял, что это потому, что FragmentTransaction
, похоже, не получал ожидающих транзакций, поэтому при вызове executePendingTransactions();
A NPE
один был брошен.
Я решил это, убедившись, что каждая транзакция фактически что-то изменила (например, добавить фрагмент 1 → удалить фрагмент 1 → commit/execute не будет работать).
Также убедитесь, что ни один из фрагментов пейджера не стал null
.
Ответ 3
Я получал ту же ошибку, потому что я ссылался на экземпляр фрагмента в адаптере пейджера вида, а сам фрагмент.
Создание нового экземпляра фрагмента каждый раз, когда фрагмент был вызван, разрешил эту ошибку. Очевидно, что это правильное программирование, но на случай, если некоторые другие нообы совершают эту ошибку....
@Override
public Fragment getItem(int position) {
if(position == 0)
return new Walkthrough_Fragment_1();
if(position == 1)
return new Walkthrough_Fragment_4();
if(position == 2)
return new Walkthrough_Fragment_2();
else{
return new Walkthrough_Fragment_3();
}
}
Ответ 4
Эта ошибка возникает при использовании FragmentPagerAdapter
внутри фрагмента, использующего setRetainInstance(true)
.
Если вы хотите сохранить setRetainInstance(true)
, вы можете использовать ответ @Marc от Этот вопрос:
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
//do nothing here! no call to super.restoreState(arg0, arg1);
}
Ответ 5
В какой-то момент вы используете экземпляр класса FragmentManager, который не инициализирован. Найдите эту точку и правильно инициализируйте объект.
Ответ 6
Я просто прочитал, что вы не можете выполнять определенные транзакции по фрагментам, которые были добавлены во время компиляции. Например, если ваш фрагмент был определен в XML, и вы пытаетесь его заменить, стрела.
Ответ 7
Я решил проблему, установив FragmentManager как статическую глобальную переменную, а затем инициализировал ее в методе onCreate. Я узнал, что с помощью getSupportFragmentManager()
везде в вашем коде может возникнуть это исключение, потому что getSupportFragmentManager() может указывать на ваше прежнее значение диспетчера фрагментов и не может ссылаться.
Вот пример:
public class yourClass{
private static FragmentManager myFragmentManagerSupport;
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myFragmentManagerSupport = this.getSupportFragmentManager();
....
}
/*Then reuse myFragmentManagerSupport everywhere you needed instead of
* getSupportFragmentManager()
*/
}
Надеюсь, что это поможет.