单实例Activity的Android Fragment生命周期

标签 android lifecycle android-fragments fragment

我有一个 singleInstance Activity 和一个 Fragment,我在 onCreate() 方法中实例化它们并将其添加到 FrameLayout 容器中并添加到 Activity 的布局中。该 Activity 除了打印日志外什么都不做。 我正在使用 android-support-v4 库和 android 2.3.3。

我观察到此设置的一个奇怪的生命周期行为,我想知道你是否可以帮我解释一下。我将提供生命周期的日志:

Activity 的第一次调用:

    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()方法是? fragment 在屏幕上显示正常。

之后,我通过触发 Intent 重新启动 Activity ,导致 Activity 的 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 <

第二个问题:为什么fragment的onResume()方法没有被调用?它仍然在屏幕上可见。据我所知, Activity 和生命周期方法应该齐头并进......

之后我第二次重新启动 Activity :

    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 的生命周期方法根本没有被触发..这是怎么回事?

最佳答案

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

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

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

所以我所做的(导入了支持包代码,而不仅仅是 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(),因为这会导致 fragment onResume 方法在这种情况下被调用两次。我不是 100% 确定为什么会这样,但这是我在测试中注意到的。

希望这有帮助:)

关于单实例Activity的Android Fragment生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6611504/

相关文章:

Android AES 加密在 Cipher.doFinal 之后丢失字节

android - AppCompat v7 : Should I use Framework FragmentManager or SupportFragmentManager?

android - 作为 ViewPager 的一部分更新 ListFragment 中的数据

java - 关于 while 循环的问题

javascript - Android - 使用 webview 加载 URL 后,我可以更改背景颜色吗

android - 最近更新后 react-native run-ios 失败

Node.JS:不保持进程运行的setTimeout

android - Activity 的 onResume() 会永远运行吗?

angular - 第一次加载页面时调用 ngOnDestroy

android - 更改方向调用 onpageselected 在 oncreateview 之前