1

我有一个 singleInstance Activity 和一个 Fragment,我在 onCreate() 方法中对其进行了实例化,并将其添加到 FrameLayout 容器中到 Activity 的布局中。该活动除了打印日志之外什么都不做。我正在使用 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 <

第一个问题:为什么在创建activity时fragment的onStop()方法?片段在屏幕上显示良好。

之后,我通过触发意图重新启动活动,从而导致活动的 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 <

第二个问题:为什么没有调用fragment的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 <

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

4

3 回答 3

3

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

这里的问题(这绝对是一个谷歌错误)要么是 FragmentActivity 的问题,要么是整个 Activity 生命周期的问题(取决于你如何看待它)。

基本上,FragmentActivity 将其片段移动到恢复状态,而不是在 onResume 方法中(通常是理智的人可能会认为),而是在 onPostResume 方法中。这一切都很好,除了 onPostResume 方法永远不会在使用 onNewIntent 调用活动时在 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% 确定为什么会这样,但这是我在测试中注意到的。

希望这可以帮助 :)

于 2011-07-12T00:56:08.123 回答
0

这让我有了一个相关的发现——

我有一个从 xml 标签膨胀的片段。在运行 3.2.1 的 Xoom 上,一切正常。在运行 3.1 的 Galaxy 10.1 上,从不调用片段的 onResume 方法。看起来修复程序可能已在 3.2 中添加。

于 2011-12-05T23:30:28.690 回答
0

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

于 2012-05-10T19:51:26.867 回答