android6.0源码分析之Activity启动过程

Posted 古冥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android6.0源码分析之Activity启动过程相关的知识,希望对你有一定的参考价值。

Activity最为android开发者最熟悉的组件,由ActivityManagerService服务进行调度管理,而ActivityManagerService的启动过程在activitymanagerservice服务源码分析一文中进行了详细分析,本文基于其对Activity的启动过程进行分析,同时也将分析AMS对Activity的调度管理。


1、 Activity的启动模式

启动模式实际上就是为了控制Activity与Task之间的关系,目前共有一下四种模式:standard、singleTop、singleTask以及singleInstance,默认的模式为standard模式。
注意:建议一般的开发者不要轻易使用后两种模式,因为不同的模式,其出栈的顺序不同,可能会导致用户按下返回键时,会有不一样的用户体验,对于启动模式的分析,推荐仔细阅读深入讲解Android中Activity launchMode,这篇文章使用图文并用的方式,很好的分析了Activity各种模式的区别,本文不再分析启动模式。


2、Activity的启动时机

Activity作为android非常重要的组件,那么我们会在哪些时机启动它呢?
通常有如下几种情形:
1. android AM命令
android系统为开发者提供了adb工具,而在adb的基础上执行adb shell就可以从PC上对手机侧执行shell命令。如启动浏览器:am start -n com.android.browser/com.android.browser.BrowserActivity。
2. 启动AMS服务时
在启动AMS服务时,在最后调用AMS的systemReady的最后阶段会启动Home界面,此时就会启动一个Activity。
3. 调用startActivity()和startActivityForResult()方法时
这是我们最常用也最熟悉的启动Activity的方式。


3、AM命令行启动Activity的过程分析

在adb中可以使用AM命令,同时在应用程序中,也可以通过AM命令来启动指定的Activity,AM是一个脚本命令,它还可以启动Service,发送广播等。

3.1 Am 框架层调用流程分析

adb执行Am命令后,最终会执行Am.java的main方法,其代码如下:

//Am.java
public static void main(String[] args)
    (new Am()).run(args);

它调用的是抽象父类BaseCommand类的run方法:

//BaseCommand.java
public void run(String[] args)
    if(args.length<1)
        //显示命令使用说明
        onShowUsage(System.out);
        return;
    
    mArgs = args;
    mNextArg = 0;
    mCurArgData = null;
    try
        onRun();
    catch(...)...

跟其他命令脚本类似,如果参数为空,显示使用说明,否则调用onRun()方法,它是一个抽象方法,在Am.java中有实现:

//Am.java
@Override
public void onRun() throws Exception
    //获取AMS
    mAm = ActivityManagerNative.getDefault();
    ...
    String op = nextArgRequired();
    if(op.equals("start"))
        //启动Activity
        runStart();
    else if(op.equals("startService"))
        //启动服务
        runStartService();  
    else if(op.equals("force-stop"))
        //强制停止
        runForceStop();
    else if(op.equals("kill"))
        //杀死进程
        runKill();  
    else if
        ...
    else
        ...
    

命令参数不同,其执行的操作不同,就本节来说,其参数为start,所以将会执行runStart()方法来启动Activity:

//Am.java
private void runStart() throws Exception
    Intent intent = makeIntent(UserHandle.USER_CURRENT);
    ...
    do
        //获取包信息
        ...
        //设置intent的标志位FLAG_ACTIVITY_NEW_TASK,即将启动一个新任务
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        ParcelFileDescriptor fd = null;
        ProfilerInfo profilerInfo = null;
        if(mProfileFile != null)//处理-P选项,统计性能
            try
                fd = openForSystemServer(new File(mProfileFile),ParcelFileDescriptior.MODE_CREATE|
                    ParcelFileDescriptor.MODE_TRUNCATE|ParcelFileDescriptor.MODE_READ_WRITE);
            catch(...)...
            profilerInfo = new ProfilerInfo(mProfileFile,fd,mSamplingInterval,mAutoStop);
        
        ...
        int res;
        ...
        if(mWaitOption)//控制是否等待启动结果,如果有-W选项,则该值为true
            result = mAm.startActivityAndWait(null,null,intent,mimeType,null,null,0,mStartFlags,
                profilerInfo,null,mUserId);
            res = result.result;
        else
            res = mAm.startActivityAsUser(null,null,intent,mimeType,null,null,0,mStartFlags,
                profilerInfo,null,mUserId);
        
        //处理一些返回结果
        ...
    while(mRepeat > 1);

startActivityAsUser()最后也是调用AMS的startActivityAndWait()方法,所以Am命令框架层的调用结束,其调用时序如下:


3.2 AMS启动Activity流程分析

Am命令将启动Activity的工作交给了AMS来进行,首先看startActivityAndWait()方法,它直接调用StackSupervisor类的startActivityMayWait()方法,其代码如下:

//ActivityStackSupervisor.java
final int startActivityMayWait(...)
    ...
    //为了不改变用户的intent
    intent = new Intent(intent);
    //收集目标intent的信息,在resolveActivity方法中与PKMS交互获得
    ActivityInfo aInfo = resolveActivity(intent,resolvedType,startFlags,profilerInfo,userId);
    ActivityContainer container = (ActivityContainer)iContainer;
    synchronized(mService)
        ...
        final ActivityStack stack;
        //取得需要启动的ActivityStack栈
        if(container == null || container.mStack.isOnHomeDisplay())
            stack = mFocusedStack;
        else
            stack = container.mStack;
        
        ...
        if(aInfo!=null&&(aInfo.applicationInfo.privateFlags&
            ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)!=0)
            //Androidmanifest.xml中的Application标签可以声明一个cantSaveState属性,若设置,其将不享受系统提
            //供的状态保存/恢复功能。主要是为了保证用户体验的连续性
            ...
        
        //启动Activity
        int res = startActivityLocked(caller,intent,resolvedType,aInfo,voiceSession,
            voiceInteractor,resultTo,resultWho,requestCode,callingPid,callingUid,callingPackage,
            realCallingPid,realCallingUid,startFlags,options,ignoreTargetSecurity,
            componentSpecified,null,container,inTask);
        ...
        //如果配置Configration发生变化,则调用AMS的updateConfigurationLocked进行处理
        if(stack.mConfigWillChange)
            mService.enforceCallingPermission(...);
            mConfigWillChange = false;
            mService.updateConfigurationLocked(config,null,false);
        
        if(outResult != null)
            outResult.result = res;
            if(res == IActivityManager.START_SUCCESS)
                //将结果放入mWaitingActivityLaunced中保存
                mWaitingActivityLaunched.add(outResult);
                do
                    try
                        //等待启动结果
                        mService.wait();
                    
                while(!outResult.timeout&&outResult.who == null);
            else if
                ...
            
            ...
        
        return res;
    

首先通过PKMS查找匹配的ActivityInfo,然后获取调用者的pid,uid等信息,由于本文的caller为空,得到的是Am所在进程的pid和uid。接着调用startActivityLocked()方法启动Activity,最后再调用mService.wait()方法来等待启动结果,并对返回值进行一些处理,此处的等待主要是Am参数中有一个-W选项,若无此选项,则不会有这个等待,最后再将启动结果res返回。
继续分析startActivityLocked()方法:

//ActivityStackSupervisor.java
final int startActivityLocked(...)
    int err = ActivityManager.START_SUCCESS;
    ProcessRecord callerApp = null;
    if (caller != null) //如果caller不为空,从AMS中找到它所属的ProcessRecord即进程,本文此处为null
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) 
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
         else 
            err = ActivityManager.START_PERMISSION_DENIED;
        
    
    ...
    //sourceRecord用于描述启动目标Activity的那个Activity
    ActivityRecord sourceRecord = null;
    //resultRecord用于描述接收启动结果的Activity,即onActivityResult将被调用以通知启动结果
    ActivityRecord resultRecord = null;
    ...
    //获取Intent设置的启动标志
    final int launchFlags = intent.getFlags();
    //此部分与LaunchMode类似,它用于控制Activity启动结果的通知
    if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) 
        ...
    
    ...
    //检查权限
    final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid, callingUid);
    ...
    //可为AMS设置IActivityController类型的监听者,AMS有任何动静都将回调该监听者
    if (mService.mController != null) 
        try 
            Intent watchIntent = intent.cloneFilter();
            //交给回调对象处理,由它判断能否继续后面的行程
            abort |= !mService.mController.activityStarting(watchIntent,
                        aInfo.applicationInfo.packageName);
         catch (RemoteException e) 
            mService.mController = null;
        
    
    if (abort) //通知resultRecord
        if (resultRecord != null) 
            resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
                Activity.RESULT_CANCELED, null);
       
        ActivityOptions.abort(options);
        return ActivityManager.START_SUCCESS;
    
    //创建一个ActivityRecord对象
    ActivityRecord r = new ActivityRecord(mService,this,callerApp,callingUid,...);
    ...
    final ActivityStack stack = mFocusedStack;
    if (voiceSession == null && (stack.mResumedActivity == null
        || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) 
        //判断是否有权限切换Application
        if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,realCallingPid, 
            realCallingUid, "Activity start")) 
            PendingActivityLaunch pal =new PendingActivityLaunch(r, sourceRecord,startFlags,
                stack);
            //将Pending的请求保存到AMS的mPendingActivityLaunches变量中
            mPendingActivityLaunches.add(pal);
            ActivityOptions.abort(options);
            return ActivityManager.START_SWITCHES_CANCELED;
        
    
    if (mService.mDidAppSwitch) 
        mService.mAppSwitchesAllowedTime = 0;
     else 
        mService.mDidAppSwitch = true;
    
    //启动处于Pending状态的Activity
    doPendingActivityLaunchesLocked(false);
    //调用此函数继续启动Activity
    err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,startFlags, 
        true, options, inTask);
    //做一些结果处理
    ...
    return err;

此段代码的主要工作就是处理sourceRecord和resultRecord,然后再处理app switch属性,如果当前禁止app switch,则将本次启动保存起来,等允许app switch时再处理,最后再调用startActivityUncheckedLocked()方法处理本次Activity启动请求:

//ActivityStackSupervisor.java
final int startActivityUncheckedLocked(...) 
    final Intent intent = r.intent;
    final int callingUid = r.launchedFromUid;
    ...
    //获取启动标志
    int launchFlags = intent.getFlags();
    if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&(launchSingleInstance 
        || launchSingleTask)) 
        //如果Intent和AndroidManifest.xml的启动模式有冲突,以AndroidManifest.xml为准
        launchFlags &=~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
     else 
         ...
    
    ...
    if (sourceRecord != null) //如果请求的发起者为空,则需要创建一个新的Task
        if (sourceRecord.finishing) 
            if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) 
                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
                newTaskInfo = sourceRecord.info;
                newTaskIntent = sourceRecord.task.intent;
            
            sourceRecord = null;
            sourceStack = null;
         else 
            sourceStack = sourceRecord.task.stack;
        
     else 
        sourceStack = null;
    
    ...
    if(inTask==null)
        if(sourceRecord==null)
            //如果不是从另外的Activity启动的,则需创建新的Task
            if((launchFlags&Intent.FLAG_ACTIVITY_MEW_TASK)==0&&inTask==null)
                launchFlags|=Intent.FLAG_ACTIVITY_NEW_TASK;
            
        else if(sourceRecord.launchMode==ActivityInfo.LAUNCH_SINGLE_INSTANCE)
            //如果此Activity在系统中已经有实例在运行,则需要为此Activity额外创建一个Task
            launchFlags|=Intent.FLAG_ACTIVITY_NEW_TASK;
        else if(launchSingleInstance||launchSingleTask)
            //如果是SingleInstance或者SingleTask的启动模式,同样需要创建新的Task
            launchFlags|=Intent.FLAG_ACTIVITY_NEW_TASK;
        
    
    ...
    targetStack.startActivityLocked(r,newTask,doResume,keepCurTransition,options);
    ...
    return ActivityManager.START_SUCCESS;

首先根据Activity的启动模式以及传入的参数来确定是否需要创建新的Task以及launchFlags,然后调用startActivityLocked()方法继续启动(这里的方法参数与前面同名方法的不一样,属于重载函数),继续分析启动过程:

//ActivityStackSupervisor.java
final void startActivityLocked(ActivityRecord r, boolean newTask,
        boolean doResume, boolean keepCurTransition, Bundle options)
    ...
    TaskRecord task = null;
    if (!newTask) //如果不是已经存在的任务,则找到它在哪里
        boolean startIt = true;
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) 
            task = mTaskHistory.get(taskNdx);
            if (task.getTopActivity() == null) 
                //此task下的Activity全部执行结束
                continue;
            
            if (task == r.task) 
                if (!startIt) //如果它对用户是不可见的,只需将其加入未启动的
                    task.addActivityToTop(r);
                    r.putInHistory();
                    ...
                    ActivityOptions.abort(options);
                    return;
                
                break;
            else if(task.numFullScreen > 0)
                startIt = false;
            
        
    
    ...
    //将Activity信息加入到history stack中并处理
    task = r.task;
    task.addActivityToTop(r);
    task.setFrontOfTask();
    r.putInHistory();
    ...
    if(doResume)
        mStackSupervisor.resumeTopActivitiesLocked(this,r,options);
    

此方法将根据传入的参数来找到此Activity所在的任务,以及进行相应判断将其加入到相应的history stack的最顶端(栈顶),最后再调用ActivityStack的resumeTopActivitiesLocked方法来启动栈顶的Activity,继续分析resumeTopActivitiesLocked方法:

//ActivityStack.java
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
            Bundle targetOptions)
    if (targetStack == null) //如果目的任务为NULL,则启动当前聚焦的任务
        targetStack = mFocusedStack;
    
    //启动targetStack
    boolean result = false;
    if (isFrontStack(targetStack)) 
        result = targetStack.resumeTopActivityLocked(target, targetOptions);
    

    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) 
        final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) 
            final ActivityStack stack = stacks.get(stackNdx);
            if (stack == targetStack) 
                //上面已经启动了
                continue;
            
            if (isFrontStack(stack)) 
                stack.resumeTopActivityLocked(null);
            
        
    
    return result;

此方法很简单就是根据当前任务,调用相应的resumeTopActivityLocked()方法来启动,而resumeTopActivityLocked也只是简单的调用了resumeTopActivityInnerLocked方法,所以分析resumeTopActivityInnerLocked方法:

//ActivityStack.java
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options)
    //找到第一个还没有结束的Activity
    final ActivityRecord next = topRunningActivityLocked(null);
    ...
    //确保拥有此Activity的任务已经启动
    if (mService.mStartedUsers.get(next.userId) == null) 
        return false;
    
    ...
    //设置启动的Uid
    mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
    ...
    ActivityStack lastStack = mStackSupervisor.getLastStack();
    if (next.app != null && next.app.thread != null) //进程,线程都存在
        //将此Activity置为Visible
        mWindowManager.setAppVisibility(next.appToken, true);
        // schedule launch ticks to collect information about slow apps.
        next.startLaunchTickingLocked();

        ActivityRecord lastResumedActivity =
                    lastStack == null ? null :lastStack.mResumedActivity;
        ActivityState lastState = next.state;

        next.state = ActivityState.RESUMED;
        mResumedActivity = next;
        next.task.touchActiveTime();
        mRecentTasks.addLocked(next.task);
        mService.updateLruProcessLocked(next.app, true, null);
        updateLRUListLocked(next);
        mService.updateOomAdjLocked();
        ...
        try 
            // Deliver all pending results.
            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);
                
            
            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(mService.mTopProcessState);
            next.clearOptionsLocked();
            //因为进程,线程都存在,所以只需恢复此Activity
            next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
            mService.isNextTransitionForward(), resumeAnimOptions);
         catch (Exception e) 
            // 如果发生异常,需要重启此Activity,注意此方法最后一个参数为false
            mStackSupervisor.startSpecificActivityLocked(next, true, false);
            return true;
        
     else 
        //因为进程或者线程为空,所以需要重新启动activity,此处最后一个参数为true
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    
    return true;

如代码可知:如果当前需要启动的Activity所在的进程和线程都已经创建,则调用ActivityThread的scheduleResumeActivity方法来恢复此Activity,此时如果发生异常,则调用startSpecificActivityLocked来重新启动此Activity,当然,我们注意到,当Activity所在的进程或者线程为启动时,它也是调用startSpecificActivityLocked方法来重新启动此Activity,但区别在此方法的最后一个参数,即进程和线程已经启动了的为flase,否则为true,下面分析startSpecificActivityLocked()方法:

//ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) 
    //先获取app,据此app来判断Activity所在的Application是否已经启动
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                            r.info.applicationInfo.uid, true);
    r.task.stack.setLaunchTime(r);
    if (app != null && app.thread != null) //进程和线程不为空,即已经启动好
        try 
            ...
            //真正启动Activity的函数,注意checkConfig参数
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
         catch (RemoteException e) ...
    
    //进程或者线程未启动
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);

由代码可知,它同样会先判断线程和进程是否已启动,如果已启动,调用realStartActivityLocked来启动Activity,否则调用AMS的startProcessLocked来启动进程,由于Am命令和AMS的Hone界面启动都是进程未启动的情况,所以此处先分析分两个阶段分析,此阶段的时序图如下:


3.2.1 AMS启动Activity所在进程的流程分析

由于android下的Java进程都是由Zygote进程fork出来的,所以分析此流程之前,需要对Zygote的原理有一些了解,对Zygote进程的分析请参考android源码分析之Zygote进程分析,先从AMS的startProcessLocked方法进行分析:

//ActivityManagerService.java
private final void startProcessLocked(ProcessRecord app, String hostingType,String hostingNameStr, 
            String abiOverride, String entryPoint, String[] entryPointArgs)
    long startTime = SystemClock.elapsedRealtime();
    if (app.pid > 0 && app.pid != MY_PID) //如果不是当前进程,则移除
        checkTime(startTime, "startProcess: removing from pids map");
        synchronized (mPidsSelfLocked) 
            mPidsSelfLocked.remove(app.pid);
            mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
        
        checkTime(startTime, "startProcess: done removing from pids map");
        app.setPid(0);
    
    ...
    //启动进程
    Process.ProcessStartResult startResult = Process.start(entryPoint,app.processName, uid, uid, 
            gids, debugFlags, mountExternal,app.info.targetSdkVersion, app.info.seinfo, 
                requiredAbi, instructionSet,app.info.dataDir, entryPointArgs);
    ...
    //通知BatteryStatsService服务此进程启动
    mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
    ...//对进程启动结果进行处理

由代码可知,它调用了Process的start方法来启动进程,继续分析start方法:

//Process.java
public static final ProcessStartResult start(...)
    try 
        return startViaZygote(processClass, niceName, uid, gid, gids,debugFlags, mountExternal,
            targetSdkVersion, seInfo, abi, instructionSet, appDataDir, zygoteArgs);
     catch (ZygoteStartFailedEx ex) 
        Log.e(LOG_TAG, "Starting VM process through Zygote failed");
        throw new RuntimeException("Starting VM process through Zygote failed", ex);
    

继续看startViaZygote方法:

//Process.java
private static ProcessStartResult startViaZygote(...)
    synchronized(Process.class) 
        ArrayList<String> argsForZygote = new ArrayList<String>();
        // --runtime-args, --setuid=, --setgid=,
        // and --setgroups= must go first
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        //参数处理
        ...
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);

同样,它首先进行一些参数处理,如runtime的参数等等,继续分析zygoteSendArgsAndGetResult方法:

//Process.java
private static ProcessStartResult zygoteSendArgsAndGetResult(ZygoteState zygoteState, 
        ArrayList<String> args) throws ZygoteStartFailedEx
     try 
         //通过socket通信,此处将进程启动的启动写进socket的输出流
         final BufferedWriter writer = zygoteState.writer;
         final DataInputStream inputStream = zygoteState.inputStream;

         writer.write(Integer.toString(args.size()));
         writer.newLine();

         int sz = args.size();
         for (int i = 0; i < sz; i++) 
             String arg = args.get(i);
             if (arg.indexOf('\\n') >= 0) 
                 throw new ZygoteStartFailedEx("embedded newlines not allowed");
             
             writer.write(arg);
             writer.newLine();
         

         writer.flush();

         // Should there be a timeout on this?
         ProcessStartResult result = new ProcessStartResult();
         result.pid = inputStream.readInt();
         if (result.pid < 0) 
             throw new ZygoteStartFailedEx("fork() failed");
         
         result.usingWrapper = inputStream.readBoolean();
         return result;
      catch (IOException ex) 
         zygoteState.close();
         throw new ZygoteStartFailedEx(ex);
     

此方法,将会与ZygoteInit中runSelectLoop()方法启动的socket进程通信,而Zygote进程将会为此Activity创建新的进程,而子进程创建好后,会调用ActivityThread的主线程的main方法,所以继续分析ActivityThread的main方法:

//ActivityThread.java
public static void main(String[] args)
    ...
    AndroidKeyStoreProvider.install();
    ...
    //启动Looper
    Looper.prepareMainLooper();
    //创建ActivityThread,即主线程
    ActivityThread thread = new ActivityThread();
    thread.attach(false);
    //获取主Handler
    if (sMainThreadHandler == null) 
        sMainThreadHandler = thread.getHandler();
    
    ...
    Looper.loop();

此段代码将会创建一个主线程对象ActivityThread,并将启动Looper以及获取主线程的Handler来进行消息处理,并调用attach方法来进行线程处理,继续分析attach方法:

//ActivityThread.java
//此处的system参数为false,即不是系统进程,而在分析AMS的时候,其启动Home界面时,此处为true
private void attach(boolean system)
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) 
        ...
        final IActivityManager mgr = ActivityManagerNative.getDefault();
        try 
            mgr.attachApplication(mAppThread);
         catch (RemoteException ex) 
            // Ignore
        
        ...
    

它调用了AMS的attachApplication方法来对线程进行包装,继续查看attachApplication方法:

//ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread) 
    synchronized (this) 
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    

只是调用了attachApplicationLocked方法:

//ActivityManagerService.java
private final boolean attachApplicationLocked(IApplicationThread thread,int pid)
    //首先获取相应的app
    if (pid != MY_PID && pid >= 0) 
        synchronized (mPidsSelfLocked) 
            app = mPidsSelfLocked.get(pid);
        
     else 
        app = null;
    
    ...
    app.makeActive(thread, mProcessStats);
    app.curAdj = app.setAdj = -100;
    app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
    app.forcingToForeground = null;
    updateProcessForegroundLocked(app, false, false);
    ...
    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
    ...
    thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());
    updateLruProcessLocked(app, false, null);
    app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
    ...

    // 查看该进程是否有栈顶可视的Activity等待运行
    if (normalMode) 
        try 
            //如果有,会调用realStartActivityLocked方法启动此Activity
            if (mStackSupervisor.attachApplicationLocked(app)) 
                didSomething = true;
            
         catch (Exception e) 
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        
    
    return true;

此处回调了ActivityThread的bindApplication方法,通过bindApplication方法来对应用进行相应的初始化,然后调用了ActivityStackSupervisor的attachApplicationLocked方法,它最后会调用realStartActivityLocked方法来真正启动Activity,本节不对Activity的调度做分析,所以先分析bindApplication方法。

//ActivityThread.java
public final void bindApplication(...)
    if (services != null) 
        // Setup the service cache in the ServiceManager
        ServiceManager.initServiceCache(services);
    
    ...
    IPackageManager pm = getPackageManager();
    android.content.pm.PackageInfo pi = null;
    ...
    AppBindData data = new AppBindData();
    data.processName = processName;
    data.appInfo = appInfo;
    ...
    data.persistent = persistent;
    data.config = config;
    data.compatInfo = compatInfo;
    data.initProfilerInfo = profilerInfo;
    //发送BIND_APPLICATION信号给ApplicationThread的H的handler处理
    sendMessage(H.BIND_APPLICATION, data);
    ...

    if (andResume) 
        app.hasShownUi = true;
        app.pendingUiClean = true;
    
    app.forceProcessStateUpTo(mService.mTopProcessState);
    //通过ActivityThread调用scheduleLaunchActivity来启动Activity
    app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,System.identityHashCode(r), 
        r.info, new Configuration(mService.mConfiguration),
        new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
        task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,newIntents, 
    ...

首先通过sendMessage发送BIND_APPLICATION信号给ApplicationThread,ApplicationThread的handler会对此进行处理。至此,有关进程和线程的流程分析结束,其时序图如下:


3.2.2 AMS对Activity的调度分析

上一节分析了进程的创建和主线程的初始化过程,本节将分析AMS对Activity生命周期的管理调度,此处涉及到的主要有如下几个类:ActivityStackSupervisor,ActivityStack,ActivityThread,ApplicationThread,ApplicationThread.H,Instrumentation等。

系统通过AMS来管理应用进程的生命周期,当然包括应用的Activity、Service等的生命周期。AMS是一个独立的进程,因此它要管理应用进程,必然要进行跨进程交互。其交互如下图:

其中:
ActivityManagerProxy——AMS的代理,供应用进程调用。通过ActivityManagerNative.getDefault()获取。
ApplicationThreadProxy——应用进程的代理,供AMS进程调用。应用启动时,会将应用进程的代理传递到AMS跨进程通信,一般都会用到远程代理。ActivityManagerService继承于Binder即它实现了IBinder接口,所以它可以用于进程间通信。在app进程启动时,会建立一个Binder线程池,专门用来处理Binder IPC事物。
在3.2.1节中已经分析了:AMS在启动好了进程之后,会调用realStartActivityLocked方法来启动Activity,所以先看realStartActivityLocked方法:

//ActivityStackSupervisor.java
final boolean realStartActivityLocked(ActivityRecord r,ProcessRecord app, boolean andResume,
         boolean checkConfig) throws RemoteException
    ...
    app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,System.identityHashCode(r),
    r.info, new Configuration(mService.mConfiguration),new Configuration(stack.mOverrideConfig), 
    r.compat, r.launchedFromPackage,task.voiceInteractor, app.repProcState, r.icicle, 
    r.persistentState, results,newIntents, !andResume, mService.isNextTransitionForward(), 
    profilerInfo);
    ...

由代码可知:它是通过调用ActivityThread.ApplicationThread类的scheduleLaunchActivity方法来启动Activity的:

//ActivityThread.java/ApplicationThread内部类
@Override
public final void scheduleLaunchActivity(...)
    updateProcessState(procState, false);
    ActivityClientRecord r = new ActivityClientRecord();
    r.token = token;
    r.ident = ident;
    ...
    r.startsNotResumed = notResumed;
    r.isForward = isForward;
    r.profilerInfo = profilerInfo;
    r.overrideConfig = overrideConfig;
    updatePendingConfiguration(curConfig);

    sendMessage(H.LAUNCH_ACTIVITY, r);

此方法将发送一个LAUNCH_ACTIVITY的Message给ApplicationThread.H的handler进行处理,而此handler将会调用ApplicationThread的handleLaunchActivity进行启动处理:

//ActivityThread.java/ApplicationThread内部类
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent)
    ...
    //确保运行的是最近的配置
    handleConfigurationChanged(null, null);
    ...
    //在create Activity之前intialize
    WindowManagerGlobal.initialize();
    //启动Activity,即OnCreate()
    Activity a = performLaunchActivity(r, customIntent);

    if (a != null) 
        r.createdConfig = new Configuration(mConfiguration);
        Bundle oldState = r.state;
        //调用OnResume()
        handleResumeActivity(r.token, false, r.isForward,!r.activity.mFinished 
            && !r.startsNotResumed);
        ...
    
    ...

如代码:首先调用performLaunchActivity来启动Activity,即调用OnCreate()生命周期,然后会调用handleResumeActivity方法来调用OnResume()生命周期。首先看performLaunchActivity():

//ActivityThread.java/ApplicationThread内部类
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent)
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) 
        //如果packageInfo为空,从ActivityInfo中获取包信息
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
            Context.CONTEXT_INCLUDE_CODE);
    
    //从ActivityClientRecord中获取组件名字
    ComponentName component = r.intent.getComponent();
    if (component == null) 
        //获取组件
        component = r.intent.resolveActivity(mInitialApplication.getPackageManager());
        r.intent.setComponent(component);
    
    if (r.activityInfo.targetActivity != null) 
        //新建组件
        component = new ComponentName(r.activityInfo.packageName,r.activityInfo.targetActivity);
    
    Activity activity = null;
    //创建Activity
    try 
        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess();
        if (r.state != null) 
            r.state.setClassLoader(cl);
        
     catch (Exception e) ...
    ...
    if (r.isPersistable()) 
        //调用OnCreate()方法
        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
     else 
        mInstrumentation.callActivityOnCreate(activity, r.state);
    
    ...
    if (!r.activity.mFinished) 
        activity.performStart();
        r.stopped = false;
    
    ...
    return activity;

此方法将会通过类加载器加载组件并新建Activity,然后通过调用Instrumentation的callActivityOnCreate方法来启动Activity,其方法定义如下:

//Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle,
        PersistableBundle persistentState) 
    prePerformCreate(activity);
    activity.performCreate(icicle, persistentState);
    postPerformCreate(activity);

此方法里调用了performCreate方法:

//Activity.java
final void performCreate(Bundle icicle) 
    onCreate(icicle);
    mActivityTransitionState.readState(icicle);
    performCreateCommon();

显然,它最后会调用定义的Activity的OnCreate()方法,即执行了OnCreate生命周期,同理其他生命周期的执行过程与此类似。OnCreate生命周期的时序图如下:


4、startActivity方法启动Activity的过程分析

本节将对我们熟悉的调用startActivity的启动方式进行分析,同样基于的源码版本是android 6.0,这种情况下,应用进程已经存在,不需要进行应用进程的创建启动(区别于AMS启动Home桌面等启动新应用的方式),首先看startActivity()代码:

@Override
public void startActivity(Intent intent,@Nullable Bundle options)
    if(options != null)
        startActivityForResult(intent,-1,options);
    else
        startActivityForResult(intent,-1);
    

由代码可知,startActivity()最终只是对startActivityForResult()方法进行简单调用,所以只需对startActivityForResult()继续分析:

public void startActivityForResult(Intent intent,int requestCode,@Nullable Bundle options)
    if(mParent == null)
        //执行Activity启动,并返回启动结果
        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;
        
        cancelInputsAndStartExitTransition(options);
    else
        //如果mParent不为空,此时最后还是会调用Instrumentation的execStartActivity()方法
        if(options != null)
            mParent.startActivityFromChild(this,intent,requestCode,options);
        else
            mParent.startActivityFromChild(this,intent,requestCode);
        
    

最后还是会调用Instrumentation的execStartActivity()方法来启动Activity,并将启动的结果返回给该应用的主线程,继续分析execStartActivity()方法:

public ActivityResult execStartActivity(Context who,IBinder contextThread,IBinder token,String 
                            target,Intent intent,int requestCode,Bundle options)
    //获取通信存根类,它派发消息给ActivityThread主线程,而主线程的mH的handler会进行相应处理
    IApplicationThread whoThread = (IApplicationThread)contextThread;
    ...
    try
        intent.migrateExtraStreanToClipData();
        intent.prepareToLeaveProcess();
        //调用AMS的startActivity()方法,即进入AMS的调度管理
        int result = ActivityManagerNative.getDefault().startActivity(whoThread,
            who.getBasePackageName(),intent,intent.resolveTypeIfNeeded(
                who.getContentResolver()),token,target,requestCode,0,null,options); 
        //检查启动结果
        checkStartActivityResult(result,intent);
    catch(RemoteException e)
        throw new RuntimeException("Failure from system",e);
    
    return null;

首先获得IApplicationThread对象,它用于与主线程进行通信,ActivityManagerNative.getDefault()获取的是AMS对象,所以此处将启动任务交给了AMS进行调度管理。startActivity方法会调用startActivityAsUser()方法:

@Override
public final int startActivityAsUser(...)
    userId = handleIncomingUser(Binder.getCallingPid(),Binder.getCallingUid(),userId,false,
        ALLOW_FULL_ONLY,"startActivity",null);
    return mStackSupervisor.startActivityMayWait(caller,-1,callingPackage,intent,resolvedType,
        null,null,resultTo,resultWho,requestCode,startFlags,profierInfo,null,null,options,false,
        userId,null,null);

至此,它的分析同第3节中的过程一致,此处不再做分析,只是本节的启动不需要启动进程,所以它的执行分支不一致。

以上是关于android6.0源码分析之Activity启动过程的主要内容,如果未能解决你的问题,请参考以下文章

源码分析-Activity的启动流程

android6.0源码分析之AMS服务源码分析

android6.0源码分析之Zygote进程分析

android6.0源码分析之Camera API2.0下的video流程分析

android6.0源码分析之Camera API2.0下的video流程分析

android6.0源码分析之Camera API1.0初始化