Android片段单实例活动的生命周期

时间:2011-07-07 13:38:43

标签: android lifecycle android-fragments fragment

我有一个singleInstance Activity和一个Fragment,我在onCreate()方法中实例化,并将FrameLayout容器添加到活动的布局中。除打印日志外,该活动不执行任何操作。 我使用的是android-support-v4 lib和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()方法?片段在屏幕上显示正常。

之后,我通过触发intent重新启动活动,从而导致活动的onNewIntent()lidecycle方法。

    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 <

现在根本没有触发fragmen的生命周期方法......那是怎么回事?

3 个答案:

答案 0 :(得分:3)

我无法回答问题1,虽然我也注意到了这种行为,但我很少在onStop方法中做很多工作(我赞成onPause和onResume),我可以帮你解决第二个问题。

这里的问题(肯定是谷歌的bug)要么是FragmentActivity的问题,要么是整个Activity的生命周期(取决于你如何看待它)。

基本上,FragmentActivity将其片段移动到恢复状态,而不是onResume方法(通常是一个理智的人可能认为),而是在onPostResume方法中。这一切都很好,除了在使用onNewIntent调用活动时,onPostResume方法永远不会在singleIntstance / singleTask活动中被调用。

所以我所做的(导入了支持包代码,而不仅仅是jar)就像修改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;
}

请注意,我不只是在onNewIntent中调用mFragments.dispatchResume(),因为这会导致片段onResume方法在这种情况下被调用两次。我不是100%确定为什么会这样,但这是我在测试中注意到的。

希望这会有所帮助:)

答案 1 :(得分:0)

这让我得到了一个相关的发现 -

我有一个从xml标签中膨胀的片段。在运行3.2.1的Xoom上,事情按预期工作。在运行3.1的Galaxy 10.1上,片段的onResume方法从不被称为。看起来可能已在3.2中添加了修复程序。

答案 2 :(得分:0)

我只想添加Geoff的注释,在我的特定情况下,当onNewIntent被触发时我正在重新创建一组嵌套片段,并且为了成功工作,我设置了一个类成员mShouldUpdateFragments,在onNewIntent中将其设置为true,并且覆盖onPostResume,我根据布尔值完成了我的工作。