我有一个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的生命周期方法......那是怎么回事?
答案 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,我根据布尔值完成了我的工作。