Activity的启动流程分析与总结

前言

​ 看了数片分析Activity启动流程的文章,但是自从看了《Android进阶解密》关于Activity启动流程的分析,我就放弃了自己撸一遍的念头。因为书里关于这部分的分析比较详细。这里记录一下书中关于Activity的启动流程。加深一下印象,便于以后温习查看。
Activity的启动过程分为两种,一种是根Activity的启动过程,可以认为是初次点击桌面的应用图标,启动Manifest中注册的作为应用的启动页面的Activity。根Activity的启动过程也可以理解为应用程序的启动过程。另一种就是普通Activity的启动过程,也就是根Activity以外的Activity的启动过程。这两种Activity的启动过程有重叠的部分,但是根Activity一般理解为应用程序的启动过程,更具有指导意义。因此本文就根Activity的启动过程进行分析。

谈到Activity的启动流程就绕不开ActivityManagerService(简称AMS),它主要负责四大组件的启动、切换、调度以及进程的管理,是Android中最核心的服务,参与了所有应用程序的启动管理。Activity的启动流程围绕AMS,可以大致分为3个部分:

  • Launcher请求AMS的过程
  • AMS到ApplicationThread的调用过程
  • ActivityThread启动Activity的过程

下面就针对这3个部分逐一进行分析。

1.Launcher请求AMS的过程

该过程的时序图如下:

在这里插入图片描述
当我们点击桌面的应用快捷图标时,就会调用Launcher的startActivitySafely方法:

public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
    ...
    // Prepare intent
    // 注释1
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    ...
            // Could be launching some bookkeeping activity
        	// 注释2
            startActivity(intent, optsBundle);
    ...
}

对于不太需要关注的代码省略了,主要是走调用流程,对关键代码进行分析,在注释1处将Flag设置为Intent.FLAG_ACTIVITY_NEW_TASK,这样根Activity会在新的任务栈中启动。在注释2处调用startActivity方法,这个方法在Activity中实现,Activity中startActivity方法有好几种重载方式,但它们最终都会调用startActivityForResult方法:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
    	// 注释1
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            // 注释2
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            ...
        } else {
            ...
        }
    }

注释1处的mParent是Activity类型的,表示当前Activity的父类,因为目前根Activity还没有创建出来,因此mParent==null成立,执行注释2处的逻辑,调用Instrumentation的execStartActivity方法,Instrumentation主要是用来监控应用程序和系统的交互,execStartActivity方法代码如下:

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        ...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            // 注释1
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

核心逻辑就是注释1的代码,首先调用ActivityManager的getService方法来获取AMS的代理对象,接着调用startActivity方法。我们先进入ActivityManager的getService方法:

public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
        	@Override
            protected IActivityManager create() {
                // 注释1
            	final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                // 注释2
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                return am;
            }
 		};

getService方法调用了IActivityManagerSingleton的get方法,看一下Singleton代码

public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

不难发现IActivityManagerSingleton的get方法,会调用create方法,在注释1处得到IBinder类型的AMS引用,接着在注释2处将它转化成IActivityManager类型的对象,即AMS的代理对象,这段代码采用的是AIDL,IActivityManager.java类是由AIDL工具在编译时自动生成的。AMS继承IActivityManager.Stub类并实现相关方法。通过这个代理对象和AMS(AMS所在的进程为SystemServer系统服务进程)进行跨进程通信,如果你对Binder机制有一定的认识,这里就比较好理解。如果还不太熟悉Binder机制,强烈建议一定要补一下,要不然分析源码总会一知半解的。需要注意的Android8.0之前并没有采用AIDL,是用AMS的代理对象ActivityManagerProxy来与AMS进行跨进程通信的。Android8.0去除了ActivityManagerNative的内部类ActivityManagerProxy,代替它的是IActivityManager,它就是AMS的代理对象。经过上面的分析,我们知道execActivity方法最终调用的是AMS的startActivity方法。补充一句,这里就由Launcher进程经过一系列调用到了SystemServer进程,可以简单概括为下图:

在这里插入图片描述

2.AMS到ApplicationThread的调用过程

Launcher请求AMS后,代码逻辑进入AMS中,接着是AMS到ApplicationThread的调用流程,时序图如下:
在这里插入图片描述

AMS的startActivity方法如下:

@Override
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());
}

AMS的startActivity方法中返回了startActivityAsUser方法,可以发现startActivityAsUser方法比startActivity方法多了一个参数UserHandle.getCallingUserId(),这个方法会获得调用者的UserId,AMS根据这个UserId来确定调用者的权限。下面进入startActivityAsUser方法:

@Override
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) {
    // 注释1
    // 判断调用者进程是否被隔离
    enforceNotIsolatedCaller("startActivity");
    // 注释2
    // 检查调用者的权限
    userId = mUserController.handleIncomingUser(Binder.getCallingPid(), 		             Binder.getCallingUid(),userId, false, ALLOW_FULL_ONLY, "startActivity", null);
    // TODO: Switch to user app stacks here.
    return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,profilerInfo,     null, null, bOptions, false, userId, null, null,"startActivityAsUser");
}

在注释1处判读调用者进程是否隔离,如果没被隔离则抛出SecurityException异常,在注释2处检查调用者是否有权限,如果没有权限也会抛出SecurityException异常。最后调用了ActivityStarter的startActivityMayWait方法,参数要比startActivityAsUser多几个,需要注意的是倒数第二个参数类型为TaskRecord,代表启动的Activity所在的栈,最后一个参数"startActivityAsUser"代表启动的理由,接下来进入startActivityMayWait方法:

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,IActivityContainer iContainer, TaskRecord inTask, String reason) {
	...
    int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
    	aInfo, rInfo, voiceSession, voiceInteractor,
    	resultTo, resultWho, requestCode, callingPid,
    	callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
        options, ignoreTargetSecurity, componentSpecified, outRecord, container,
        inTask, reason);
        ...
        return res;
     }
}

ActivityStarter是Android7.0中新加入的类,它是加载Activity的控制类,会收集所有的逻辑来决定如何将Intent和Flags转换为Activity,并将Activity和Task以及Stack相关联。ActivityStarter的startActivityMayWait方法调用了startActivityLocked方法:

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, ActivityStackSupervisor.ActivityContainer container,
    TaskRecord inTask, String reason) {
	// 注释1
    // 判断启动
    if (TextUtils.isEmpty(reason)) {
    	throw new IllegalArgumentException("Need to specify a reason.");
    }
    
    mLastStartReason = reason;
    mLastStartActivityTimeMs = System.currentTimeMillis();
    mLastStartActivityRecord[0] = null;
	// 注释2
    mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, 			     resolvedType,aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, 		requestCode,callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, 	startFlags,options, ignoreTargetSecurity, componentSpecified,                    	     mLastStartActivityRecord,container, inTask);
    if (outActivity != null) {
        // mLastStartActivityRecord[0] is set in the call to startActivity above.
        outActivity[0] = mLastStartActivityRecord[0];
    }
    return mLastStartActivityResult;
}

在注释1处判断启动的理由不为空,如果为空则抛出IllegalArgumentException异常。紧接着在注释2处又调用了startActivity方法:

/** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */
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, ActivityStackSupervisor.ActivityContainer container,
    TaskRecord inTask) {
    
    int err = ActivityManager.START_SUCCESS;
    // Pull the optional Ephemeral Installer-only bundle out of the options early.
    final Bundle verificationBundle
    	= options != null ? options.popAppVerificationBundle() : null;

    ProcessRecord callerApp = null;
    // 注释1
    // caller为IApplicationThread类型
    if (caller != null) {
        // 注释2
        // 得到Launcher进程
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            // 获取Launcher进程的pid和uid
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            Slog.w(TAG, "Unable to find app for caller " + caller
                   + " (pid=" + callingPid + ") when starting: "
                   + intent.toString());
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }
    ...
    // 注释3
    // 创建即将要启动的Activity的描述类ActivityRecord
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
    	callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
        resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
        mSupervisor, container, options, sourceRecord);
    if (outActivity != null) {
        // 注释4
        outActivity[0] = r;
    }

    ...

    doPendingActivityLaunchesLocked(false);
    // 注释5
    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, 				true,options, inTask, outActivity);
    }

ActivityStarter的startActivity方法逻辑比较多,这里列出部分需要注意的代码。在注释1处判断IApplicationThread类型的caller是否为null,这个caller是方法调用一路传过来的,指向的是Launcher所在的应用程序进程的ApplicationThread对象,在注释2处调用AMS的getRecordForAppLocked方法得到的是代表Launcher进程的callApp对象,它是ProcessRecord类型的,ProcessRecord用于描述一个应用程序进程。同样的,ActivityRecord用于描述一个Activity,用来记录一个Activity的所有信息。接下来创建ActivityRecord,用于描述将要启动的Activity,并在注释4处将创建的ActivityRecord赋值给ActivityRecord[]类型的outActivity,这个outActivity会作为注释5处的startActivity方法的参数传递下去。

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
	IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
    int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
    ActivityRecord[] outActivity) {
    
    int result = START_CANCELED;
    try {
    	mService.mWindowManager.deferSurfaceLayout();
        // 注释1
        result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
             startFlags, doResume, options, inTask, outActivity);
    } 
    ...
    return result;
}

startActivity方法接着调用了startActivityUnchecked方法:

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {

        ...
        // 注释1
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            // 注释2
            // 创建新的TaskRecord
            result = setTaskFromReuseOrCreateNewTask(
                    taskToAffiliate, preferredLaunchStackId, topStack);
        } else if (mSourceRecord != null) {
            result = setTaskFromSourceRecord();
        } else if (mInTask != null) {
            result = setTaskFromInTask();
        } else {
            // This not being started from an existing activity, and not part of a new task...
            // just put it in the top task, though these days this case should never happen.
            setTaskToCurrentTopOrCreateNewTask();
        }
    	...
            
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
 			...
            } else {
                if (mTargetStack.isFocusable() && 															!mSupervisor.isFocusedStack(mTargetStack)) {
                    	mTargetStack.moveToFront("startActivityUnchecked");
                }
                // 注释3
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, 							mStartActivity,mOptions);
            }
        } else {
            mTargetStack.addRecentActivityLocked(mStartActivity);
        }
        ...
    }

startActivityUnchecked方法主要处理与栈管理相关的逻辑。在前面Launcher的startActivitySafely中,将Intent的Flag设置为FLAG_ACTIVITY_NEW_TASK,这样注释1处的条件判断就会满足,接着执行注释2处的setTaskFromReuseOrCreateNewTask方法内部会创建一个新的Activity任务栈。在注释3处会调用ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法:

boolean resumeFocusedStackTopActivityLocked(
    	ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions){
    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }
    // 注释1
    // 获取要启动的Activity所在的栈的栈顶的不是处于停止状态的ActivityRecord
    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    // 注释2
    if (r == null || r.state != RESUMED) {
        // 注释3
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    } else if (r.state == RESUMED) {
        // Kick off any lingering app transitions form the MoveTaskToFront operation.
        mFocusedStack.executeAppTransition(targetOptions);
    }
    return false;
}

注释1处调用ActivityStack的topRunningActivityLocked方法获取要启动的Activity所在栈的栈顶并且不是停止状态的ActivityRecord。在注释2处,如果ActivityRecord不为null,或者要启动的Activity的状态不是RESUMED状态,就会调用注释3处的ActivityStack的resumeTopActivityUncheckedLocked方法,对于即将启动的Activity,注释2处条件判断是肯定满足的,接下来查看ActivityStack的resumeTopActivityUnchecked方法:

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    if (mStackSupervisor.inResumeTopActivity) {
        // Don't even start recursing.
        return false;
    }

    boolean result = false;
    try {
        // Protect against recursion.
        mStackSupervisor.inResumeTopActivity = true;
        // 注释1
        result = resumeTopActivityInnerLocked(prev, options);
    } 
    ...
}

紧接着查看注释1处的ActivityStack的resumeTopActivityInnerLocked方法:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions 			options) { 
    ...
        	// 注释1
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }

        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }

接着进入注释1处,ActivityStackSupervisor的startSpecificActivityLocked方法

void startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    // 注释1
    // 获取即将启动的Activity的所在的应用进程
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                        r.info.applicationInfo.uid, true);

    r.getStack().setLaunchTime(r);
	// 注释2
    // 判断要启动的Activity所在的应用程序进程如果已经运行的话,就会调用注释3处
    if (app != null && app.thread != null) {
        try {
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                || !"android".equals(r.info.packageName)) {
                    
                app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                // 注释3
                // 这个方法第二个参数是代表要启动的Activity所在的应用程序进程的ProcessRecord
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

​ 在注释1处获取即将启动的Activity所在的应用程序进程,在注释2处判断要启动的Activity所在的应用程序进程如果已经运行的话,就会调用注释3处的realStartActivityLocked方法,这个方法的第二个参数是代表要启动的Activity所在的应用程序进程的ProcessRecord。接下来进入realStartActivityLocked方法:

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
      boolean andResume, boolean checkConfig) throws RemoteException {
    ...
    // 注释1
    // app是ProcessRecord类型的,thread是IApplicationThread类型的 
	app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
    	System.identityHashCode(r), r.info,
        mergedConfiguration.getGlobalConfiguration(),
        mergedConfiguration.getOverrideConfiguration(), r.compat,
        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
        r.persistentState, results, newIntents, !andResume,
        mService.isNextTransitionForward(), profilerInfo);
        ...
        return true;
}

​ 注释1处的app.thread指的是IApplicationThread,其中ApplicationThread继承了IApplicationThread.Stub。app指的是传入的要启动的Activity所在的应用程序进程,因此这段代码指的就是要在目标应用程序进程启动Activity。当前代码逻辑运行在AMS所在的进程(SystemServer系统服务进程)中,通过ApplicationThread来与应用程序进程进程Binder通信(跨进程通信),也就是说ApplicationThread是AMS和应用程序进程的通信桥梁

在这里插入图片描述

3.ActivityThread启动Activity的过程

通过前面的分析,我们知道代码逻辑目前运行到应用程序进程中,ActivityThread启动Activity过程时序图如下:

在这里插入图片描述

接着查看ApplicationThread的scheduleLaunchActivity方法,ApplicationThread是ActivityThread的内部类,ActivityThread负责管理当前应用程序进程的主线程,scheduleLaunchActivity方法代码如下:

@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
		ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
		CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
		int procState, Bundle state, PersistableBundle persistentState,
		List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
		boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

	updateProcessState(procState, false);
	// 此处的r就是保存要启动activity的信息,作为参数通过sendMessage发送出去
	ActivityClientRecord r = new ActivityClientRecord();

    r.token = token;
    r.ident = ident;
    r.intent = intent;
    r.referrer = referrer;
    ...
    updatePendingConfiguration(curConfig);
    sendMessage(H.LAUNCH_ACTIVITY, r);
}

​ scheduleLaunchActivity方法将启动Activity的参数封装成ActivityClientRecord。sendMessage方法向H类发送类型为LAUNCH_ACTIVITY的消息,并将ActivityClientRecord传递出去,sendMessage方法有多个重载,最终调用的sendMessage方法如下:

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
    if (DEBUG_MESSAGES) Slog.v(
        TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
        + ": " + arg1 + " / " + obj);
    Message msg = Message.obtain();
    msg.what = what;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    if (async) {
        msg.setAsynchronous(true);
    }
    mH.sendMessage(msg);
}

​ 这里的mH指的是H,它是ActivityThread的内部类并继承Handler,是应用程序进程中主线程的消息管理类。因为ApplicationThread是一个Binder,它的调用逻辑运行在Binder线程池(子线程)中,所以这里需要用H将代码的逻辑切换到主线程中。H类中处理消息的handleMessage方法如下:

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");
            // 注释1
            // 取出之前保存的要启动的Activity的信息
            // 这些信息封装在ActivityClientRecord这个类中
            final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
			// 注释2
            // pachageinfo 指的是LoadedApk
            r.packageInfo = getPackageInfoNoCheck(
                r.activityInfo.applicationInfo, r.compatInfo);
            handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        } break;
        case RELAUNCH_ACTIVITY: {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
            ActivityClientRecord r = (ActivityClientRecord)msg.obj;
            handleRelaunchActivity(r);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        } break;
        ...
    }
    ...
}

查看H类中handleMessage方法中对LAUNCH_ACTIVITY的处理,在注释1处将传过来的msg的成员变量obj转换为ActivityClientRecord。在注释2处通过getPackageInfoNoCheck方法获得LoadedApk类型的对象并赋值给ActivityClientRecord的成员变量packageInfo。应用程序要启动Activity时需要将该Activity所属的APK加载进来,而LoadedApk就是用来描述已加载的APK文件的。接着调用handleLaunchActivity方法:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String 		reason) {
	...   

    // Initialize before creating the activity
    WindowManagerGlobal.initialize();
	// 注释1
    // 启动Activity
    Activity a = performLaunchActivity(r, customIntent);

    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        reportSizeConfigurations(r);
        Bundle oldState = r.state;
        // 注释2
        // 将Activity的状态置为Resume
        handleResumeActivity(r.token, false, r.isForward,
              !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

        if (!r.activity.mFinished && r.startsNotResumed) {

            performPauseActivityIfNeeded(r, reason);

            if (r.isPreHoneycomb()) {
                r.state = oldState;
            }
        }
    } else {
        // If there was an error, for any reason, tell the activity manager to stop us.
        try {
            // 注释3
            // 停止Activity启动
            ActivityManager.getService()
                .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }
}

​ 注释1处的performLaunchActivity方法用来启动Activity,注释2处的代码用来将Activity的状态设置为Resume,如果该Activity为null,就会执行注释3处的逻辑,通知AMS停止启动Activity,接下来进入performLaunchActivity:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) 
	// 注释1 
    // 获取ActivityInfo类
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
        // 注释2 
        // 获取APK文件的描述类
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                                       Context.CONTEXT_INCLUDE_CODE);
    }
	// 注释3
	// 获取要启动Activity的ComponentName类,它保存了该Activity的包名和类名
    ComponentName component = r.intent.getComponent();
    ...
	// 注释4
    // 创建要启动Activity的上下文
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        // 注释5
        // 通过类加载器来创建要启动的Activity的实例
        activity = mInstrumentation.newActivity(
            cl, component.getClassName(), r.intent);
        ...
        }
    } catch (Exception e) {
        ...
    }

    try {
        // 注释6
        // 创建Application
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        ...
        if (activity != null) {
            ...
            // 注释7
            // 初始化Activity
            activity.attach(appContext, this, getInstrumentation(), r.token,
                            r.ident, app, r.intent, r.activityInfo, title, r.parent,
                            r.embeddedID, r.lastNonConfigurationInstances, config,
                            r.referrer, r.voiceInteractor, window, r.configCallback);

            ...
            if (r.isPersistable()) {
                // 注释8
          		// 顾名思义下一步就是去调用Activity的onCreate方法
                mInstrumentation.callActivityOnCreate(activity, r.state, 								r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            ...
        r.paused = true;
        mActivities.put(r.token, r);

    } catch (SuperNotCalledException e) {
        throw e;
    } catch (Exception e) {
        ...
    }
    return activity;
    }

​ 在注释1处获取ActivityInfo,用于存储代码以及AndroidManifest设置的Activity和Receiver节点信息,比如Activity的theme和launchMode。在注释2处获取APK文件的描述类LoadedApk。在注释3处获取要启动的Activity的ComponentName类,在该类中保存了Activity的包名和类名。注释4处用来创建要启动Activity的上下文环境。注释5处根据ComponentName中存储的Activity类名,用类加载器来创建该Activity的实例。注释6处用来创建Application,makeApplication方法内部会调用Application的onCreate方法。注释7处调用Activity的attach方法初始化Activity,在attach方法中会创建Window对象(PhoneWindow)并与Activity自身进行关联。在注释8处调用Instrumentation的callActivityOnCreate方法:

public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
    prePerformCreate(activity);
    activity.performCreate(icicle, persistentState);
    postPerformCreate(activity);
}

进入activity的performCreate方法:

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    restoreHasCurrentPermissionRequest(icicle);
    // 注释1
    // 正式进入Activity的生命周期方法
    onCreate(icicle, persistentState);
    mActivityTransitionState.readState(icicle);
    performCreateCommon();
}

​ 如注释1处代码所示,正式进入Activity的生命周期方法,根Activity的启动流程大致分析完了,下面对大致流程进行小结一下。

4.总结

根Activity的启动过程涉及4个进程,分别是Launcher进程、AMS所在进程(SystemServer进程)、Zygote进程、应用程序进程,首先Launcher进程向AMS请求创建根Activity,AMS会判断根Activity所需要的应用程序进程是否存在并启动,如果不存储就会请求Zygote进程创建应用程序进程。应用程序进程启动后,AMS会请求应用程序进程启动根Activity。

原创文章 23 获赞 30 访问量 9557

猜你喜欢

转载自blog.csdn.net/my_csdnboke/article/details/106173074