App启动流程

1.涉及到的类介绍:

因为Android的框架设计时建立在Client-Server结构上,所以下面分Client和Server两端来介绍相关类
Client端:表示一个应用端
Activity:Android中活动组件,每一个Activity多对应一个Window,多个Window叠加后被SurfaceFling处理显示
ActivityThread:Android应用的入口类,主要用于开启消息循环,进程唯一。
ActivityThread.ApplicationThread:IApplicationThread.Stub子类,进程唯一。作为Server端通知Client的通道,实际是通过AIDL
ActivityThread.H:Handler子类,用于将Applicationthread接受到的server消息切换到主线程执行相应方法
Instrumentation:仪表盘
ActivityClientRecord:客户端的Activity的描述对象,每个activity在Client和Server端均有一个描述对象,ActivityClientRecord保存了对应activity基本信息(类名,AndroidManifest文件中的描述信息等),同时还存有该Activity在Server端描述对象的凭证(token)
Server端:表示系统端
ActivityManagerService:系统提供的Activity管理服务,系统唯一,在系统启动后会注册该实例到ServiceManager中
ActivityRecord:Activity对象在Server端的描述对象,是AMS调度的最小单位,和ActivityClientRecord对应,
TaskRecord:存储ActivityRecord的栈结构容器
ActivityStack:存储TaskRecord的栈结构容器,
ActivityStackSupervisor:ActivityStack行为管理对象,
ProcessRecord:应用的进程描述对象
ActivityDisplay:屏幕描述对象,一个实例表示一个屏幕,默认是当前手机屏幕
ActivityStarter:Actvity启动器

2.关联关系:

Untitled drawing.png

3.App启动流程:

点击桌面上某一个App的icon,会触发Launcher类中startActivitySafely方法,Launcher实际上是Actvity的子类,所以实际上会调用到Activity的startActivity方法

Activity.java

void startActivitySafely(Intent intent) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
….
}

查看activity的startActivity方法发现,其最终会调用到startActivityForResult方法

Activity.java
//这里的requestCodo = -1;options = null;
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        ...
    } else {
       ...
    }
}

在startActivityForResult方法中调用了Instrumentation的execStartActivity方法,传入的参数说明如下:
this:当前桌面上下文信息,类型为Context
mMainThread.getApplicationThread():当前为桌面进程的ApplicationThread,IApplication.stub的子类,mMainThread为当前进程的ActivityThread对象,
mToken:IBinder类型,是Activity的成员变量,在attach方法时被赋值初始化,AMS基于该mToken可以获取当前Activity对应的服务器端端ActivityRecord
this:当前桌面Activity ,当前为Launcher对象
intent:待启动Avtivity的信息描述,比如包名,组件名等
requestCode:请求代码,当前为-1
options:携带的参数信息

#Intrumentation.java
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    Uri referrer = target != null ? target.onProvideReferrer() : null;
    if (referrer != null) {
        intent.putExtra(Intent.EXTRA_REFERRER, referrer);
    }
    ...
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        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;
}
#ActivityManager.java
public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

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

通过上面代码,我们可以知道getService()实际上是通过Singleton类获取IActivityManager。注释1处获取到IBinder类型的ActivityManagerService的引用。
SystemServer中调用ActivityManagerService.setSystemProcess(),在setSystemProcess()方法中可以找到以下内容:
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
没错会将ActivityManagerService存储到ServiceManager中进行管理。也就是注释1处通过Context.ACTIVITY_SERVICE查找到IBinder类型的AMS引用。我们再接着看注释2处,看到这里你肯定很清楚,这是AIDL实现,IActivityManager.java会在编译时生成,Stub是其内部类,调用其asInterface()方法会将IBinder转换成IActivityManager接口,如果是跨进程的会为其生成代理Stub.Proxy。ActivityManagerService继承IActivityManager.Stub。
获取到ActivityManagerService实例后,调用起startActivity方法,传入参数说明:
whoThread:launcher进程的ApplicationThread对象
who.getBasePackageName():launcher进程的包名
intent:带启动的activity信息
intent.resolveTypeIfNeeded(who.getContentResolver()):待启动的activity的mimetype,当前为空
token:launcher进程中当前Activity在AMS中存储的ActivityRecord对应的key

ActivityManagerService.java

@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) {
enforceNotIsolatedCaller("startActivity");
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, "startActivityAsUser");
}
AMS的startActivity方法做了两件事:
1.通过用户控制器获取当前来访的进程的UserId
2.将启动Activity的操作委托给了mActivityStarter.startActivityMayWait,mActivityStarter是ActivityStarter类的实例,主要负责Activity启动相关处理

#ActivityStarter.java
final int startActivityMayWait(IApplicationThread caller, int callingUid,
        String callingPackage, Intent intent, String resolvedType,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int startFlags,
        ProfilerInfo profilerInfo, WaitResult outResult,
        Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
        TaskRecord inTask, String reason) {
    …//复制了一个临时的Intent对象
    final Intent ephemeralIntent = new Intent(intent);
    intent = new Intent(intent);
    
    ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
    if (rInfo == null) {
        ...
    }
    // Collect information about the target of the Intent.
    ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

    ActivityOptions options = ActivityOptions.fromBundle(bOptions);
    synchronized (mService) {
        ...

        final ActivityStack stack = mSupervisor.mFocusedStack;
        if (aInfo != null &&
                (aInfo.applicationInfo.privateFlags
                        & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
           ...
        }


        final ActivityRecord[] outRecord = new ActivityRecord[1];
        int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor,
                resultTo, resultWho, requestCode, callingPid,
                callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
                reason);
        ...
    }
}

startActivityMayWait方法主要完成了几件事:
1.复制了一个intent对象,并通过mSupervisor对象查询了该intent对应的ResolveInfo和ActivityInfo对象,这两个对象的内容主要是通过PackageManager查询该进程的AndroidManifest文件生成的
2.将启动Activiy的任务委托给了startActivityLocked方法,而startActivityLocked方法又委托给了startActivity方法

private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
        String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
        String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
        ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
        ActivityRecord[] outActivity, TaskRecord inTask) {
    
    ProcessRecord callerApp = null;
    if (caller != null) {
        callerApp = mService.getRecordForAppLocked(caller);//获取launcher进程的描述对象ProcessRecord,caller为桌面进程的IApplicationThread
        if (callerApp != null) {
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            ...
        }
    }
    final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;

    ActivityRecord sourceRecord = null;//SourceRecord为桌面展示的Activity的AMS端的描述对象
    ActivityRecord resultRecord = null;//
    if (resultTo != null) {
        sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);//resultTo参数launcher进程当前展示的Activity的mToken对象,此处isInAnyStackLocked方法是找到桌面Activity对应在AMS端的记录ActivityRecord对象
    }

    final int launchFlags = intent.getFlags();
    ...

    //resultRecord为空
    final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();
    //检查是否具有启动权限
    boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
            requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity, callerApp,
            resultRecord, resultStack, options);
    abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
            callingPid, resolvedType, aInfo.applicationInfo);
    ...//初始化一些成员

    //创建即将启动的Activity在AMS端的记录
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
            callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
            resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
            mSupervisor, options, sourceRecord);
    if (outActivity != null) {
        outActivity[0] = r;
    }


    if (r.appTimeTracker == null && sourceRecord != null) {
        // If the caller didn't specify an explicit time tracker, we want to continue
        // tracking under any it has.
        r.appTimeTracker = sourceRecord.appTimeTracker;
    }

    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
            options, inTask, outActivity);
}

startActivity方法主要做了下列事情:
1.为接下来启动Activity准备参数:查找launcher进程正在展示的ActivityRecord和创建待启动的ActivityRecord
2.检查启动权限
3.委托startActivity方法去启动,而在startActivity中又委托了startActivityUnchecked方法启动Activity

ActivityStarter.java

//参数说明:
r:上一步创建的描述待启动的ActivityRecord对象
sourceRecord:桌面进程正在展示的Activity的AMS端描述对象
voiceSession:null
voiceInteractor:null
startFlags:0
doResume:true
options:null
inTask:null
outActivity:长度为1的ActivityRecord数组,其元素就是r

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {
    //设置初始化状态,就是设置当前类的一些成员变量值
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
            voiceInteractor);
    //计算mLaunchFlag的值,该方法主要就是给mLaunchFlag添加了FLAG_ACTIVITY_NEW_TASK标记
    computeLaunchingTaskFlags();
    //初始化mSourceStack成员为当前桌面进程的ActivityStack
    computeSourceStack();
    mIntent.setFlags(mLaunchFlags);
    //获取可以重用的ActivityRecord
    ActivityRecord reusedActivity = getReusableIntentActivity();
    if (reusedActivity != null) {
        …//如果有可重用的ACtivityRecord,则会有如下可能处理:
        1.完全符合重用,则会分发onNewIntent方法
        2.如果不符合重用,如启动模式不满足时等,会返回失败码或者新建TaskRecord等操作
    }
    //mStartActivity就是待启动的ActivityRecord,和入餐的r是一样的
    if (mStartActivity.packageName == null) {
        ...
    }
    final ActivityStack topStack = mSupervisor.mFocusedStack;//获取当前有焦点的ActivityStack,即桌面应用所在的栈
    final ActivityRecord topFocused = topStack.topActivity();//桌面进程正在展示的ActivityRecord
    final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);//mNotTop为r,topRunningNonDelayedActivityLocked为找到当前栈内不是mNotTop的且正在展示的ActivityRecord,即top为桌面进程正在展示的ActivityRecord
    final boolean dontStart = top != null && mStartActivity.resultTo == null
            && top.realActivity.equals(mStartActivity.realActivity)
            && top.userId == mStartActivity.userId
            && top.app != null && top.app.thread != null
            && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
            || mLaunchSingleTop || mLaunchSingleTask);
     //dontStart为false
    if (dontStart) {
        如果待启动的Activity和当前栈顶的Activity是同一个,则调用起onNewIntent方法,然后结束本次调用
    }


    boolean newTask = false;
    final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
            ? mSourceRecord.getTask() : null;


    // Should this be considered a new task?
    int result = START_SUCCESS;
    if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
            && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
        newTask = true;
        //创建待启动App的ActivityStack,TaskRecord
        result = setTaskFromReuseOrCreateNewTask(
                taskToAffiliate, preferredLaunchStackId, topStack);
    } else if{
        …
    }

    //检查权限
    mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
            mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
    mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
            mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
    …
   //委托目标栈去启动Activity
    mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
            mOptions);
    if (mDoResume) {
        …//切换Activity,使其onResume等
        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");
            }
            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                    mOptions);
        }
    } else {
        mTargetStack.addRecentActivityLocked(mStartActivity);
    }
    ...更新状态


    return START_SUCCESS;
}

startActivityUnchecked方法做了如下事情:
1.更新ActivityStarter的成员状态,比如launchFlag等
2.创建ActivityStack,TaskRecord等
3.将启动Activity的前置操作委托给起对应的ActivityStack,主要是设置TaskRecord到前台
4.委托ActivityStackSupervisor去执行启动操作

ActivityStack.java

参数说明:
r:待启动的ActivityRecord
focusedTopActivity:桌面进程顶部Activity
newTask:true
keepCurTransition:false
options:null

final void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
        boolean newTask, boolean keepCurTransition, ActivityOptions options) {
    TaskRecord rTask = r.getTask();
    final int taskId = rTask.taskId;
    ...

    // 将待启动的Activity对应的TaskRecord赋值并设为前台Task
    task = activityTask;
    task.setFrontOfTask();


    if (!isHomeOrRecentsStack() || numActivities() > 0) {
        ...
        boolean doShow = true;
        if (newTask) {
            // Even though this activity is starting fresh, we still need
            // to reset it to make sure we apply affinities to move any
            // existing activities from other tasks in to it.
            // If the caller has requested that the target task be
            // reset, then do so.
            if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
                resetTaskIfNeededLocked(r, r);
                doShow = topRunningNonDelayedActivityLocked(null) == r;
            }
        } else if (options != null && options.getAnimationType()
                == ActivityOptions.ANIM_SCENE_TRANSITION) {
            doShow = false;
        }
        if (r.mLaunchTaskBehind) {
            ...
        } else if (SHOW_APP_STARTING_PREVIEW && doShow) {
            …//开启启动窗口
            r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity));
        }
    } 
}
#ActivityStackSupervisor.java
参数说明:
targetStack:待启动的Activity所属的Activity栈
target:待启动的ActivityRecord
targetOptions:携带的参数
boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    //是否已经准备好
    if (!readyToResume()) {
        return false;
    }


    if (targetStack != null && isFocusedStack(targetStack)) {
        //恢复堆栈顶部的活动,将操作重新回归给ActivityStack
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }

    //获取要启动的Activity所在栈的栈顶的处于活动状态的ActivityRecord
    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    if (r == null || r.state != RESUMED) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    } else if (r.state == RESUMED) {
        // Kick off any lingering app transitions form the MoveTaskToFront operation.
        mFocusedStack.executeAppTransition(targetOptions);
    }


    return false;
}
#ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    …
    try {
        // Protect against recursion.
        mStackSupervisor.inResumeTopActivity = true;
        result = resumeTopActivityInnerLocked(prev, options);
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }
    ...
}
#ActivityStack.java
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
     ...
     mStackSupervisor.startSpecificActivityLocked(next, true, true);
     ...
     return true;
}
#ActivityStack.java
void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    // 获取启动Activity所在进程
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);


    r.getStack().setLaunchTime(r);
    // 判断进程是否已运行,这里app值为null
    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);
            }
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }
    }
    //创建进程并启动
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}
#ActivityManagerService.java
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
        boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
        boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
        String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    long startTime = SystemClock.elapsedRealtime();
    ProcessRecord app;

    if (app == null) {
        //创建新进程的描述对象,通过 new ProcessRecord来创建的
        app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
    } else {
        ...
    }
    启动进程,通过Process.start来启动
    startProcessLocked(
            app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
    
    return (app.pid != 0) ? app : null;
}
#ActivityManagerService.java
private final void startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
        //entryPoint的值是null
        boolean isActivityProcess = (entryPoint == null);
        if (entryPoint == null) entryPoint = "android.app.ActivityThread”;//这个熟悉吧
        
        ProcessStartResult startResult;
        //hostingType为“activity”
        if (hostingType.equals("webview_service")) {
            startResult = startWebView(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, null, entryPointArgs);
        } else {
            //调用Process.start方法启动进程,调用ActivityThread.main方法
            startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, invokeWith, entryPointArgs);
        }
}

流程进行到这里,服务器端的初始化已经基本完成,开始准备和新进程进行交互

public static void main(String[] args) {
    //准备主线程的Looper
    Looper.prepareMainLooper();
    //构造方法中会生成ResourcesManager对象
    ActivityThread thread = new ActivityThread();
    //调用attach方法
    thread.attach(false);
    
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
    //开启主线程消息循环
    Looper.loop();


    throw new RuntimeException("Main thread loop unexpectedly exited");
}
private void attach(boolean system) {
    ...
    if (!system) {
        ViewRootImpl.addFirstDrawHandler(new Runnable() {
            @Override
            public void run() {
                ensureJitEnabled();
            }
        });
        final IActivityManager mgr = ActivityManager.getService();
        try {
            mgr.attachApplication(mAppThread);//调用了ActivityManagerService的attchApplication方法
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        ...添加GC观察器
    } else {
        系统进程处理模块
    }
    ...
    ViewRootImpl.addConfigCallback(configChangedCallback);
}
#ActivityManagerService.java
参数说明:
thrade:新进程中的ActivityThread的AppicationThread对象,在创建ACtivityThread对象时生成
@Override
public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}
#ActivityManagerService.java
private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid) {
        if (app.instr != null) {
            thread.bindApplication(processName, appInfo, providers,
                    app.instr.mClass,
                    profilerInfo, app.instr.mArguments,
                    app.instr.mWatcher,
                    app.instr.mUiAutomationConnection, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(getGlobalConfiguration()), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked(),
                    buildSerial);
        } else {
            thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                    null, null, null, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(getGlobalConfiguration()), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked(),
                    buildSerial);
        }

        updateLruProcessLocked(app, false, null);
    } catch (Exception e) {
       ...
    }
    if (mStackSupervisor.attachApplicationLocked(app)) {
        didSomething = true;
    }
    return true;
}

attachApplicationLocked方法做了两件事:
1.调用bindApplication方法,创建Application对象和调用其onCreate方法
2.调用attachApplicationLocked方法,启动Acivity

#ActivityThread.ApplicationThread
public final void bindApplication(String processName, ApplicationInfo appInfo,
        List<ProviderInfo> providers, ComponentName instrumentationName,
        ProfilerInfo profilerInfo, Bundle instrumentationArgs,
        IInstrumentationWatcher instrumentationWatcher,
        IUiAutomationConnection instrumentationUiConnection, int debugMode,
        boolean enableBinderTracking, boolean trackAllocation,
        boolean isRestrictedBackupMode, boolean persistent, Configuration config,
        CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
        String buildSerial) {


    if (services != null) {
        // Setup the service cache in the ServiceManager
        ServiceManager.initServiceCache(services);
    }
   ...
    sendMessage(H.BIND_APPLICATION, data);//发送了H.BIND_APPLICATION消息,最终在主线程调用handleBindApplication方法
}
#ActvityThread.java
private void handleBindApplication(AppBindData data) {
    //生成配置信息对象
    mConfiguration = new Configuration(data.config);
    mCompatConfiguration = new Configuration(data.config);
    ...
    if (ii != null) {
        final ApplicationInfo instrApp = new ApplicationInfo();
        ii.copyTo(instrApp);//复制Application相关信息
        instrApp.initForUser(UserHandle.myUserId());
        final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                appContext.getClassLoader(), false, true, false);
        //生成AppContext对象
        final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);

        try {
            final ClassLoader cl = instrContext.getClassLoader();
            //生成仪表盘对象
            mInstrumentation = (Instrumentation)
                cl.loadClass(data.instrumentationName.getClassName()).newInstance();
        } catch (Exception e) {
        }

        final ComponentName component = new ComponentName(ii.packageName, ii.name);
        //调用init初始化mInstrumentation中的成员变量
        mInstrumentation.init(this, instrContext, appContext, component,
                data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
    } else {
        mInstrumentation = new Instrumentation();
    }

    Application app;
    try {
       //生成Application对象
        app = data.info.makeApplication(data.restrictedBackupMode, null);
        mInitialApplication = app;
        ...
        try {
            //委托仪表盘调用Application的OnCreate方法
            mInstrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {
            ...
        }
    } 
}
#ActivityStackSupervisor.java
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    ...
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            if (!isFocusedStack(stack)) {
                continue;
            }
            stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
            final ActivityRecord top = stack.topRunningActivityLocked();
            final int size = mTmpActivityList.size();
            for (int i = 0; i < size; i++) {
                final ActivityRecord activity = mTmpActivityList.get(i);
                if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                        && processName.equals(activity.processName)) {
                    try {
                        if (realStartActivityLocked(activity, app,
                                top == activity /* andResume */, true /* checkConfig */)) {
                            didSomething = true;
                        }
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Exception in new application when starting activity "
                                + top.intent.getComponent().flattenToShortString(), e);
                        throw e;
                    }
                }
            }
        }
    }
    ...
    return didSomething;
}

attachApplicationLocked方法主要是找到之前创建的ActivityRecord对象,开始启动对应的Activity:

#ActivityStackSupervisor.java
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
        boolean andResume, boolean checkConfig) throws RemoteException {
    ...
    final TaskRecord task = r.getTask();
    final ActivityStack stack = task.getStack();

    try {
        ...
        r.app = app;

        try {
            ...
            //通知客户端进程启动Activity,这里的r.appTolen实在ActivityRecord对象构造函数中初始化的,实际对象为Token,内部持有ActivityRecord的引用,在Activity的attach方法中会将其赋值给mToken,用于后续查找该ActivityRecord对象
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info,
                    // TODO: Have this take the merged configuration instead of separate global
                    // and override configs.
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);
            ...
        } catch (RemoteException e) {
        }
    } 
    ...
    return true;
}
#ActivityThread.ApplicationThread
@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) {
    //创建客户端的Activity的描述对象
    ActivityClientRecord r = new ActivityClientRecord();
    r.token = token;
    …赋值操作
    sendMessage(H.LAUNCH_ACTIVITY, r);//消息的接受者会执行handleLaunchActivity方法
}
#ActivityThread.java
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    //初始化全全局窗口配置
    WindowManagerGlobal.initialize();
    //分发performLaunchActivity方法
    Activity a = performLaunchActivity(r, customIntent);

    if (a != null) {
        ...
        //分发onResume方法
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
        ...
    } else {
        ...
    }
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
        //初始化包信息
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }
    ...
    //创建ContextImpl对象
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        //创建Activity对象
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        ...
    } catch (Exception e) {
    }


    try {
        if (activity != null) {
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = new Configuration(mCompatConfiguration);
            appContext.setOuterContext(activity);
            //调用Activity的attach方法,注意其第四个参数
            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);
            …//调用Activity的onCreate方法
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            //分发onStart方法
            if (!r.activity.mFinished) {
                activity.performStart();
                r.stopped = false;
            }
            if (!r.activity.mFinished) {
                if (r.isPersistable()) {
                    if (r.state != null || r.persistentState != null) {
                        //分发OnRestoreInstanceState方法,如果需要
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                r.persistentState);
                    }
                } else if (r.state != null) {
                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                }
            }
            ...
        }
    } 

    return activity;
}

4.参考资料:
Activity管理方式
App启动流程8.0
App启动流程-老罗
launcher.java

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,248评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,681评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,443评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,475评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,458评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,185评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,451评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,112评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,609评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,083评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,163评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,803评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,357评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,357评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,590评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,636评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,925评论 2 344

推荐阅读更多精彩内容