原理解析Android攻城狮Android知识

沉思曲:Activity启动

2017-06-19  本文已影响143人  空同定翁

继上文之后,终于鼓起勇气来整理这篇文章了。说到Acitivity启动,其实是个复杂而艰难的过程,认真去分析这块可以发现很多意外的宝藏。本人才疏学浅,由工作分享所致不得不研究。

本文已代码为主,注释为辅,内容较长,烦请务必认真读完,相信必能有所获。先上图:

代码流程图


Activity启动流程.png

就上图说明几点:

note

源进程


1.1、先从StartActivity说起

public void startActivity(Intent intent) {
    this.startActivity(intent, null);
}

​ 启动Activity传入Intent,Intent携带了src的Context信息,以及dest的Class信息或Action。

public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        //请求码设为-1
        startActivityForResult(intent, -1);
    }
}
public void startActivityForResult(Intent intent, int requestCode) {
    startActivityForResult(intent, requestCode, null);
}
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
    if (mParent == null) {
        //调用execStartActivity方法
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        //发送结果给src
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        if (requestCode >= 0) {
            mStartedActivity = true;
        }

        cancelInputsAndStartExitTransition(options);
    } else {//嵌套Activity逻辑,现已不推荐使用了
        if (options != null) {
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}

startActivity方法还是比较简单:

1.2、execStartActivity | Instrumentation.java

Instrumentation是啥?
1、一个应用与一个Instrumentation关联,该应用的每个Activity都有该Instrumentation的引用。
2、Instrumentation可理解为应用进程的管家,它负责管理应用端四大组件等(见后代码)。

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
  
    //IApplicationThread为Binder,AMS通过它来控制Activity生命周期等
    IApplicationThread whoThread = (IApplicationThread) contextThread;
  
    //查找列表,dest是否已启动,已启动则直接返回结果?
    if (mActivityMonitors != null) {
        synchronized (mSync) {
            final int N = mActivityMonitors.size();
            for (int i=0; i<N; i++) {
                final ActivityMonitor am = mActivityMonitors.get(i);
                if (am.match(who, null, intent)) {
                    am.mHits++;
                    if (am.isBlocking()) {
                        return requestCode >= 0 ? am.getResult() : null;
                    }
                    break;
                }
            }
        }
    }
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess();
        //AIDL调用服务进程AMS的startActivity方法
        int result = ActivityManagerNative.getDefault()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, null, options);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
    }
    return null;
}

为了后续分析方便,这里简要说下源进程与AMS是如何通信的:

源进程与AMS通信

获取AMS Binder代理.png ActivityManagerService类图.png

AMS与源/目的进程通信

之所以加上目的进程,是因为启动的Activity可能与源Activity不在同一个进程中。

ApplicationThread类图.png

AMS进程


2.1、startActivity

源进程调用了AMS的startActivity方法,传入whoThread等参数,该方法在ActivityManagerService.java中。

public final int startActivity(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo,
        String resultWho, int requestCode, int startFlags,
        String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
    //调用startActivityAsUser方法
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode,
            startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
}
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo,
        String resultWho, int requestCode, int startFlags,
        String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
    enforceNotIsolatedCaller("startActivity");
    userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
            false, true, "startActivity", null);
  
    //调用ActivityStackSupervisor的startActivityMayWait方法
    return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
            resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
            null, null, options, userId);
}

2.2、startActivityMayWait

上面方法接着调用到startActivityMayWait,该方法在ActivityStackSupervisor.java中。
往下说之前,先插上一句:
ActivityStackSupervisior从类名可以看出,似乎是负责监督Activity栈的一个类。其实这个类类似于Instrumentation,把它理解为AMS的管家就可以了,只不过一个在源进程一个在AMS进程。

final int startActivityMayWait(IApplicationThread caller, int callingUid,
        String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
        String resultWho, int requestCode, int startFlags, String profileFile,
        ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
        Bundle options, int userId) {
    ...
      
    //备份,避免修改原始intent
    intent = new Intent(intent);

    /**
      * 获取dest信息,判断是否有匹配的Component。
      * 此处AMS通过Binder连接到PMS,由PMS负责Intent的匹配。
      */
    ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
            profileFile, profileFd, userId);

    synchronized (mService) {
        //AIDL通信,获取客户端进程pid等信息
        int callingPid;
        if (callingUid >= 0) {
            callingPid = -1;
        } else if (caller == null) {
            callingPid = Binder.getCallingPid();
            callingUid = Binder.getCallingUid();
        } else {
            callingPid = callingUid = -1;
        }

        //获取处于前台的ActivityStack,即接收输入或正在启动下一Activity的Stack
        final ActivityStack stack = getFocusedStack();
        
        //配置是否发生变化
        stack.mConfigWillChange = config != null
                && mService.mConfiguration.diff(config) != 0;

        final long origId = Binder.clearCallingIdentity();
    
        //设置了ApplicationInfo.FLAG_CANT_SAVE_STATE标志
        //该标志表示:dest所在进程为重量级进程,此时不能按应用正常生命周期处理
        if (aInfo != null &&
                (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
            
            //dest的进程名等于其包名
            if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
                
                //存在重量级进程正在运行,且该进程不是dest所要在的进程
                //此时替换dest为HeavyWeightSwitcherActivity
                if (mService.mHeavyWeightProcess != null &&
                        (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
                        !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
                    int realCallingUid = callingUid;
                    
                    if (caller != null) {
                        //查找客户端进程信息
                        ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
                        if (callerApp != null) {
                            realCallingUid = callerApp.info.uid;
                        } else {
                            ActivityOptions.abort(options);
                            return ActivityManager.START_PERMISSION_DENIED;
                        }
                    }

                    IIntentSender target = mService.getIntentSenderLocked(
                            ActivityManager.INTENT_SENDER_ACTIVITY, "android",
                            realCallingUid, userId, null, null, 0, new Intent[] { intent },
                            new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
                            | PendingIntent.FLAG_ONE_SHOT, null);
    
                    Intent newIntent = new Intent();
                    //是否返回结果
                    if (requestCode >= 0) {
                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
                    }
                    
                    //设置PendingIntent
                    newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
                            new IntentSender(target));
                    
                    //有Activity运行在该重量级进程中,假设为heavyActivity
                    if (mService.mHeavyWeightProcess.activities.size() > 0) {
                        ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
                        //设置dest的包名为heavyActivity包名
                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
                                hist.packageName);
                        //设置dest的Task为heavyActivity所在Task
                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
                                hist.task.taskId);
                    }
                    
                    //heavyActivity不存在,设置新包名
                    newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
                            aInfo.packageName);
                    newIntent.setFlags(intent.getFlags());
                    
                    //将dest替换为HeavyWeightSwitcherActivity
                    newIntent.setClassName("android",
                            HeavyWeightSwitcherActivity.class.getName());
                    
                    //设置新intent的信息
                    intent = newIntent;
                    resolvedType = null;
                    caller = null;
                    callingUid = Binder.getCallingUid();
                    callingPid = Binder.getCallingPid();
                    componentSpecified = true;
                    try {
                        ResolveInfo rInfo =
                            AppGlobals.getPackageManager().resolveIntent(
                                    intent, null,
                                    PackageManager.MATCH_DEFAULT_ONLY
                                    | ActivityManagerService.STOCK_PM_FLAGS, userId);
                        aInfo = rInfo != null ? rInfo.activityInfo : null;
                        aInfo = mService.getActivityInfoForUser(aInfo, userId);
                    } catch (RemoteException e) {
                        aInfo = null;
                    }
                }
            }
        }

        int res = startActivityLocked(caller, intent, resolvedType,
                aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
                callingPackage, startFlags, options, componentSpecified, null);

        ...
        return res;
    }
}

该方法可简述为:

2.3、startActivityLocked

该方法同样在ActivityStackSupervisor.java中。

final int startActivityLocked(IApplicationThread caller,
        Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
        String resultWho, int requestCode,
        int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
        boolean componentSpecified, ActivityRecord[] outActivity) {
    
    int err = ActivityManager.START_SUCCESS;
    ProcessRecord callerApp = null;
    
    //判断AMS是否保存了源进程信息,并获取源进程pid、uid
    if (caller != null) {
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }

    if (err == ActivityManager.START_SUCCESS) {
        final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
    }

    ActivityRecord sourceRecord = null; 
    ActivityRecord resultRecord = null; //用来获取startActivityForeResult的结果
    if (resultTo != null) {
        //在task中查找src对应的ActivityRecord
        sourceRecord = isInAnyStackLocked(resultTo);
        if (sourceRecord != null) {
            if (requestCode >= 0 && !sourceRecord.finishing) {
                resultRecord = sourceRecord;
            }
        }
    }
    
    //src所在的Activity堆栈
    ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;

    int launchFlags = intent.getFlags();

    //设置了Intent.FLAG_ACTIVITY_FORWARD_RESULT标志
    //该标志表示:如果A->src->dest,则启动dest的结果返回给A,而不是src
    if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
            && sourceRecord != null) {
        //此时,src启动dest不得指定requestCode>=0
        if (requestCode >= 0) {
            ActivityOptions.abort(options);
            return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
        }
        
        //返回结果为src的返回结果
        resultRecord = sourceRecord.resultTo;
        //返回结果交给A
        resultWho = sourceRecord.resultWho;
        requestCode = sourceRecord.requestCode;
        //将src的返回结果设为null,使src不处理
        sourceRecord.resultTo = null;
        if (resultRecord != null) {
            resultRecord.removeResultsLocked(
                sourceRecord, resultWho, requestCode);
        }
    }

    //检查源进程是否有android.Manifest.permission.START_ANY_ACTIVITY权限
    //检查源Activity是否具备目的Activity通过android:permission声明的权限
    ...

    //为dest创建ActivityRecord
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
            intent, resolvedType, aInfo, mService.mConfiguration,
            resultRecord, resultWho, requestCode, componentSpecified, this);
    if (outActivity != null) {
        outActivity[0] = r;
    }

    //获取处于前台的stack
    final ActivityStack stack = getFocusedStack();
    
    /**
     * 前台stack中没有处于可见状态的Activity
     * 或者前台可见Activity与src有不同的uid(不同app)
     */
    if (stack.mResumedActivity == null
            || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
        //判断是否需要挂起目的Activity,比如正在通电话
        if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
            PendingActivityLaunch pal =
                    new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
            //挂起dest
            mService.mPendingActivityLaunches.add(pal);
            setDismissKeyguard(false);
            ActivityOptions.abort(options);
            return ActivityManager.START_SWITCHES_CANCELED;
        }
    }

    //运行切换,将运行切换时间置0,表示可任意切换app
    if (mService.mDidAppSwitch) {
        mService.mAppSwitchesAllowedTime = 0;
    } else {
        mService.mDidAppSwitch = true;
    }

    //先启动挂起等待的Activity
    mService.doPendingActivityLaunchesLocked(false);
    
    //接着往下执行
    err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
    ...
    return err;
}

该方法完成了:

2.4、startActivityUncheckedLocked

该方法在ActivityStackSupervisor.java中。

final int startActivityUncheckedLocked(ActivityRecord r,
        ActivityRecord sourceRecord, int startFlags, boolean doResume,
        Bundle options) {
    ...
    //若设置了Intent.FLAG_ACTIVITY_NO_USER_ACTION,则dest在onPause()之前不再调用其onUserLeaveHint()方法
    mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;

    //dest是否需要延迟启动
    if (!doResume) {
        r.delayedResume = true;
    }

    //若设置了Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP,则AMS将dest作为其task的Top Activity
    ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;

    /**
     * 若设置了ActivityManager.START_FLAG_ONLY_IF_NEEDED标志
     * 判断src与dest是否是同一Activity,或者src是否为空;满足,则将top activity作为caller(即src)
     */
    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
        ActivityRecord checkedCaller = sourceRecord;
        //src为空,将top activity作为src
        if (checkedCaller == null) {
            checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
        }
        //src与dest不同,清除ActivityManager.START_FLAG_ONLY_IF_NEEDED标志
        if (!checkedCaller.realActivity.equals(r.realActivity)) {
            startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
        }
    }
    
    /**
     * 判断是否需要为目的Activity分配新的task,即为launchFlags置位Intent.FLAG_ACTIVITY_NEW_TASK。
     * 注意:此处区分launchMode与launchFlages,launchMode是被启动Activity在AndroidManifest.xml中声明的;
     * launchFlags是启动Activity希望启动的方式。
     */
    if (sourceRecord == null) { //src为空,为dest分配新task
        if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
        }
    } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
        //src启动模式为singleInstance,为dest分配新task
        //src的task只能有src,dest只能另外分配task
        launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
    } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
        //dest的启动模式为singleInstance或singleTask,为dest分配新task
        launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
    }

    final ActivityStack sourceStack;
    if (sourceRecord != null) {
        if (sourceRecord.finishing) {
            //src正在销毁,src所处的task可能为空或即将销毁;避免盲目将dest放到src所处task,为dest分配新task
            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
            }
            //将src及其task置空
            sourceRecord = null;
            sourceStack = null;
        } else {
            sourceStack = sourceRecord.task.stack;
        }
    } else {
        sourceStack = null;
    }

    if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
        /**
         * 由于需要dest分配新task,而src又要求返回结果
         * 此时为避免混乱,先取消返回结果,并将返回结果置空
         */
        r.resultTo.task.stack.sendActivityResultLocked(-1,
                r.resultTo, r.resultWho, r.requestCode,
            Activity.RESULT_CANCELED, null);
        r.resultTo = null;
    }

    ...
    //为dest查找可复用的task
    if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
            (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
        ...
    }

    if (r.packageName != null) {
        ...
        //如果dest与task栈顶Activity相同,判断是否需要重新创建dest
        if (top != null && r.resultTo == null) {
            if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
                if (top.app != null && top.app.thread != null) {
                    
                    //设置了这些标志位,不重新创建dest实例
                    if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
                        || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
                        || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
                            
                        ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
                                top.task);                   
                        topStack.mLastPausedActivity = null;
                        
                        if (doResume) {
                            //不重新创建dest实例,直接启动顶部dest实例
                            resumeTopActivitiesLocked();
                        }
                        
                        ....
                        return ActivityManager.START_DELIVERED_TO_TOP;
                    }
                }
            }
        }

    } else {
        //返回错误结果
        ...
        return ActivityManager.START_CLASS_NOT_FOUND;
    }
   ...

    // 在新的task中启动dest
    if (r.resultTo == null && !addingToTask
            && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {          
        targetStack = adjustStackFocus(r);
        moveHomeStack(targetStack.isHomeStack());
        if (reuseTask == null) {
            //在新task中启动
            r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
                    null, true);
        } else {
            r.setTask(reuseTask, reuseTask, true);
        }
        newTask = true;
        
        //设置了Intent.FLAG_ACTIVITY_TASK_ON_HOME,即把dest置于Home Actvity之上,即按back键从dest返回到home
        if (!movedHome) {
            if ((launchFlags &
                    (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
                    == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
                r.task.mOnTopOfHome = true;
            }
        }
    } 
    //不在新task中启动dest
    else if (sourceRecord != null) {
        ...
        //dest之前启动过,清除task中dest之上的Activity,即clearTop启动模式
        //如,启动前:A-dest-src,启动后:A-dest
        if (!addingToTask &&
                (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
            ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
            keepCurTransition = true;
            if (top != null) {
                ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
                top.deliverNewIntentLocked(callingUid, r.intent);
                ...
                return ActivityManager.START_DELIVERED_TO_TOP;
            }
        }
        //dest之前启动过,将dest放栈顶。如,启动前:A-dest-src,启动后:A-src-dest
        else if (!addingToTask &&
                (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
            final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
            if (top != null) {
                final TaskRecord task = top.task;
                task.moveActivityToFrontLocked(top);
                ...
                return ActivityManager.START_DELIVERED_TO_TOP;
            }
        }
        //为dest设置task
        r.setTask(sourceTask, sourceRecord.thumbHolder, false);
    } 
    //标准启动流程,创建dest实例,放在task栈顶
    else {
        targetStack = adjustStackFocus(r);
        moveHomeStack(targetStack.isHomeStack());
        ActivityRecord prev = targetStack.topActivity();
        r.setTask(prev != null ? prev.task
                : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
                null, true);
    }

    ...
    //调用该方法,接着往下执行
    targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
    
    mService.setFocusedActivityLocked(r);
    return ActivityManager.START_SUCCESS;
}

方法略长,该方法主要是检查dest的启动模式,判断是否需要给dest创建新task,以及dest如何放置在其task中。

2.5、startActivityLocked

该方法在ActivityStack.java中,从类名可看出:ActivityStack用来描述我们常说的Activity栈。

/**
 * 注:为方便描述,将dest所在的task标记为DestTask
 */
final void startActivityLocked(ActivityRecord r, boolean newTask,
        boolean doResume, boolean keepCurTransition, Bundle options) {
            
    //DestTask信息
    TaskRecord rTask = r.task;
    final int taskId = rTask.taskId;
    
    //DestTask之前不存在
    if (taskForIdLocked(taskId) == null || newTask) {
        //DestTask放入已存在task列表中
        insertTaskAtTop(rTask);
        //将DestTask切换到前台
        mWindowManager.moveTaskToTop(taskId);
    }
    
    TaskRecord task = null;
    
    //DestTask之前存在,在已存在task列表中找到它
    if (!newTask) {
        boolean startIt = true;
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            task = mTaskHistory.get(taskNdx);
            //找到了DestTask
            if (task == r.task) {
                /**
                 * DestTask不可见,此时只将dest置于DestTask顶部,而不启动它
                 * 当用户按下返回键时,再启动dest
                 */
                if (!startIt) {
                    //将dest置于DestTask顶部
                    task.addActivityToTop(r);
                    //使DestTask中Actvity数量加1
                    r.putInHistory();
                    
                    mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
                            r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                            (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
                            r.userId);
                    if (VALIDATE_TOKENS) {
                        validateAppTokensLocked();
                    }
                    ActivityOptions.abort(options);
                    return;
                }
                break;
            } else if (task.numFullscreen > 0) {
                startIt = false;
            }
        }
    }

    //DestTask不处于前台,则dest在调用onPause()之前,不回调其onUserLeaving方法。
    if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
        mStackSupervisor.mUserLeaving = false;
        if (DEBUG_USER_LEAVING) Slog.v(TAG,
                "startActivity() behind front, mUserLeaving=false");
    }

    //DestTask
    task = r.task;
    //将dest放在DestTask顶部
    task.addActivityToTop(r);
    //使DestTask中Actvity数量加1
    r.putInHistory();
    
    //dest是否为DestTask的root activity(即位于栈底)
    //如果DestTask是新task,那DestTask只有dest,则dest肯定是root activity
    r.frontOfTask = newTask;
    
    //如果DestTask是新task,或dest所在进程未运行,则显示启动预览窗口
    if (!isHomeStack() || numActivities() > 0) {
        ...
    } 
    ...

    if (doResume) {
        //调用该方法,继续往下执行
        mStackSupervisor.resumeTopActivitiesLocked();
    }
}

2.6、resumeTopActivitiesLocked

该方法在ActivityStackSupervisor.java中,又回到这里了,其实AMS就是在这几个类换来换去~

boolean resumeTopActivitiesLocked() {
     return resumeTopActivitiesLocked(null, null, null);
}
//注意:上步中入参都为null
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
    Bundle targetOptions) {
    //targetStack为null,将targetStack设置为处于前台的Task
    if (targetStack == null) {
        targetStack = getFocusedStack();
    }
    boolean result = false;
    for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
        final ActivityStack stack = mStacks.get(stackNdx);
        //查找处于前台的stack
        if (isFrontStack(stack)) {
            //前台stask与targetStack相同,即启动Activity所在task为前台task
            if (stack == targetStack) {
                //在dest所在的task中调用该方法,注意:入参都为null
                result = stack.resumeTopActivityLocked(target, targetOptions);
            } else {
                //启动HomeActivity
                stack.resumeTopActivityLocked(null);
            }
        }
    }
    return result;
}

2.7、resumeTopActivityLocked

该方法在ActivityStack.java中,又回到ActivityStack了……

//该方法确保当前task顶部的Activity是resumed状态的(前台可见状态)
final boolean resumeTopActivityLocked(ActivityRecord prev) {
    return resumeTopActivityLocked(prev, null);
}
//注意:此处入参都为null
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
    if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");

    //当前task中栈顶Activity,即dest
    ActivityRecord next = topRunningActivityLocked(null);
    ...

    //当前栈不存在Activity,启动Launcher
    if (next == null) {
        ActivityOptions.abort(options);
        return mStackSupervisor.resumeHomeActivity(prev);
    }

    next.delayedResume = false;

    //dest已经处于前台可见状态,设置动画,直接返回
    if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
                mStackSupervisor.allResumedActivitiesComplete()) {
        mWindowManager.executeAppTransition();
        mNoAnimActivities.clear();
        ActivityOptions.abort(options);
        return false;
    }

    //nextTask为dest所在task,记为DestTask
    final TaskRecord nextTask = next.task;
    
    //入参是prev为null,所以prevTask为null
    final TaskRecord prevTask = prev != null ? prev.task : null;
    //prevTask为null,忽略
    if (prevTask != null && prevTask.mOnTopOfHome && prev.finishing && prev.frontOfTask) {
        ...
    }

    /**
     * 手机处于休眠状态,且该task不存在可见状态的Activity,且该task顶部Activity处于暂停状态
     * 设置动画,直接返回
     */
    if (mService.isSleepingOrShuttingDown()
            && mLastPausedActivity == next
            && mStackSupervisor.allPausedActivitiesComplete()) {
        mWindowManager.executeAppTransition();
        mNoAnimActivities.clear();
        ActivityOptions.abort(options);
        return false;
    }

    //dest的user未启动,直接返回
    if (mService.mStartedUsers.get(next.userId) == null) {
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return false;
    }

    //从stop列表中移除dest
    mStackSupervisor.mStoppingActivities.remove(next);
    //从即将休眠列表中移除dest
    mStackSupervisor.mGoingToSleepActivities.remove(next);
    next.sleeping = false;
    //从等待显示列表中移除dest
    mStackSupervisor.mWaitingVisibleActivities.remove(next);
    next.updateOptionsLocked(options);

    //当前正在暂停其他Activity,等该暂停操作完成
    if (!mStackSupervisor.allPausedActivitiesComplete()) {
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return false;
    }

    //该代码不执行,跳过
    if (false) {
        ...
    }

    //暂停AMS中前台不可见的Stack中resumed activity,dest才能启动!
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving);
    if (mResumedActivity != null) {
        pausing = true;
        startPausingLocked(userLeaving, false);
    }
    
    if (pausing) {
        if (DEBUG_SWITCH || DEBUG_STATES)
        //dest所在进程存在,设置其进程信息
        if (next.app != null && next.app.thread != null) {
            mService.updateLruProcessLocked(next.app, false, true);
        }
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }

    //系统即将休眠,结束mLastNoHistoryActivity
    if (mService.mSleeping && mLastNoHistoryActivity != null &&
            !mLastNoHistoryActivity.finishing) {
        requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
                null, "no-history", false);
        mLastNoHistoryActivity = null;
    }

    ...

    ActivityStack lastStack = mStackSupervisor.getLastStack();
    
    //next(即dest)所在进程存在
    if (next.app != null && next.app.thread != null) {
        if (DEBUG_SWITCH) Slog.v(TAG, "Resume running: " + next);

        //窗口管理器标记next可见
        mWindowManager.setAppVisibility(next.appToken, true);
        next.startLaunchTickingLocked();

        //上个处于可见状态的Activity
        ActivityRecord lastResumedActivity =
                lastStack == null ? null :lastStack.mResumedActivity;
        ActivityState lastState = next.state;
        mService.updateCpuStats();
        
        //将next状态更改为可见状态
        next.state = ActivityState.RESUMED;
        //将next设置为当前可见的Activity
        mResumedActivity = next;
        
        next.task.touchActiveTime();
        //AMS将next所在task添加进最近红的task列表
        mService.addRecentTaskLocked(next.task);
        mService.updateLruProcessLocked(next.app, true, true);
        updateLRUListLocked(next);

        //获取窗口配置信息
        boolean notUpdated = true;
        if (mStackSupervisor.isFrontStack(this)) {
            Configuration config = mWindowManager.updateOrientationFromAppTokens(
                    mService.mConfiguration,
                    next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
            if (config != null) {
                next.frozenBeforeDestroy = true;
            }
            notUpdated = !mService.updateConfigurationLocked(config, next, false, false);
        }

        if (notUpdated) {
            //dest配置在启动过程中发生了变化,结束启动
            ActivityRecord nextNext = topRunningActivityLocked(null);
            if (nextNext != next) {
                mStackSupervisor.scheduleResumeTopActivities();
            }
            if (mStackSupervisor.reportResumedActivityLocked(next)) {
                mNoAnimActivities.clear();
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return true;
            }
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            return false;
        }

        try {
            //处理dest收到的ActivityResult
            ArrayList<ResultInfo> a = next.results;
            if (a != null) {
                final int N = a.size();
                if (!next.finishing && N > 0) {
                    next.app.thread.scheduleSendResult(next.appToken, a);
                }
            }

            //回调dest的onNewIntent方法
            if (next.newIntents != null) {
                next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
            }

            ...
            next.sleeping = false;
            mService.showAskCompatModeDialogLocked(next);
            next.app.pendingUiClean = true;
            next.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
            
            //进程存在,直接调用scheduleResumeActivity方法
            next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
                    mService.isNextTransitionForward());
            mStackSupervisor.checkReadyForSleepLocked();
        } 
        ...
        
    } else {
        ...
        /**
         * dest所在的进程不存在
         * 调用该方法启动进程,进程启动后,流程与scheduleResumeActivity相同
         */
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
    return true;
}

2.8、startSpecificActivityLocked

该方法在ActivityStackSupervisor.java中,这里导向了目的进程创建流程,标注加红,下一篇文章从这里开始哦!

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    // 获取dest所在进程信息
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);
    r.task.stack.setLaunchTime(r);
    
    /**
     * dest所在进程存在
     * 由于上个方法已经判断dest进程不存在,为啥此处仍有判断?
     * 难道在此期间,dest进程可能被启动了?
     */
    if (app != null && app.thread != null) {
        try {
            app.addPackage(r.info.packageName, mService.mProcessStats);
            //调用该方法继续
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }
    }
  
    /**
     * dest进程不存在,调用该方法启动进程,该流程见《ActivityThrad分析》
     * 后续仍会调用上realStartActivityLocked方法
     */
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

2.9、realStartActivityLocked

该方法在ActivityStackSupervisor.java中。

final boolean realStartActivityLocked(ActivityRecord r,
        ProcessRecord app, boolean andResume, boolean checkConfig)
        throws RemoteException {

    ...
    //dest记录进程信息
    r.app = app;
    app.waitingToKill = null;
    r.launchCount++;
    r.lastLaunchTime = SystemClock.uptimeMillis();
    
    //将dest保存到ProcessRecord中
    int idx = app.activities.indexOf(r);
    if (idx < 0) {
        app.activities.add(r);
    }
    ...
        //调用该方法启动
        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                System.identityHashCode(r), r.info,
                new Configuration(mService.mConfiguration), r.compat,
                app.repProcState, r.icicle, results, newIntents, !andResume,
                mService.isNextTransitionForward(), profileFile, profileFd,
                profileAutoStop);

        ...
    } 
    ...
    return true;
}

目的进程


3.1、scheduleLaunchActivity

该方法在ActivityThread.java中,为ActivityThread的内部类。

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
            ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
            int procState, Bundle state, List<ResultInfo> pendingResults,
            List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
            String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {

        updateProcessState(procState, false);
        ActivityClientRecord r = new ActivityClientRecord();

        r.token = token;
        r.ident = ident;
        r.intent = intent;
        r.activityInfo = info;
        r.compatInfo = compatInfo;
        r.state = state;

        r.pendingResults = pendingResults;
        r.pendingIntents = pendingNewIntents;

        r.startsNotResumed = notResumed;
        r.isForward = isForward;

        r.profileFile = profileName;
        r.profileFd = profileFd;
        r.autoStopProfiler = autoStopProfiler;

        updatePendingConfiguration(curConfig);
        //通过H handler发送LAUNCH_ACTIVITY消息
        queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
    }

3.2、handleMessage

该方法在H handler中了。

public void handleMessage(Message msg) {
        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
        switch (msg.what) {
            case LAUNCH_ACTIVITY: {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                r.packageInfo = getPackageInfoNoCheck(
                        r.activityInfo.applicationInfo, r.compatInfo);
                //调用该方法
                handleLaunchActivity(r, null);
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            } break;
            ...
        }

3.3、handleLaunchActivity

该方法在ActivityThread.java中

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ...
    //调用该方法启动dest
    Activity a = performLaunchActivity(r, customIntent);

    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        Bundle oldState = r.state;
        //该方法会调用dest的onResume方法
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed);

        if (!r.activity.mFinished && r.startsNotResumed) {
            //暂停dest,因为dest不在前台
            try {
                r.activity.mCalled = false;
                mInstrumentation.callActivityOnPause(r.activity);
                //Honeycomb之前版本需要保存状态
                if (r.isPreHoneycomb()) {
                    r.state = oldState;
                }
                if (!r.activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onPause()");
                }

            }
            ...
            r.paused = true;
        }
    } else {
       //出错,结束dest
        try {
            ActivityManagerNative.getDefault()
                .finishActivity(r.token, Activity.RESULT_CANCELED, null);
        } catch (RemoteException ex) {}
    }
}

这里分析下内部的两个重要调用方法:performLaunchActivity 、handleResumeActivity

3.4、performLaunchActivity ActivityThread.java

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ActivityInfo aInfo = r.activityInfo;
    //dest包信息(packageInfo为LoadAPK对象)
    if (r.packageInfo == null) {
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }
    
    //启动dest的Intent是否指定了启动组件
    ComponentName component = r.intent.getComponent();
    if (component == null) {
        //intent未指定启动组件,查询与Intent匹配的Activity
        component = r.intent.resolveActivity(
            mInitialApplication.getPackageManager());
        r.intent.setComponent(component);
    }
    
    //dest是否设置了targetActivity,设置了则启动targetActivity
    if (r.activityInfo.targetActivity != null) {
        component = new ComponentName(r.activityInfo.packageName,
                r.activityInfo.targetActivity);
    }

    //反射创建dest实例
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {
        ...
    }

    try {
        /**
         * dest所在Application已启动,则直接返回它
         * 否则为dest创建Application,并回调该Appication的onCreate方法
         */
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);

        if (activity != null) {
            //为dest创建上下文环境
            Context appContext = createBaseContextForActivity(r, activity);
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = new Configuration(mCompatConfiguration);
            //设置到dest中
            activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config);

            if (customIntent != null) {
                activity.mIntent = customIntent;
            }
            r.lastNonConfigurationInstances = null;
            activity.mStartedActivity = false;
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                activity.setTheme(theme);
            }
            activity.mCalled = false;
            
            //回调dest的onCreate方法!!!
            mInstrumentation.callActivityOnCreate(activity, r.state);
            
            r.activity = activity;
            r.stopped = true;
            
            //调用dest的onStart()方法
            if (!r.activity.mFinished) {
                activity.performStart();
                r.stopped = false;
            }
            
            if (!r.activity.mFinished) {
                if (r.state != null) {
                    //设置了state,调用dest的onRestoreInstanceState方法
                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                }
            }
            
            if (!r.activity.mFinished) {
                activity.mCalled = false;
                //回调dest的onPostCreate()方法
                mInstrumentation.callActivityOnPostCreate(activity, r.state);
                ...
            }
        }
        r.paused = true;
        mActivities.put(r.token, r);

    } 
    ...

    return activity;
}

3.5、handleResumeActivity

该方法在ActivityThread.java中。

final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
        boolean reallyResume) {
       unscheduleGcIdler();

    //调用dest的onResume方法
    ActivityClientRecord r = performResumeActivity(token, clearHide);

    if (r != null) {
        final Activity a = r.activity;
        ...
        
        if (!willBeVisible) {
            try {
                //aidl调用AMS方法,判断dest是否可见
                willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
                        a.getActivityToken());
            } catch (RemoteException e) {
            }
        }
        
        //将dest所在窗口添加到WindowManager
        if (r.window == null && !a.mFinished && willBeVisible) {
            //获取dest所在窗口
            r.window = r.activity.getWindow();
            //获取窗口的DecorView
            View decor = r.window.getDecorView();
            //将DecorView设置不可见
            decor.setVisibility(View.INVISIBLE);
            
            //获取WindowManager
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
            l.softInputMode |= forwardBit;
            if (a.mVisibleFromClient) {
                a.mWindowAdded = true;
                //将DecorView添加到WindowManager
                wm.addView(decor, l);
            }
        } else if (!willBeVisible) {
            //隐藏dest所在窗口
            r.hideForNow = true;
        }

        // Get rid of anything left hanging around.
        cleanUpPendingRemoveWindows(r);

        //显示dest
        if (!r.activity.mFinished && willBeVisible
                && r.activity.mDecor != null && !r.hideForNow) {
            ...
            if ((l.softInputMode
                    & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
                    != forwardBit) {
                //设置软键盘属性
                l.softInputMode = (l.softInputMode
                        & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
                        | forwardBit;
                
                if (r.activity.mVisibleFromClient) {
                    ViewManager wm = a.getWindowManager();
                    View decor = r.window.getDecorView();
                    //显示dest窗口下的DecorView
                    wm.updateViewLayout(decor, l);
                }
            }
            ...
        }

        ...
        if (reallyResume) {
            try {
                //通知AMS,dest已处于可见状态
                ActivityManagerNative.getDefault().activityResumed(token);
            } catch (RemoteException ex) {
            }
        }

    } else {
        try {
            //出现异常,结束dest
            ActivityManagerNative.getDefault()
                .finishActivity(token, Activity.RESULT_CANCELED, null);
        } catch (RemoteException ex) {
        }
    }
}

总结


总算写完了,看到这里估计你也晕了~
不想写总结了,就这样吧,觉得可以就点个赞吧。

上一篇下一篇

猜你喜欢

热点阅读