1. 程式人生 > >Android中的intent flag

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效果相同