一、問題描述
如标題所述,最近被重複執行個體化launcher activity這個問題搞得很慘,這個問題有哪些表現呢?如下:
- 在package installers 安裝界面安裝完一個應用後,直接打開app,然後進入了 Activity_1, 此時再通過此activity用startActivity(intent)的方法打開 Activity_2.
- 然後按home鍵傳回桌面,在桌面點選app圖示進入,你覺得應該進入的是 Activity_2 ,實際上卻是launcher Activity_1 .
- 然而還沒完,這時候你按 back 傳回鍵,會發現傳回到了之前打開的 Activity_2,再按傳回,又出現 launcher**Activity_1**. 也就是說系統重複執行個體化了Activity_1.
- 退出app後再次點選桌面圖示進入,反複試驗,沒有再出現這個問題。也就是說,這個問題(bug ?)隻出現在操作步驟(1)後才會産生.
二、問題原因
我們先看AndroidManifest這個檔案,我們輕而易舉發現,但凡是App入口Activity,那麼一定會包含
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
這幾行代碼。這裡到底有什麼玄機呢?其實這個就是跟桌面約定好的啟動攔截過濾器。因為桌面有一個很明顯的需求就是,如果我們再次點選已經在背景的App圖示時,是應該将該背景任務挪到前台而不是再次啟動該App程式。
但是由于package installers安裝直接打開app的啟動方式與app的啟動方式不一緻導緻點選桌面圖示的時候認為沒有背景任務是以有啟動了一個界面導緻。
三、解決方法
在App第一個啟動界面super.onCreate(…)方法之後插入代碼:
if(!this.isTaskRoot()) {
//判斷該Activity是不是任務空間的源Activity,“非”也就是說是被系統重新執行個體化出來
//如果你就放在launcher Activity中話,這裡可以直接return了
Intent mainIntent=getIntent();
String action=mainIntent.getAction();
if(mainIntent.hasCategory(Intent.CATEGORY_LAUNCHER)
&& action.equals(Intent.ACTION_MAIN)) {
finish();
//finish()之後該活動會繼續執行後面的代碼,你可以logCat驗證,加return避免可能的exception
return;
}
}
四、來源google
https://code.google.com/p/android/issues/detail?id=14262
https://code.google.com/p/android/issues/detail?id=2373#c40