Intereting Posts
Получить минимум из столбца базы данных SQLite? Идентификатор регистрации равен нулю от gcm в android 2.3.3, 2.3.5, но он не является нулевым и работает в android 2.3.4, 4.0.4 e.printStackTrace (); В строке Изменение цвета значка настроек панели действий NullPointerException в SharedPreferences Android Как получить список записей фрагмента backstack в android? Android – Пользовательская анимация на транзакции фрагмента не запущена Android – кэш Bitmap занимает много памяти Будет ли Samsung поддерживать API отпечатков пальцев Google от Marshmallow? Ошибка памяти: куча памяти Java на Android Studio Как позвонить в список контактов Android И выбрать один номер телефона на экране своих данных? Android: файлы, которые я пишу на SD-карте, не отображаются в Windows Explorer, для Acer Iconiatab Вкладки вкладки в Android 4 с поддержкой библиотеки (ActionBarSherlock) Изменить конфигурацию Как избавиться от белой полосы в верхней части экрана с помощью adjustResize

Android: CursorLoader сбой на не верхнем фрагменте

У меня есть несколько ListFragments, которые используют CursorLoader для извлечения их содержимого. По мере того, как пользователь перебирает содержимое, один фрагмент заменяет другой (активность остается прежней). Но если контент изменяется на не-верхнем фрагменте, приложение вылетает:

E/AndroidRuntime(18830): FATAL EXCEPTION: main E/AndroidRuntime(18830): java.lang.RuntimeException: Unable to resume activity {com.example.ExampleApp/com.example.ExampleApp.ExampleActivity}: java.lang.IllegalStateException: Content view not yet created E/AndroidRuntime(18830): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2120) E/AndroidRuntime(18830): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2135) E/AndroidRuntime(18830): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:957) E/AndroidRuntime(18830): at android.os.Handler.dispatchMessage(Handler.java:99) E/AndroidRuntime(18830): at android.os.Looper.loop(Looper.java:130) E/AndroidRuntime(18830): at android.app.ActivityThread.main(ActivityThread.java:3683) E/AndroidRuntime(18830): at java.lang.reflect.Method.invokeNative(Native Method) E/AndroidRuntime(18830): at java.lang.reflect.Method.invoke(Method.java:507) E/AndroidRuntime(18830): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) E/AndroidRuntime(18830): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) E/AndroidRuntime(18830): at dalvik.system.NativeStart.main(Native Method) E/AndroidRuntime(18830): Caused by: java.lang.IllegalStateException: Content view not yet created E/AndroidRuntime(18830): at android.support.v4.app.ListFragment.ensureList(ListFragment.java:328) E/AndroidRuntime(18830): at android.support.v4.app.ListFragment.setListShown(ListFragment.java:280) E/AndroidRuntime(18830): at android.support.v4.app.ListFragment.setListShownNoAnimation(ListFragment.java:266) E/AndroidRuntime(18830): at com.example.ExampleApp.FirstListFragment.onLoadFinished(FirstListFragment.java:102) E/AndroidRuntime(18830): at com.example.ExampleApp.FristListFragment.onLoadFinished(FirstListFragment.java:20) E/AndroidRuntime(18830): at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:414) E/AndroidRuntime(18830): at android.support.v4.app.LoaderManagerImpl$LoaderInfo.reportStart(LoaderManager.java:298) E/AndroidRuntime(18830): at android.support.v4.app.LoaderManagerImpl.doReportStart(LoaderManager.java:751) E/AndroidRuntime(18830): at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:512) E/AndroidRuntime(18830): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1129) E/AndroidRuntime(18830): at android.app.Activity.performStart(Activity.java:3791) E/AndroidRuntime(18830): at android.app.Activity.performRestart(Activity.java:3821) E/AndroidRuntime(18830): at android.app.Activity.performResume(Activity.java:3826) E/AndroidRuntime(18830): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2110) E/AndroidRuntime(18830): ... 10 more 

Это может произойти, когда фоновое обновление изменяет содержимое или когда пользователь возвращается с главного экрана, а другой фрагмент находится в верхней части заднего стека. Обработчик onLoadFinished пытается обновить пользовательский интерфейс, который больше не существует. Но почему фрагмент все еще получает обновления курсора?

Я работал над этим, прервав обновление, если фрагмент не виден, но это кажется неправильным.

Вот как выглядит мой Фрагмент, немного отредактированный для краткости:

 public class FirstListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Initialize empty cursor adapter. mAdapter = new ExampleCursorAdapter(getActivity(), null, 0); setListAdapter(mAdapter); // Start with a progress indicator setListShown(false); // Prepare the loader. Either re-connect with an existing one, or start a new one. getLoaderManager().initLoader(EXAMPLE_LOADER_ID, null, this); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new CursorLoader(getActivity(), ExampleProvider.CONTENT_URI, PROJECTION, null, null, null); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // Do nothing if we're not visible. if(!isVisible()) { return; } // Swap the new cursor in. (The framework will take care of closing the // old cursor once we return.) mAdapter.swapCursor(data); // The list should now be shown. if(isResumed()) { setListShown(true); } else { setListShownNoAnimation(true); } } @Override public void onLoaderReset(Loader<Cursor> loader) { // This is called when the last Cursor provided to onLoadFinished() above is about to be // closed. We need to make sure we are no longer using it. mAdapter.swapCursor(null); } } 

isVisible() предотвращает крах, но это ни в одном из примеров кода, который я видел. Что здесь не так?


Edit: Конечно же, я закончил с StaleDataException старым представлением, пытаясь использовать закрытый курсор. Итак, теперь я уничтожаю LoaderManager, когда представление уничтожено. Все еще не уверен, что это правильно, и я не могу воспроизвести исключение StaleDataException.

Я удалил isVisible() взломать сверху и добавил:

 @Override public void onDestroyView() { super.onDestroyView(); // The CursorLoader example doesn't do this, but if we get an update while the UI is // destroyed, it will crash. Why is this necessary? getLoaderManager().destroyLoader(EXAMPLE_LOADER_ID); } 

Solutions Collecting From Web of "Android: CursorLoader сбой на не верхнем фрагменте"

Кажется, это проблема с фрагментами списка, получающими представление списка. По какой-то причине getListView () не вернет действительный вид, если только фрагмент не показывается. Я видел, как он бросает незаконное государственное исключение на что-либо в жизненном цикле перед onStart ().

То, как я решаю проблему, я вызываю загрузчика в методе onCreateView (). Когда загрузчик возвращается с данными, я проверяю, запускается ли действие. Если это так, я загружаю его в представление списка, если не храню его в локальной переменной, а затем загружаю данные в метод onStart ().

Это похоже на супер-хак, но он работает.