2011-07-07 101 views
1

我有一個singleInstance Activity和一個片段,我在onCreate()方法中實例化,並將其添加到一個FrameLayout容器中放入活動的佈局中。該活動除了打印日誌外不做任何事情。 我正在使用android-support-v4 lib和android 2.3.3。單個實例活動的Android片段生命週期

我觀察到一個奇怪的生命週期行爲與此設置,我不知道你是否可以幫我解釋這一點。我將提供日誌的生命週期:

活動的第一次調用:

07-07 15:12:17.990 V/FragActivity(2358): onCreate >> [email protected] 
    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 > [email protected] 
    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 > [email protected] 
    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()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 > [email protected] 
    07-07 15:13:23.231 V/FragActivity(2358): onPause < 
    07-07 15:13:23.231 V/FragActivity(2358): onNewIntent > [email protected] 
    07-07 15:13:26.231 V/FragActivity(2358): onNewIntent < 
    07-07 15:13:26.231 V/FragActivity(2358): onResume > [email protected] 
    07-07 15:13:29.230 V/FragActivity(2358): onResume < 

第二個問題:爲什麼片段的onResume()方法不被調用?它仍然可以在屏幕上看到。據我瞭解活動和生命週期方法應當齊頭並進......

後,我重新啓動活動第二次:

07-07 15:13:42.140 V/FragActivity(2358): onPause > [email protected] 
    07-07 15:13:45.143 V/FragActivity(2358): onPause < 
    07-07 15:13:45.143 V/FragActivity(2358): onNewIntent > [email protected] 
    07-07 15:13:48.144 V/FragActivity(2358): onNewIntent < 
    07-07 15:13:48.150 V/FragActivity(2358): onResume > [email protected] 
    07-07 15:13:51.151 V/FragActivity(2358): onResume < 

現在fragmen的生命週期方法不會被觸發,在所有.. 那個怎麼樣?

回答

3

我無法回答問題1,儘管我也注意到了這種行爲,但我很少在我的onStop方法中做很多工作(我贊成onPause和onResume),我可以幫你解決第二個問題。

這裏的問題(這肯定是一個谷歌的bug)是FragmentActivity或整個Activity生命週期的問題(取決於你如何看待它)。

基本上,FragmentActivity將其片段移動到恢復狀態,而不是在onResume方法(正如一般人理智的人可能會想到的)中,而是在onPostResume方法中。這一切都很好,除了當onNewIntent調用活動時,onPostResume方法永遠不會在singleIntstance/singleTask活動中調用。

所以我沒有(已導入的支持包代碼,而不是僅僅罐子)爲修改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%確定這是爲什麼,但這是我在測試中注意到的。

希望這有助於:)

+1

您的我的英雄:)我認爲值得一提的是,您不必將源代碼導入到您的項目中,因爲所需成員的可見性被設置爲默認值。只需在你的src和一個擴展FragmentActivity的類中創建一個android.support.v4.app包。這足以提供對mResumed和mFragments的訪問。 – dskinner

0

這使我相關的發現 -

我有一個從XML標籤膨脹的片段。在運行3.2.1的Xoom上,事情按預期工作。在運行3.1的Galaxy 10.1上,該片段的onResume方法爲,從未稱爲。看起來可能已經在3.2中添加了修復程序。

0

我只想添加到Geoff的評論,在我的具體情況下,當onNewIntent被觸發時,我重新創建了一組嵌套片段,並且爲了成功工作,我設置了一個類成員mShouldUpdateFragments,在onNewIntent中設置它爲true,並重寫onPostResume,我根據布爾值完成了我的工作。

+0

人工智能,你應該忽視這一點,因爲這不適用於所有的Android版本 – dskinner

+0

我得到一個完全不同的日誌信息出於某種原因.... http://stackoverflow.com/questions/11104727/so-why-does-我的日誌 - 信息 - 顯示 - 完全-錯誤的行爲之間的活動,fragm – Maxrunner