Android中的intent flag
1,Intent.FLAG_ACTIVITY_NEW_TASK
在Service中呼叫startActivity和在BroadcastReceiver(靜態註冊)中通過onReceive傳遞過來的context.startActivity時(該context型別為ReceiverRestrictedContext,和Service一樣,都沒有重寫startActivity),如果不加FLAG_ACTIVITY_NEW_TASK的話會報如下錯誤的
AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag
@Override public void startActivity(Intent intent, Bundle options) { warnIfCallingFromSystemProcess(); if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { throw new AndroidRuntimeException( "Calling startActivity() from outside of an Activity " + " context requires the FLAG_ACTIVITY_NEW_TASK flag." + " Is this really what you want?"); } mMainThread.getInstrumentation().execStartActivity( getOuterContext(), mMainThread.getApplicationThread(), null, (Activity) null, intent, -1, options); }
注意看上面的這段程式碼:if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0)
為什麼在Activity中不加FLAG_ACTIVITY_NEW_TASK呼叫startActivity時不會報錯呢。原因是因為Activity重寫了ContextWrapper中的startActivity方法
@Override public void startActivity(Intent intent) { this.startActivity(intent, null); } @Override public void startActivity(Intent intent, @Nullable Bundle options) { if (options != null) { startActivityForResult(intent, -1, options); } else { // Note we want to go through this call for compatibility with // applications that may have overridden the method. startActivityForResult(intent, -1); } } public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) { Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); }
可以發現,裡面是沒有加FLAG_ACTIVITY_NEW_TASK判斷的
當Intent物件包含這個標記時,系統會尋找或建立一個新的task來放置目標Activity,尋找時依據目標Activity的taskAffinity屬性進行匹配,如果找到一個task的taskAffinity與之相同,就將目標Activity壓入此task中,如果查詢無果,則建立一個新的task,並將該task的taskAffinity設定為目標Activity的taskActivity,將目標Activity放置於此task。注意,如果同一個應用中Activity的taskAffinity都使用預設值或都設定相同值時,應用內的Activity之間的跳轉使用這個標記是沒有意義的,因為當前應用task就是目標Activity最好的宿主
FLAG_ACTIVITY_NEW_TASK應該這樣去理解:根據Activity Affinity判斷是否需要建立新的Task,然後再建立新的Activit例項放進去
FLAG_ACTIVITY_CLEAR_TOP :此時效果與Activity啟動模式中的singleTask相同
FLAG_ACTIVITY_SINGLE_TOP:與Activity啟動模式中的singleTop效果相同