Подтвердить что ты не робот

Пакет совместимости Android - фрагмент... не привязан к деятельности


Здравствуйте, Я столкнулся с этой проблемой: Я использую пакет Compatibility для использования фрагмента в приложении Android (min SDK 2.1).

Случайное исключение иногда возникает в фрагменте, и я не могу понять, почему. Это трассировка стека, которую я получаю:

java.lang.IllegalStateException: Fragment FeedListFragment{438a54e8} not attached to Activity
    at android.support.v4.app.Fragment.getLoaderManager(Fragment.java:715)
    at com.myappli.ui.FeedListFragment.refreshUpdateDate(FeedListFragment.java:283)
    at com.myappli.ui.phone.FeedListActivity.onReceiveResult(FeedListActivity.java:277)
    at com.myappli.data.rssplayer.service.KTDetachableResultReceiver.onReceiveResult(KTDetachableResultReceiver.java:55)
    at android.os.ResultReceiver$MyRunnable.run(ResultReceiver.java:43)
    at android.os.Handler.handleCallback(Handler.java:587)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:4425)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
    at dalvik.system.NativeStart.main(Native Method)

Вот соответствующий код, который я вызываю в классе Fragment:

public class FeedListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor>, FeedListCursorAdapterListener {

...
    public void refreshUpdateDate() {
    getLoaderManager().restartLoader(LAST_UPDATE_CURSOR_ID, null, this);
    }
...
}

Вот код действия, вызывающего фрагмент:

private FeedListFragment mCursorLoaderListFg;

if (!isFinishing()) {
    mCursorLoaderListFg.refreshUpdateDate();
    mCursorLoaderListFg.refreshDisplay();
    mCursorLoaderListFg.hideLoadingArticles();
}

Вот исходный код фрагмента для getLoaderManager():

/**
* Return the LoaderManager for this fragment, creating it if needed.
*/
public LoaderManager getLoaderManager() {
    if (mLoaderManager != null) {
        return mLoaderManager;
    }
    if (mActivity == null) {
        throw new IllegalStateException("Fragment " + this + " not attached to Activity");
    }
    mCheckedForLoaderManager = true;
    mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, true);
    return mLoaderManager;
}

Ниже приведены шаги приложения перед сбоем:

  • Операция вызывает методы в фоновом режиме.
  • Вызов методов обратного вызова
  • В этом методе обратного вызова активность вызывает фрагмент
  • Фрагмент пытается запустить некоторые методы (например, getLoadManager()), которые нуждаются в активности.
  • Фрагмент больше не привязан к action = > crash

Мы попробовали два исправления:

  • проверить активность, чтобы проверить, завершена ли работа (например, код выше)
  • тест на фрагменте с методом isDetached.

Спасибо за помощь!!!

Не стесняйтесь спрашивать меня больше информации, если я не понимаю.

4b9b3361

Ответ 1

У меня была аналогичная проблема.

Попробуйте использовать isAdded() или isVisible() вместо isDetached(). К сожалению, isDetached(), похоже, не работает так, как должно...

Ответ 2

Что сработало для меня, так это использовать прослушиватель фрагментов фрагмента, добавить для него функцию getActivity, которая возвращает активность прослушивателя фрагментов (активность, создавшая фрагмент).

Теперь, когда у меня есть вызов, который нужен для работы, я просто использую эту функцию.

Ответ 3

Я решил эту проблему, изменив свой внутренний класс адаптера на статический внутренний класс.

private static class MessagesAdapter extends CursorAdapter {
...

Я не уверен, как это объяснить, но это связано с тем, что мы должны использовать нестатический внутренний класс, как рекомендовано здесь

Ответ 4

Фрагмент будет прикреплен к действию на мероприятии Fragment.onAttach(Activity). Ваша деятельность должна реализовать слушателя, обеспечивает фрагмент. Чтобы гарантировать, что ваш метод refreshUpdateDate() будет вызываться только после события, onAttach() должен сначала принять действие в качестве реализации прослушивателя, а затем вызвать метод listenent fragmentAttached(). Таким образом, ваша активность будет проинформирована, когда фрагмент присоединен и refreshUpdateDate() может быть вызван, например, direct в fragmentAttached(). См. Создание обратных вызовов событий для действия.