Жизненный цикл Android-фрагмента активности одного экземпляра

У меня есть действие singleInstance и фрагмент, который я создаю в методе onCreate() и добавляю в контейнер FrameLayout в макет действия. Действие ничего не делает, кроме распечатки журналов. Я использую библиотеку android-support-v4 и Android 2.3.3.

Я наблюдал странное поведение жизненного цикла с этим параметром, и мне интересно, не могли бы вы помочь мне объяснить это. Я предоставлю журналы для жизненных циклов:

Первый вызов активности:

    07-07 15:12:17.990 V/FragActivity( 2358): onCreate >> com.test.fragmentlife.FragActivity@44f98778
    07-07 15:12:21.010 V/FragActivity( 2358): onCreate <<
    07-07 15:12:21.020 V/LayoutFragment( 2358): onAttach > LayoutFragment{44f467c8 #0 id=0x7f070000}
    07-07 15:12:24.021 V/LayoutFragment( 2358): onAttach <
    07-07 15:12:24.021 V/LayoutFragment( 2358): onCreate > LayoutFragment{44f467c8 #0 id=0x7f070000}
    07-07 15:12:27.020 V/LayoutFragment( 2358): onCreate <
    07-07 15:12:27.020 V/LayoutFragment( 2358): onCreateView > LayoutFragment{44f467c8 #0 id=0x7f070000}
    07-07 15:12:30.022 V/LayoutFragment( 2358): onCreateView <
    07-07 15:12:30.030 V/LayoutFragment( 2358): onActivityCreated > LayoutFragment{44f467c8 #0 id=0x7f070000}
    07-07 15:12:33.030 V/LayoutFragment( 2358): onActivityCreated <
    07-07 15:12:33.030 V/LayoutFragment( 2358): onStart > LayoutFragment{44f467c8 #0 id=0x7f070000}
    07-07 15:12:36.030 V/LayoutFragment( 2358): onStart <
    07-07 15:12:36.040 V/FragActivity( 2358): onStart > com.test.fragmentlife.FragActivity@44f98778
    07-07 15:12:39.041 V/FragActivity( 2358): onStart <
    07-07 15:12:39.041 V/LayoutFragment( 2358): onStop > LayoutFragment{44f467c8 #0 id=0x7f070000}
    07-07 15:12:42.040 V/LayoutFragment( 2358): onStop <
    07-07 15:12:42.040 V/FragActivity( 2358): onResume > com.test.fragmentlife.FragActivity@44f98778
    07-07 15:12:45.041 V/FragActivity( 2358): onResume <
    07-07 15:12:45.041 V/LayoutFragment( 2358): onStart > LayoutFragment{44f467c8 #0 id=0x7f070000}
    07-07 15:12:48.040 V/LayoutFragment( 2358): onStart <
    07-07 15:12:48.040 V/LayoutFragment( 2358): onResume > LayoutFragment{44f467c8 #0 id=0x7f070000}
    07-07 15:12:51.042 V/LayoutFragment( 2358): onResume <

Первый вопрос: почему метод onStop() фрагмента при создании активности? Фрагмент отлично отображается на экране.

После этого я перезапускаю действие, запуская намерение, вызывая метод лидецикла onNewIntent() действия.

    07-07 15:13:17.220 V/LayoutFragment( 2358): onPause > LayoutFragment{44f467c8 #0 id=0x7f070000}
    07-07 15:13:20.220 V/LayoutFragment( 2358): onPause <
    07-07 15:13:20.230 V/FragActivity( 2358): onPause > com.test.fragmentlife.FragActivity@44f98778
    07-07 15:13:23.231 V/FragActivity( 2358): onPause <
    07-07 15:13:23.231 V/FragActivity( 2358): onNewIntent > com.test.fragmentlife.FragActivity@44f98778
    07-07 15:13:26.231 V/FragActivity( 2358): onNewIntent <
    07-07 15:13:26.231 V/FragActivity( 2358): onResume > com.test.fragmentlife.FragActivity@44f98778
    07-07 15:13:29.230 V/FragActivity( 2358): onResume <

Второй вопрос: почему не вызывается метод onResume() фрагмента? Его до сих пор видно на экране. Насколько я знаю, методы деятельности и жизненного цикла должны идти рука об руку...

После этого я перезапускаю активность во второй раз:

    07-07 15:13:42.140 V/FragActivity( 2358): onPause > com.test.fragmentlife.FragActivity@44f98778
    07-07 15:13:45.143 V/FragActivity( 2358): onPause <
    07-07 15:13:45.143 V/FragActivity( 2358): onNewIntent > com.test.fragmentlife.FragActivity@44f98778
    07-07 15:13:48.144 V/FragActivity( 2358): onNewIntent <
    07-07 15:13:48.150 V/FragActivity( 2358): onResume > com.test.fragmentlife.FragActivity@44f98778
    07-07 15:13:51.151 V/FragActivity( 2358): onResume <

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


person Fabian    schedule 07.07.2011    source источник


Ответы (3)


Я не могу ответить на вопрос 1, хотя я тоже заметил такое поведение, но я редко много работаю в своих методах onStop (я предпочитаю onPause и onResume), я могу помочь с вашим вторым вопросом.

Проблема здесь (которая определенно является ошибкой Google) связана либо с FragmentActivity, либо с жизненным циклом Activity в целом (в зависимости от того, как вы на это смотрите).

По сути, FragmentActivity переводит свои фрагменты в возобновленное состояние не в методе onResume (как мог бы подумать в целом здравомыслящий человек), а в методе onPostResume. Это все хорошо, за исключением того, что метод onPostResume никогда не вызывается в действии singleIntstance/singleTask, когда действие вызывается с помощью onNewIntent.

Итак, что я сделал (импортировав код пакета поддержки, а не только банку), изменил FragmentActivity вот так...

//this boolean is only ever set to true in onNewIntent
private boolean mResumeNeedsToDoDispatch = false; 

/**
 * Ensure any outstanding fragment transactions have been committed.
 */
@Override
protected void onResume() {
    super.onResume();
    mResumed = true;

    //Check if onNewIntent was called. If so, dispatch resumes to fragments now
    if (mResumeNeedsToDoDispatch) {
        mResumeNeedsToDoDispatch = false;
        mFragments.dispatchResume();
    }

    mFragments.execPendingActions();
}


/**
 * Google, I think you forgot this #(
 */
@Override
public void onNewIntent(Intent newIntent) {
    super.onNewIntent(newIntent);
    mResumeNeedsToDoDispatch = true;
}

Обратите внимание, что я не просто вызвал mFragments.dispatchResume() в onNewIntent, потому что в этом случае методы фрагмента onResume вызываются дважды. Я не уверен на 100%, почему это так, но это то, что я заметил в своих тестах.

Надеюсь это поможет :)

person Geoff    schedule 12.07.2011
comment
Ваш мой герой :) Я думаю, стоит упомянуть, что вам не нужно импортировать исходники в ваш проект, так как видимость необходимых участников установлена ​​по умолчанию. Просто создайте пакет android.support.v4.app в своем src и класс, расширяющий FragmentActivity. Этого будет достаточно, чтобы предоставить доступ к mResumed и mFragments. - person dskinner; 30.05.2012

Это привело меня к родственному открытию —

У меня есть фрагмент, который накачивается из тега xml. На Xoom с версией 3.2.1 все работает как положено. На Galaxy 10.1 с версией 3.1 метод фрагмента onResume никогда не вызывается. Похоже, исправление могло быть добавлено в 3.2.

person dokkaebi    schedule 05.12.2011

Я просто хочу добавить к комментарию Джеффа: в моем конкретном случае я воссоздавал набор вложенных фрагментов при запуске onNewIntent, и для его успешной работы я устанавливаю член класса mShouldUpdateFragments, устанавливая его true в onNewIntent и переопределяя onPostResume, где Я сделал свою работу на основе логического значения.

person dskinner    schedule 10.05.2012
comment
ppl, вы должны игнорировать это, так как это не работает на всех версиях Android. - person dskinner; 30.05.2012
comment
по какой-то причине я получаю совершенно другую информацию журнала.... stackoverflow.com/questions/11104727/ - person Maxrunner; 19.06.2012