Activity启动模式相关

1,240 阅读7分钟

源码基于Android 8.1

Launcher.java

public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
    ...
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    ...
    try {
        if (Utilities.ATLEAST_MARSHMALLOW
                && (item instanceof ShortcutInfo)
                && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
                    || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
                && !((ShortcutInfo) item).isPromise()) {
            // Shortcuts need some special checks due to legacy reasons.
            startShortcutIntentSafely(intent, optsBundle, item);
        } else if (user == null || user.equals(Process.myUserHandle())) {
            // start
            startActivity(intent, optsBundle);
        } else {
            LauncherAppsCompat.getInstance(this).startActivityForProfile(
                    intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
        }
        return true;
    } catch (ActivityNotFoundException|SecurityException e) {
        Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
        Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
    }
}

Activity.java

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                
                mStartedActivity = true;
            }
        } else {
            ...
        }
    }

主要是调用Instrumentation里面的execStartActivity,就是通过AMS调用到startActivity。

ActivityManagerService.java

public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

------
  
  public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        //caller不为空,callingUid为-1,
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
    }

ActivityStarter.java

final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult,
            Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            TaskRecord inTask, String reason) {
    boolean componentSpecified = intent.getComponent() != null;
    intent = new Intent(intent);
    //
    ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
    ...
    int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
                    reason);
}

-----------
  
int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
        String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
        String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
        ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
        ActivityRecord[] outActivity, TaskRecord inTask, String reason) {

    ...
    mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
            aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
            callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
            options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
            inTask);

    ...
}
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
        String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
        String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
        ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
        ActivityRecord[] outActivity, TaskRecord inTask) {
  
    //如果启动的是HomeActivity,那么此时caller是为null的,callingUid依旧为0
    //正常启动时不会为null的
    if (caller != null) {
        //获取启动目标Activity的源Activity线程的ProcessRecord
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            //获得pid和uid
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }
  
    ...
    ActivityRecord sourceRecord = null;
    ActivityRecord resultRecord = null;
    //启动HomeActivity的时候resultTo为空,所以sourceRecord也会是null
    //此时该值为前面传入的token
    if (resultTo != null) {
        //通过这个token去遍历stack里面获取ActivityRecord
        sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
        ...
        if (sourceRecord != null) {
            //正常startActivity过来的requestCode为-1
            if (requestCode >= 0 && !sourceRecord.finishing) {
                resultRecord = sourceRecord;
            }
        }
    }
    ...
    //创建ActivityRecord
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, options, sourceRecord);
    ...
    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
}
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {
    ...
    result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, outActivity);
    
    ...
    return result;
}
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {
        //初始化配置,mStartActivity、mLaunchMode等
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor);
        //计算mLaunchFlags,具体可以看标记1
        computeLaunchingTaskFlags();
        //计算源Activity所在的Stack
        computeSourceStack();
        //将mLaunchFlags设置给Intent
        mIntent.setFlags(mLaunchFlags);
        //寻找是否可重用的Task,返回栈顶的ActivityRecord,标记2
        ActivityRecord reusedActivity = getReusableIntentActivity();
        ...
        //根据getReusableIntentActivity方法判断,Standard和SingleTop的启动模式
        //是不会到这个判断里面的
        if (reusedActivity != null) {
            ...
            //将目标Activity的Task设置为重用的Task
            if (mStartActivity.getTask() == null) {
                mStartActivity.setTask(reusedActivity.getTask());
            }
 
            if (reusedActivity.getTask().intent == null) {
                reusedActivity.getTask().setIntent(mStartActivity);
            }
          
            //如果启动模式是SingleInstance、SingleTask或者设置了FLAG_ACTIVITY_CLEAR_TOP
            if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                    || isDocumentLaunchesIntoExisting(mLaunchFlags)
                    || mLaunchSingleInstance || mLaunchSingleTask) {
                //获取重用的Task
                final TaskRecord task = reusedActivity.getTask();
                //遍历该Task,寻找是否存在一个Activity等于目标Activity
                //存在则将该Activity上面的所有Activity都finish掉
                //如果找到的Activity是标准模式启动的,则把找到的Activity也finish了,返回null
                //不然就返回该找到的Activity
                //该Task内不存在目标Activity,也返回null 
                final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
                        mLaunchFlags);

                if (reusedActivity.getTask() == null) {
                    reusedActivity.setTask(task);
                }

            	//这边主要是判断了不为null的情况,下面setTaskFromIntentActivity方法内
            	//会判断top为null的情况处理
                if (top != null) {
                    if (top.frontOfTask) {
                        top.getTask().setIntent(mStartActivity);
                    }
                  	//会一直调用到onNewIntent
                    deliverNewIntent(top);
                }
            }
            ...
            //将重用的Task移到ActivityStack前台
            reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
            ...
            //标记3
            setTaskFromIntentActivity(reusedActivity);
            if (!mAddingToTask && mReuseTask == null) {
               //表示可以复用Activity,并且Task也没有被清空
                resumeTargetStackIfNeeded();
                if (outActivity != null && outActivity.length > 0) {
                    outActivity[0] = reusedActivity;
                }

                return START_TASK_TO_FRONT;
            }
        }
        ...
        //顶部的Activity和目标Activity是不是一样的
        final ActivityStack topStack = mSupervisor.mFocusedStack;
        final ActivityRecord topFocused = topStack.topActivity();
        final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
        final boolean dontStart = top != null && mStartActivity.resultTo == null
                && top.realActivity.equals(mStartActivity.realActivity)
                && top.userId == mStartActivity.userId
                && top.app != null && top.app.thread != null
                && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
                || mLaunchSingleTop || mLaunchSingleTask);
  		if (dontStart) {
        		topStack.mLastPausedActivity = null;
            if (mDoResume) {
                mSupervisor.resumeFocusedStackTopActivityLocked();
            }
            ...
            deliverNewIntent(top);
            ...

            return START_DELIVERED_TO_TOP;
        }
        ...
        //下面判断是在没有找到复用的Task的情况下或者是在上面没有处理好的,比如top == null的时候
        //指定了FLAG_ACTIVITY_NEW_TASK
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            //标记4
            result = setTaskFromReuseOrCreateNewTask(
                    taskToAffiliate, preferredLaunchStackId, topStack);
        } else if (mSourceRecord != null) {
            //设置与源Activity一样的Task和Stack
            result = setTaskFromSourceRecord();
        } else if (mInTask != null) {
            //指定了Task中启动的时候会带这里
            result = setTaskFromInTask();
        } else {
            setTaskToCurrentTopOrCreateNewTask();
        }
}

startActivityUnchecked方法内主要就是处理了启动模式相关的操作,设置目标Activity的Stack和Task。

标记1:computeLaunchingTaskFlags

private void computeLaunchingTaskFlags() {
  ...
  //判断是在什么情况下需要自动加上FLAG_ACTIVITY_NEW_TASK标志
  if (mInTask == null) {
        if (mSourceRecord == null) {
            // 表示没有源Activity的时候,就需要启动一个新的Task
            if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
                Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
                            "Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);
                mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
            }
        } else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
            // 表示源Activity的启动模式为SingleInstance,这时候需要启动一个新的Task
            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
        } else if (mLaunchSingleInstance || mLaunchSingleTask) {
            // 当此时的Activity的启动模式设置为SingleInstance或者是SingleTask
             // 需要启动一个新的Task
            mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
        }
    }
}

标记2:getReusableIntentActivity

//获取可以复用的Task
private ActivityRecord getReusableIntentActivity() {
    //排除了standard和singleTop这两种启动模式
    boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
            (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
            || mLaunchSingleInstance || mLaunchSingleTask;
    
    putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
    ActivityRecord intentActivity = null;
  	//当准确知道目标Activity会具体在哪个Task内,getLaunchTaskId不会为-1
    if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
        final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
        intentActivity = task != null ? task.getTopActivity() : null;
    } else if (putIntoExistingTask) {
        if (mLaunchSingleInstance) {
            //SingleInstance,搜索所有的stack以及从栈顶到底遍历task去寻找对应的Activity
            //找不到返回null
            //主要比较的是Intent的Action、Data、Type、Categories、Package、Component
            //或者是Component,根据findActivityLocked最后一个参数判断
            intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
                   mStartActivity.isHomeActivity());
        } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
            //分屏相关
            intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
                    !mLaunchSingleTask);
        } else {
            //遍历每个stack里面的Task,task.getTopActivity获取栈顶的Activity
            //主要比较的是这个目标Activity的Intent的ComponentName和Task的Intent的ComponentName  
            //以及他们的TaskAffinity,所以得到一个复用的Task,返回复用Task栈顶的ActivityRecord
            intentActivity = mSupervisor.findTaskLocked(mStartActivity, mSourceDisplayId);
        }
    }
    return intentActivity;
}

标记3:setTaskFromIntentActivity

private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
        if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) {
            //获取重用的Task
            final TaskRecord task = intentActivity.getTask();
            //清除该Task内的所有Activity
            task.performClearTaskLocked();
            //对Task重新赋值
            mReuseTask = task;
            mReuseTask.setIntent(mStartActivity);

            mMovedOtherTask = true;
        } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                || mLaunchSingleInstance || mLaunchSingleTask) {
            //清除目标Activity在Task中对应位置上面的所有Activity
            //跟上面的处理的是一样的
            ActivityRecord top = intentActivity.getTask().performClearTaskLocked(mStartActivity,
                    mLaunchFlags);
            if (top == null) {
                
                mAddingToTask = true;
              	//把目标Activity的Task设置为null,后面需重新计算该Activity需要放置的Task
                mStartActivity.setTask(null);
                
                mSourceRecord = intentActivity;
                final TaskRecord task = mSourceRecord.getTask();
                if (task != null && task.getStack() == null) {
                    
                    mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
                            null /* bounds */, mLaunchFlags, mOptions);
                    mTargetStack.addTask(task,
                            !mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
                }
            }
        } else if (mStartActivity.realActivity.equals(intentActivity.getTask().realActivity)) {
            //如果重用的Activity和目标的Activity一样,并且是SingleTop的情况下
            if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 || mLaunchSingleTop)
                    && intentActivity.realActivity.equals(mStartActivity.realActivity)) {
                if (intentActivity.frontOfTask) {
                    intentActivity.getTask().setIntent(mStartActivity);
                }
              	//onNewIntent
                deliverNewIntent(intentActivity);
            } else if (!intentActivity.getTask().isSameIntentFilter(mStartActivity)) {
                //Task的Intent和目标Activity的Intent不同
                //表示不能复用Activity
                mAddingToTask = true;
                mSourceRecord = intentActivity;
            }
        } else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
            
            mAddingToTask = true;
            mSourceRecord = intentActivity;
        } else if (!intentActivity.getTask().rootWasReset) {
            
            intentActivity.getTask().setIntent(mStartActivity);
        }
}

标记4:setTaskFromReuseOrCreateNewTask

private int setTaskFromReuseOrCreateNewTask(
            TaskRecord taskToAffiliate, int preferredLaunchStackId, ActivityStack topStack) {
    //主要是获取或创建ActivityStack,具体操作如下:
    //1.如果mReuseTask不为空则直接使用该Task对应的ActivityStack
    //注:mReuseTask在清除Task所有Activity的时候进行了赋值以及指定了mInTask的时候
    //2.根据目标Activity的类型获取对应的ActivityStack
    //3.前台ActivityStack不为空,并且该Stack的顶部的Task等于目标Activity的Task,则返回前台ActivityStack
    //4.判断目标Activity对应的Task所在的ActivityStack是否存在
    //5.遍历当前屏幕下的所有ActivityStack,如果是动态创建的Stack,则返回
    //6.最终创建一个ActivityStack
    mTargetStack = computeStackFocus(
                mStartActivity, true, mLaunchBounds, mLaunchFlags, mOptions)
    if (mReuseTask == null) {
        //通过ActivityStack新建TaskRecord
        //加入到TaskHistory
        final TaskRecord task = mTargetStack.createTaskRecord(
                    mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
                    mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
                    mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
                    mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity.mActivityType);
        //将目标Activity添加到该Task顶部
        addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
        ...
    } else {
        addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
    }
    ...
    if (mDoResume) {
        //移动到前台
        mTargetStack.moveToFront("reuseOrNewTask");
    }
}