Android 7.0 ActivityManagerService(3) 启动Activity的过程:二

来源:互联网 发布:win10设置java环境变量 编辑:程序博客网 时间:2024/06/03 22:42

这一篇博客,我们将继续学习Activity的启动流程。
在启动Activity的过程:一中,我们的流程最终分析到AMS通过zygote启动Activity对应的进程,现在我们看看后续的过程如何进行。
关于zygote启动进程的流程,可以参考Android6.0 SystemServer进程。这篇文章中,分析了zygote如何启动SystemServer进程和普通进程。虽然分析的是Android M的代码,但与android N的思路基本一致。

一、ActivityThread的main函数

通过zygote启动进程时,传入的className为android.app.ActivityThread。
因此,当zygote通过反射调用进程的main函数时,ActivityThread的main函数将被启动:

public static void main(String[] args) {    ..................    //开始信息采样    SamplingProfilerIntegration.start();    // CloseGuard defaults to true and can be quite spammy.  We    // disable it here, but selectively enable it later (via    // StrictMode) on debug builds, but using DropBox, not logs.    //和调试有关    CloseGuard.setEnabled(false);    //得到当前进程的UserEnvironment    Environment.initForCurrentUser();    ...............    // Make sure TrustedCertificateStore looks in the right place for CA certificates    // 确保进程能够得到CA证书的路径    final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());    TrustedCertificateStore.setDefaultUserDirectory(configDir);    Process.setArgV0("<pre-initialized>");    //准备主线程的Looper    Looper.prepareMainLooper();    //创建当前进程的ActivityThread    ActivityThread thread = new ActivityThread();    //调用attach函数    thread.attach(false);    if (sMainThreadHandler == null) {        //保存进程对应的主线程Handler        sMainThreadHandler = thread.getHandler();    }    .........    //进入主线程的消息循环    Looper.loop();    throw new RuntimeException("Main thread loop unexpectedly exited");}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

从上述代码可以看出,ActivityThread的main函数最主要工作是:
1、创建出一个Looper,并将主线程加入到消息循环中。
2、创建出ActivityThread,并调用其attach函数。

在介绍AMS的启动过程时,我们就提到了ActivityThread。
当时从代码中,我们知道SystemServer进程,为了融入Android体系,调用createSystemContext函数。
在createSystemContext函数中,SystemServer进程创建了自己的ActivityThread,并调用了attach函数。
通过比对代码容易看出,SystemServer进程作为系统进程,attach参数为true,而普通进程传入的参数为false。

现在,我们重新看看ActivityThread的attach函数,这次侧重于普通进程的部分:

private void attach(boolean system) {    sCurrentActivityThread = this;    mSystemThread = system;    if (!system) {        ViewRootImpl.addFirstDrawHandler(new Runnable() {            @Override            public void run() {                //JIT-Just in time                //JIT技术主要是对多次运行的代码进行编译,当再次调用时使用编译之后的机器码,而不是每次都解释,以节约时间                //JIT原理:                //每启动一个应用程序,都会相应地启动一个dalvik虚拟机,启动时会建立JIT线程,一直在后台运行。                //当某段代码被调用时,虚拟机会判断它是否需要编译成机器码,如果需要,就做一个标记。                //JIT线程在后台检测该标记,如果发现标记被设定,就把对应代码编译成机器码,并将其机器码地址及相关信息保存起来                //当进程下次执行到此段代码时,就会直接跳到机器码执行,而不再解释执行,从而提高运行速度                //这里开启JIT,应该是为了提高android绘制的速度                ensureJitEnabled();            }        });        //设置在DDMS中看到的进程名为"<pre-initialized>"        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId());        //设置RuntimeInit的mApplicationObject参数        RuntimeInit.setApplicationObject(mAppThread.asBinder());        final IActivityManager mgr = ActivityManagerNative.getDefault();        try {            //与AMS通信,调用其attachApplication接口            mgr.attachApplication(mAppThread);        } catch (RemoteException ex) {            throw ex.rethrowFromSystemServer();        }        // Watch for getting close to heap limit.        // 监控GC操作; 当进程内的一些Activity发生变化,同时内存占用量较大时        // 通知AMS释放一些Activity        BinderInternal.addGcWatcher(new Runnable() {            public void run() {                if (!mSomeActivitiesChanged) {                    return;                }                Runtime runtime = Runtime.getRuntime();                long dalvikMax = runtime.maxMemory();                long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();                //判断内存占用量是否过大                if (dalvikUsed > ((3*dalvikMax)/4)) {                    ...........                    mSomeActivitiesChanged = false;                    try {                        //通知AMS释放一些Activity,以缓解内存紧张                        mgr.releaseSomeActivities(mAppThread);                    } catch (RemoteException e) {                        throw e.rethrowFromSystemServer();                    }                }            }        });    } else {        .............    }    ........}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

在分析Activity启动过程的第一部分时,我们提到过AMS创建一个应用进程后,会设置一个超时时间。
如果超过这个时间,应用进程还没有和AMS交互,AMS就认为该进程创建失败。
因此,应用进程启动后,需要尽快和AMS交互。

上述代码中,attachApplication就是应用进程与AMS交互的接口。

二、AMS的attachApplication函数

我们进入AMS看看attachApplication相关的流程。

public final void attachApplication(IApplicationThread thread) {    synchronized (this) {        int callingPid = Binder.getCallingPid();        final long origId = Binder.clearCallingIdentity();        //进一步调用attachApplicationLocked函数        attachApplicationLocked(thread, callingPid);        Binder.restoreCallingIdentity(origId);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

attachApplicationLocked函数比较长,分段来看一下。

1 Part-I

private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {    ProcessRecord app;    //根据pid查找对应的ProcessRecord对象    if (pid != MY_PID && pid >= 0) {        synchronized (mPidsSelfLocked) {            app = mPidsSelfLocked.get(pid);        }    } else {        app = null;    }    //如果进程由AMS启动,则它在AMS中一定有对应的ProcessRecord    //此处app为null,则表示AMS没有该进程的记录,故需要kill掉此异常进程    if (app == null) {        ................        if (pid > 0 && pid != MY_PID) {            //pid大于0且不是系统进程,则直接kill掉            //将调用android_util_Process.cpp中的android_os_Process_sendSignalQuiet函数            //最终通过kill函数杀死进程,kill函数要求pid > 0            Process.killProcessQuiet(pid);        } else {            try {                //pid < 0时,fork进程失败,因此仅上层完成清理工作即可                //调用ApplicationThread的scheduleExit函数                //应用进程将进行一些扫尾工作,例如结束消息循环,然后退出运行                thread.scheduleExit();            } catch (Exception e) {                // Ignore exceptions.            }        }        return false;    }    // If this application record is still attached to a previous    // process, clean it up now.    // 判断pid对应processRecord的IApplicationThread是否为null    // AMS创建ProcessRecord后,在attach之前,正常情况下IApplicationThread应该为null    // 特殊情况下:如果旧应用进程被杀死,底层对应的pid被释放,在通知到达AMS之前(AMS在下面的代码里注册了“讣告”接收对象),    // 用户又启动了一个新的进程,新进程刚好分配到旧进程的pid时    // 此处得到的processRecord可能就是旧进程的,于是app.thread可能不为null,因此需要作判断和处理    if (app.thread != null) {        handleAppDiedLocked(app, true, true);    }    ...................    final String processName = app.processName;    try {        //创建一个“讣告”接收对象,注册到应用进程的ApplicationThread中        //当应用进程退出时,该对象的binderDied将被调用,这样AMS就能做相应的处理        //binderDied函数将在另一个线程中被调用,其内部也会调用handleAppDiedLocked函数        AppDeathRecipient adr = new AppDeathRecipient(                app, pid, thread);        thread.asBinder().linkToDeath(adr, 0);        app.deathRecipient = adr;    } catch (RemoteException e) {        app.resetPackageList(mProcessStats);        startProcessLocked(app, "link fail", processName);        return false;    }    设置app的一些变量,例如调度优先级和oom_adj相关的成员    .................    //启动成功,从消息队列中移除PROC_START_TIMEOUT_MSG    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);    .................
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

至此,attachApplicationLocked的第一部分介绍完毕。
这部分代码的核心功能比较简单,其实就是:
1、判断进程的有效性,同时注册观察者监听进程的死亡信号。
2、设置pid对应的ProcessRecord对象的一些成员变量,例如和应用进程交互的IApplicationThread对象、进程调度的优先级等。
3、进程注册成功,AMS从消息队列中移除PROC_START_TIMEOUT_MSG。

2 Part-II

现在,我们看看attachApplicationLocked第二部分的代码:

..............//AMS正常启动后,mProcessesReady就已经变为true了boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);//generateApplicationProvidersLocked将通过PKMS查询定义在进程中的ContentProvider,并将其保存在AMS的数据结构中List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;//这里应该是处理:加载ContentProvider时,启动进程的场景//checkAppInLaunchingProvidersLocked主要将当前启动进程的ProcessRecord,和AMS中mLaunchingProviders的ProcessRecord进行比较//当判断出该进程是由于启动ContentProvider而被加载的,那么就发送一个延迟消息(10s)//通过这里可以看出,当由于加载ContentProvider启动进程时,在进程启动后,ContentProvider在10s内要完成发布if (providers != null && checkAppInLaunchingProvidersLocked(app)) {    Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);    msg.obj = app;    mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);}...........try {    ...........    //回调进程ApplicationThread的bindApplication接口    thread.bindApplication(..........);    //更新进程调度策略    updateLruProcessLocked(app, false, null);    ..............} catch () {    ............    app.resetPackageList(mProcessStats);    app.unlinkDeathRecipient();    //这里的策略比较激进,当bindApplicaiton失败后,将直接重新启动这个进程    startProcessLocked(app, "bind fail", processName);    return false;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

从代码来看,第二阶段最核心工作就是:
调用进程ApplicationThread的bindApplication函数,接下来我们分析一下该函数。

2.1 ApplicationThread的bindApplication函数

从之前的代码,我们知道应用进程由zygote fork得到,然后调用ActivityThread的main函数,进入到Java世界。
但是截至目前,该进程并没有融入到Android的体系中,因此仅能被称为一个Java进程,甚至连进程名也只是“敷衍”地定义为“pre-initialized”。

我们之前分析AMS启动过程时,介绍了SystemServer的createSystemContext函数。
在该函数中,SystemServer在自己的进程中,创建出Android运行环境,才摇身一变成为了Android进程。
同样,此处的bindApplication函数,就是在新进程中创建并初始化对应的Android运行环境。

现在,我们看看bindApplication函数的主要流程:

//参数较多,无需深究,重要的从代码流程中就能知道含义public final void bindApplication(.......) {    //按照string-IBinder的方式,保存AMS传递过来的系统service的Binder接口    //这样进程与系统服务通信时,就不需要先通过SystemServer查询了    if (services != null) {        // Setup the service cache in the ServiceManager        ServiceManager.initServiceCache(services);    }    //内部发送H.SET_CORE_SETTINGS消息    //由handleSetCoreSettings进行处理,主要用于保存新的信息    setCoreSettings(coreSettings);    //用AppBindData对象保存参数对应的信息    AppBindData data = new AppBindData();    data.processName = processName;    data.appInfo = appInfo;    data.providers = providers;    ..................    //发送消息    sendMessage(H.BIND_APPLICATION, data);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

由以上代码可知,ApplicationThread的接口被AMS调用后,会将参数保存到AppBindData对象中,然后发送消息让ActivityThread的主线程处理。
由此可以看出,对应用进程而言,ApplicationThread只是与AMS通信的接口,实际的工作一般还是会交给ActivityThread来完成。

ActivityThread中处理该消息的实际函数为handleBindApplication,我们看看这个函数的内容。

2.2 handleBindApplication函数

private void handleBindApplication(AppBindData data) {    // Register the UI Thread as a sensitive thread to the runtime.    VMRuntime.registerSensitiveThread();    .................    //初始化性能统计对象    mProfiler = new Profiler();    if (data.initProfilerInfo != null) {        mProfiler.profileFile = data.initProfilerInfo.profileFile;        mProfiler.profileFd = data.initProfilerInfo.profileFd;        mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;        mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;    }    // send up app name; do this *before* waiting for debugger    //重新设置进程名,并修改DDMS中的名称    Process.setArgV0(data.processName);    android.ddm.DdmHandleAppName.setAppName(data.processName,            UserHandle.myUserId());    if (data.persistent) {        // Persistent processes on low-memory devices do not get to        // use hardware accelerated drawing, since this can add too much        // overhead to the process.        //在低内存设备上,禁止常驻进程使用硬件加速        if (!ActivityManager.isHighEndGfx()) {            ThreadedRenderer.disable(false);        }    }    //启动性能统计    if (mProfiler.profileFd != null) {        mProfiler.startProfiling();    }    // If the app is Honeycomb MR1 or earlier, switch its AsyncTask    // implementation to use the pool executor.  Normally, we use the    // serialized executor as the default. This has to happen in the    // main thread so the main looper is set right.    //Java并发使用的ThreadExecutor,没有太深入的去了解    //比较浅显的来讲,serialized executor应该是保证一个任务执行完毕后,才去执行下一个任务    //pool executor根据配置的corePoolSize决定初始时,可以并行的数量;    //当同时提交的任务数量,超过corePoolSize时,任务就会加入到队列中    if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {        AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);    }    /*    * Before spawning a new process, reset the time zone to be the system time zone.    * This needs to be done because the system time zone could have changed after the    * the spawning of this process. Without doing this this process would have the incorrect    * system time zone.    */    TimeZone.setDefault(null);    /*    * Set the LocaleList. This may change once we create the App Context.    */    LocaleList.setDefault(data.config.getLocales());    //更新资源和兼容性相关的配置    synchronized (mResourcesManager) {        /*         * Update the system configuration since its preloaded and might not         * reflect configuration changes. The configuration object passed         * in AppBindData can be safely assumed to be up to date         */        mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);        mCurDefaultDisplayDpi = data.config.densityDpi;        // This calls mResourcesManager so keep it within the synchronized block.        applyCompatConfiguration(mCurDefaultDisplayDpi);    }    //根据传递过来的ApplicationInfo创建一个对应的LoadedApk对象    data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);    /**    * Switch this process to density compatibility mode if needed.    */    //如果没有设置屏幕密度,则为Bitmap设置默认的屏幕密度    if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)            == 0) {        mDensityCompatMode = true;        Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);    }    updateDefaultDensity();    final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));    DateFormat.set24HourTimePref(is24Hr);    ....................    /**    * For apps targetting Honeycomb or later, we don't allow network usage    * on the main event loop / UI thread. This is what ultimately throws    * {@link NetworkOnMainThreadException}.    */    //禁止在主线程使用网络操作    if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {        StrictMode.enableDeathOnNetwork();    }    /**    * For apps targetting N or later, we don't allow file:// Uri exposure.    * This is what ultimately throws {@link FileUriExposedException}.    */    //禁止主线程操作文件    if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.N) {        StrictMode.enableDeathOnFileUriExposure();    }    ...............    /**    * Initialize the default http proxy in this process for the reasons we set the time zone.    */    final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);    if (b != null) {        final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);        try {            //设置默认的Http proxy            final ProxyInfo proxyInfo = service.getProxyForNetwork(null);            Proxy.setHttpProxySystemProperty(proxyInfo);        } catch (RemoteException e) {            .............        }    }    .........................    //创建出进程读应的Android运行环境    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);    .........................    // Install the Network Security Config Provider. This must happen before the application    // code is loaded to prevent issues with instances of TLS objects being created before    // the provider is installed.    .................    NetworkSecurityConfigProvider.install(appContext);    .................    if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {        //如果package中声明了FLAG_LARGE_HEAP,则可跳出虚拟机对内存限制        dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();    } else {        // Small heap, clamp to the current growth limit and let the heap release        // pages after the growth limit to the non growth limit capacity. b/18387825        dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();    }    // Allow disk access during application and provider setup. This could    // block processing ordered broadcasts, but later processing would    // probably end up doing the same disk access.    final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();    try {        // If the app is being launched for full backup or restore, bring it up in        // a restricted environment with the base application class.        // 利用LoadedApk的makeApplication函数,通过反射创建出Application        Application app = data.info.makeApplication(data.restrictedBackupMode, null);        mInitialApplication = app;        // don't bring up providers in restricted mode; they may depend on the        // app's custom Application class        if (!data.restrictedBackupMode) {            if (!ArrayUtils.isEmpty(data.providers)) {                //加载进程对应Package中携带的ContentProvider                installContentProviders(app, data.providers);                // For process that contains content providers, we want to                // ensure that the JIT is enabled "at some point".                // 通过JIT技术加速                mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);            }        }        ...................        try {            //调用Application的onCreate函数,完成一些初始化工作            mInstrumentation.callApplicationOnCreate(app);        } catch (Exception e) {            .................        }    } finally {        StrictMode.setThreadPolicy(savedPolicy);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180

如上文所述,handleBindApplication的目的是让一个Java进程融入到Android体系中。
因此,该函数中的代码主要进行以下工作:
1、按照Android的要求,完成对进程基本参数的设置置,包括设置进程名、时区、资源及兼容性配置;
同时也添加了一些限制,例如主线程不能访问网络等。
2、创建进程对应的ContextImpl、LoadedApk、Application等对象,同时加载Application中的ContentProvider,并初始化Application。
当完成上述工作后,新建的进程终于加入到了Android体系。

3 Part-III

接下来,我们看看AMS中attachApplicationLocked函数的最后一部分内容:

.....................// Remove this record from the list of starting applications.// 进程已经启动,从一些列表中移除对应的记录mPersistentStartingProcesses.remove(app);...................mProcessesOnHold.remove(app);boolean badApp = false;boolean didSomething = false;// See if the top visible activity is waiting to run in this process...if (normalMode) {    try {        //启动Activity        if (mStackSupervisor.attachApplicationLocked(app)) {            didSomething = true;        }    } catch (Exception e) {        Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);        badApp = true;    }}// Find any services that should be running in this process...if (!badApp) {    try {        //启动因目标进程还未启动,而处于等待状态的service        didSomething |= mServices.attachApplicationLocked(app, processName);    } catch (Exception e) {        Slog.wtf(TAG, "Exception thrown starting services in " + app, e);        badApp = true;    }}// Check if a next-broadcast receiver is in this process...if (!badApp && isPendingBroadcastProcessLocked(pid)) {    try {        //发送因目标进程还未启动,而处于等待状态的Broadcast        didSomething |= sendPendingBroadcastsLocked(app);    } catch (Exception e) {        // If the app died trying to launch the receiver we declare it 'bad'        Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);        badApp = true;    }}// Check whether the next backup agent is in this process...if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {    ...............    try {        //启动backup Agent        thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,                compatibilityInfoForPackageLocked(mBackupTarget.appInfo),                mBackupTarget.backupMode);        } catch (Exception e) {            Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);            badApp = true;        }    }}if (badApp) {    //如果以上组件启动出错,则需要杀死进程并移除记录    app.kill("error during init", true);    handleAppDiedLocked(app, false, true);    return false;}//如果以上没有启动任何组件,那么didSomething为falseif (!didSomething) {    //调整进程的oom_adj值, oom_adj相当于一种优先级    //如果应用进程没有运行任何组件,那么当内存出现不足时,该进程是最先被系统“杀死”    //反之,进程中运行的组件越多,则越不容易被“杀死”    updateOomAdjLocked();}return true;......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

这段代码比较好理解,主要功能就是启动新建进程中运行的Activity、Service等组件。

这里我们主要关注一下Activity的启动过程,即下面这段代码:

.............if (normalMode) {    try {        if (mStackSupervisor.attachApplicationLocked(app)) {            didSomething = true;        }    } catch (Exception e) {        ..........        badApp = true;    }}...............
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

我们跟进定义于ActivityStackSupervisor中的attachApplicationLocked函数:

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {    final String processName = app.processName;    boolean didSomething = false;    //ActivityStackSupervisor维护着终端中所有Activity和Task之间的关系    //此处通过轮寻,找出前台栈顶端的待启动Activity    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;            }            ActivityRecord hr = stack.topRunningActivityLocked();            if (hr != null) {                //前台待启动的Activity与当前新建的进程一致时,启动这个Activity                if (hr.app == null && app.uid == hr.info.applicationInfo.uid                        && processName.equals(hr.processName)) {                    try {                        //realStartActivityLocked进行实际的启动工作                        if (realStartActivityLocked(hr, app, true, true)) {                            didSomething = true;                        }                    } catch (RemoteException e) {                        .............                    }                }            }        }    }    .................    return didSomething;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

通过这段代码,我们终于明白了启动Activity的过程:一中的流程,为什么要花大力气先将待启动的Activity的Task移动到前台,并且要将该Activity移动到栈顶。
毕竟,在创建新进程时,无法将待启动Activity的信息一并传递给新进程(进程刚创建时,并没有加入到Android体系),因此新进程被创建后,无法知道需要创建的Activity。
于是,上面的代码就规定:如果前台栈顶Activity对应的进程信息,与新启动的进程相互吻合时,该进程就需要启动该Activity。

三、realStartActivityLocked函数

接下来,我们看看ActivityStatckSupervisor中的realStartActivityLocked函数:

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,        boolean andResume, boolean checkConfig) throws RemoteException {    if (!allPausedActivitiesComplete()) {        // While there are activities pausing we skipping starting any new activities until        // pauses are complete. NOTE: that we also do this for activities that are starting in        // the paused state because they will first be resumed then paused on the client side.        ...........        return false;    }    if (andResume) {        //为显示做准备        r.startFreezingScreenLocked(app, 0);        mWindowManager.setAppVisibility(r.appToken, true);        ..........    }    // Have the window manager re-evaluate the orientation of    // the screen based on the new activity order.  Note that    // as a result of this, it can call back into the activity    // manager with a new orientation.  We don't care about that,    // because the activity is not currently running so we are    // just restarting it anyway.    if (checkConfig) {        Configuration config = mWindowManager.updateOrientationFromAppTokens(                mService.mConfiguration,                r.mayFreezeScreenLocked(app) ? r.appToken : null);        //AMS更新绘制相关的配置信息        mService.updateConfigurationLocked(config, r, false);    }    r.app = app;    app.waitingToKill = null;    r.launchCount++;    ...............    //将待启动Activity对应ActivityRecord加入到进程中保存    int idx = app.activities.indexOf(r);    if (idx < 0) {        app.activities.add(r);    }    //更新优先级    mService.updateLruProcessLocked(app, true, null);    mService.updateOomAdjLocked();    ...............    final ActivityStack stack = task.stack;    try {        ...............        List<ResultInfo> results = null;        List<ReferrerIntent> newIntents = null;        if (andResume) {            results = r.results;            newIntents = r.newIntents;        }        ...............        if (andResume) {            app.hasShownUi = true;            app.pendingUiClean = true;        }        app.forceProcessStateUpTo(mService.mTopProcessState);        //通知应用进程启动Activity        app.thread.scheduleLaunchActivity(............);        if ((app.info.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {            //处理heavy-weight进程的情况            .........        }    } catch (RemoteException e) {        if (r.launchFailed) {            // This is the second time we failed -- finish activity            // and give up.            ................            //从代码来看,第二次启动失败,才会将ActivityRecord中的launchFailed置为true            mService.appDiedLocked(app);            stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,                    "2nd-crash", false);            return false;        }        // This is the first time we failed -- restart process and        // retry.        app.activities.remove(r);        throw e;    }    r.launchFailed = false;    if (andResume) {        // As part of the process of launching, ActivityThread also performs        // a resume.        // Activity进入resumeState后,更新相应的状态        stack.minimalResumeActivityLocked(r);    } else {        ................    }    // Launch the new version setup screen if needed.  We do this -after-    // launching the initial activity (that is, home), so that it can have    // a chance to initialize itself while in the background, making the    // switch back to it faster and look better.    if (isFocusedStack(stack)) {        //启动系统设置向导对应的Activity,当系统更新或初次使用时需要配置        mService.startSetupActivityLocked();    }    ................    return true;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108

从上面的代码可以看出,realStartActivityLocked函数主要工作包括:
1、进一步配置ActivityRecord和ProcessRecord;
2、调用scheduleLaunchActivity,通知应用进程启动Activity;
3、在Activity启动后,AMS调用minimalResumeActivityLocked更新相应的状态。

这里我们只需要进一步看看scheduleLaunchActivity和minimalResumeActivityLocked这两个函数的流程。

1、scheduleLaunchActivity

scheduleLaunchActivity定义于ApplicationThread中:

public final void scheduleLaunchActivity(........) {    //更新进程的状态    updateProcessState(procState, false);    ActivityClientRecord r = new ActivityClientRecord();    //保存AMS传递过来的信息    r.token = token;    r.ident = ident;    r.intent = intent;    ...........    //更新本地配置    updatePendingConfiguration(curConfig);    //发送消息,即ApplicationThread的工作其实就是与AMS通信    //实际的处理,还是交给进程主线程的代表ActivityThread处理    sendMessage(H.LAUNCH_ACTIVITY, r);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

ActivityThread中的handler处理消息的代码如下:

public void handleMessage(Message msg) {    ...............    switch (msg.what) {        case LAUNCH_ACTIVITY: {            ..............            final ActivityClientRecord r = (ActivityClientRecord) msg.obj;            //利用ApplicationInfo等信息得到对应的LoadedApk,保存到ActivityClientRecord            r.packageInfo = getPackageInfoNoCheck(                    r.activityInfo.applicationInfo, r.compatInfo);            //调用handleLaunchActivity            handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");            ..............        } break;        ...........    }    .............}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

我们跟进一下handleLaunchActivity:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {    // If we are getting ready to gc after going to the background, well    // we are back active so skip it.    // 如果Activity从前台移动到后台,则有可能准备进行Gc操作    // 现在Activity重新启动,就需要取消Gc操作了    // 对于新建Activity而言,此处无实际动作    unscheduleGcIdler();    mSomeActivitiesChanged = true;    //Activity进行性能统计    if (r.profilerInfo != null) {        mProfiler.setProfiler(r.profilerInfo);        mProfiler.startProfiling();    }    // Make sure we are running with the most recent config.    // 保证Activity以最新的配置启动,即保证Activity符合最新语言、主题、分辨率等的要求    handleConfigurationChanged(null, null);    ............    // Initialize before creating the activity    WindowManagerGlobal.initialize();    //1、创建Activity    Activity a = performLaunchActivity(r, customIntent);    if (a != null) {        r.createdConfig = new Configuration(mConfiguration);        ............        //2、调用activity的onResume        handleResumeActivity(.......);        if (!r.activity.mFinished && r.startsNotResumed) {            // The activity manager actually wants this one to start out paused, because it            // needs to be visible but isn't in the foreground. We accomplish this by going            // through the normal startup (because activities expect to go through onResume()            // the first time they run, before their window is displayed), and then pausing it.            // 处理可见但非前台的Activity,这种Activity在启动后将进入到pause状态            performPauseActivityIfNeeded(r, reason);        }        ...................    } else {        try {            //如果启动错误,则通知AMS            ActivityManagerNative.getDefault()                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);        } catch (RemoteException ex) {            ...............        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

从上述代码可以看出,handleLaunchActivity的工作主要包括:
1、调用performLaunchActivity创建出Activity;
2、调用handleResumeActivity,完成调用目标Activity的onResume接口等工作;
3、对于可见但非前台的Activity,还需要调用performPauseActivityIfNeeded函数,调用Activity的onPause接口。

我们主要看一下performLaunchActivity和handleResumeActivity函数。

1.1 performLaunchActivity

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {    ............    Activity activity = null;    try {        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();        //反射创建Activity        activity = mInstrumentation.newActivity(                cl, component.getClassName(), r.intent);        ...............    } catch (Exception e) {        ...........    }    try {        ..............        if (activity != null) {            ..........            //设置Activity的主要变量,例如mMainThread、mUiThread等            //mMainThread的类型为ActivityThread;mUiThread的类型为Thread            //二者实际的工作线程是同一个            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);            ...........            //进行主题的设置            activity.mStartedActivity = false;            int theme = r.activityInfo.getThemeResource();            if (theme != 0) {                activity.setTheme(theme);            }            //调用Activity的onCreate函数            activity.mCalled = false;            if (r.isPersistable()) {                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);            } else {                mInstrumentation.callActivityOnCreate(activity, r.state);            }            .............            r.activity = activity;            r.stopped = true;            if (!r.activity.mFinished) {                //调用Activity的onStart函数                activity.performStart();                r.stopped = false;            }            //调用Activity的onRestoreInstanceState函数            if (!r.activity.mFinished) {                if (r.isPersistable()) {                    if (r.state != null || r.persistentState != null) {                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,                                r.persistentState);                    }                } else if (r.state != null) {                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);                }            }            //调用Activity的onPostCreate接口            if (!r.activity.mFinished) {                activity.mCalled = false;                if (r.isPersistable()) {                    mInstrumentation.callActivityOnPostCreate(activity, r.state,                            r.persistentState);                } else {                    mInstrumentation.callActivityOnPostCreate(activity, r.state);                }                .............            }            r.paused = true;            //Activity保存到进程中            mActivities.put(r.token, r);        }    } catch (SuperNotCalledException e) {        .........    } catch (Exception e) {        ..........    }    return activity;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84

performLaunchActivity的功能比较直观,就是利用反射创建出目标Activity,然后设置Activity的内部变量,最后依次调用Activity生命周期中的接口,主要包括onCreate、onStart等。

1.2 handleResumeActivity

接下来,看看handleResumeActivity的工作:

final void handleResumeActivity(.......) {    ActivityClientRecord r = mActivities.get(token);    ..............    //主要是调用目标Activity的onResume函数    r = performResumeActivity(token, clearHide, reason);    if (r != null) {        final Activity a = r.activity;        //为绘制做准备工作        ..............        if (!r.activity.mFinished && willBeVisible                 && r.activity.mDecor != null && !r.hideForNow) {            //进行绘制相关的工作            .............        }        if (!r.onlyLocalRequest) {            //可以看出ActivityThread用Stack的方式,保存完成onResume的Activity            //r为刚刚完成onResume的新Activity,mNewActivities保存已经完成onResume的Activity            //新的Activity的nextIdle指向旧的            r.nextIdle = mNewActivities;            //然后将新建的Activity保存到mNewActivities中            mNewActivities = r;            ...........            //向ActivityThread的MessageQueue中增加一个IdleHandler            Looper.myQueue().addIdleHandler(new Idler());        }        r.onlyLocalRequest = false;        // Tell the activity manager we have resumed.        if (reallyResume) {            try {                //通知AMS Activity进入Resume状态                //AMS会修改对应的存储信息                ActivityManagerNative.getDefault().activityResumed(token);            } catch (RemoteException ex) {                ............            }        }    } else {        ...........    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

从上面的代码可以看出,handleResumeActivity函数将会调用Activity的onResume接口,并进行绘制相关的操作,
然后向Activity的MessageQueue中增加一个IdleHandler,最终通知AMS更新Activity的状态。

在之前的博客Android7.0 MessageQueue 中,我们提到过当MessagQueue的next函数被调用时,如果队列中没有message需要处理,那么将调用添加到MessageQueue的IdleHandler的queueIdle接口。
handleResumeActivity函数向ActivityThread增加了一个IdleHandler,我们看看它的作用:

private class Idler implements MessageQueue.IdleHandler {    public final boolean queueIdle() {        ActivityClientRecord a = mNewActivities;        ..................        if (a != null) {            mNewActivities = null;            IActivityManager am = ActivityManagerNative.getDefault();            ActivityClientRecord prev;            do {                ............                if (a.activity != null && !a.activity.mFinished) {                    try {                        //调用AMS的activityIdle函数                        am.activityIdle(a.token, a.createdConfig, stopProfiling);                        a.createdConfig = null;                    } catch (RemoteException ex) {                        ..............                    }                    //do-while循环将处理所有的已经完成onResume的Activity                    prev = a;                    a = a.nextIdle;                    prev.nextIdle = null;                }            }while (a != null);            ..........        }        .........        //返回值为false,于是执行一次后,会被移除        return false;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

从上面的代码可以看出,当ActivityThread空闲下来后,将为所有完成onResume的Activity调用AMS的activityIdle函数。
该函数是Activity成功创建并启动流程中的最后一步,我们稍后再分析。

至此,scheduleLaunchActivity函数分析完毕,我们看看realStartActivityLocked函数的下一个关键点minimalResumeActivityLocked。

2、minimalResumeActivityLocked

minimalResumeActivityLocked定义于ActivityStack中。ActivityStack是Activity所在Task中,保存ActivityRecord的数据结构。
我们看看minimalResumeActivityLocked的代码:

void minimalResumeActivityLocked(ActivityRecord r) {    r.state = ActivityState.RESUMED;    .............    mResumedActivity = r;    r.task.touchActiveTime();    //mRecentTasks保存近期被调用的Task    mRecentTasks.addLocked(r.task);    //更新一些状态    completeResumeLocked(r);    //判断AMS当前维护的Activity对应的进程是否可以sleep    //若可以sleep,将调用对应ApplicationThread的scheduleSleeping函数    mStackSupervisor.checkReadyForSleepLocked();    setLaunchTime(r);    ............}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

上述代码中主要的工作由completeResumeLocked来完成:

/*** Once we know that we have asked an application to put an activity in* the resumed state (either by launching it or explicitly telling it),* this function updates the rest of our state to match that fact.*/private void completeResumeLocked(ActivityRecord next) {    //更新ActivityRecord的变量    next.visible = true;    next.idle = false;    ............    if (next.isHomeActivity()) {        //对Home Activity的特殊处理        ..........    }    if (next.nowVisible) {        // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now.        //如果已经visible将进行通知        mStackSupervisor.reportActivityVisibleLocked(next);        mStackSupervisor.notifyActivityDrawnForKeyguard();    }    // schedule an idle timeout in case the app doesn't do it for us.    //发送一个延迟消息IDLE_TIMEOUT_MSG,延迟时间为10s    //这里就是要求Activity启动后,10s内要调用AMS的activityIdle函数    //不过从代码来看,即使Activity 10s内没有调用activityIdle函数,    //ActivityStackSupervisor也会自己调用activityIdleInternalLocked函数    mStackSupervisor.scheduleIdleTimeoutLocked(next);    mStackSupervisor.reportResumedActivityLocked(next);    ......................}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

从这部分代码,可以看出minimalResumeActivityLocked函数整体上就是负责更新一些状态,不用过于在意它的细节。

四、activityIdle函数

现在,我们看一下Activity启动的最后一步,即调用AMS的activityIdle函数:

public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {    ................    synchronized (this) {        ActivityStack stack = ActivityRecord.getStackLocked(token);        if (stack != null) {            //主要调用ActivityStackSupervisor的activityIdleInternalLocked函数            ActivityRecord r =                    mStackSupervisor.activityIdleInternalLocked(token, false, config);            .................        }    }    ..............}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

跟进activityIdleInternalLocked函数:

//ActivityThread在超时时间内,调用activityIdle时,fromTimeout的值为false//如果超时后,由ActivityStackSupervisor主动调用该函数,fromTimeout的值为truefinal ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,        Configuration config) {    ................    ActivityRecord r = ActivityRecord.forTokenLocked(token);    if (r != null) {        ....................        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);        ....................        if (fromTimeout) {            //超时时,将通知Activity完成启动            reportActivityLaunchedLocked(fromTimeout, r, -1, -1);        }        if (config != null) {            r.configuration = config;        }        r.idle = true;        ................    }    //当所有Resumed Activity都处于空闲状态时    if (allResumedActivitiesIdle()) {        if (r != null) {            mService.scheduleAppGcsLocked();        }        //mLaunchingActivity是一个WakeLock,用于防止在操作Activity的过程中休眠        //由于该WakeLock不能长时间使用,因此系统设置了一个超时消息LAUNCH_TIMEOUT_MSG        //处理该消息时,将释放该WakeLock        //此处,当所有Activity均空闲时,说明事件处理完毕,此时需要释放该WakeLock        if (mLaunchingActivity.isHeld()) {            mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);            ...............            mLaunchingActivity.release();        }        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);    }    // Atomically retrieve all of the other things to do.    //processStoppingActivitiesLocked返回那些因本次Activity启动而被暂停(paused)的Activity    final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(true);    NS = stops != null ? stops.size() : 0;    if ((NF = mFinishingActivities.size()) > 0) {        //finishes保存等待结束的Activity        finishes = new ArrayList<>(mFinishingActivities);        mFinishingActivities.clear();    }    .................    // Stop any activities that are scheduled to do so but have been    // waiting for the next one to start.    for (int i = 0; i < NS; i++) {        r = stops.get(i);        final ActivityStack stack = r.task.stack;        if (stack != null) {            if (r.finishing) {                //如果被暂停的Activity已经处于了finishing状态,则通知它们执行Destroy操作,即Activity的onDestroy函数将被调用                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);            } else {                //否则通知它们执行stop操作,即Activity的onStop将被调用                stack.stopActivityLocked(r);            }        }    }    // Finish any activities that are scheduled to do so but have been    // waiting for the next one to start.    // 处理等待结束的Activity,从代码来看最终也是调用其onDestroy接口    for (int i = 0; i < NF; i++) {        r = finishes.get(i);        final ActivityStack stack = r.task.stack;        if (stack != null) {            activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");        }    }    ................    //AMS清理没有任何组建的无用进程    mService.trimApplications();    if (activityRemoved) {        //如果等待结束的Activity被处理,保证前台栈顶Activity处于Resumed状态        resumeFocusedStackTopActivityLocked();    }    return r;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90

至此,启动Activity最后一部分的主要工作介绍完毕。
从代码来看,这一部分最主要的工作是:
进行一些扫尾工作,即根据后台Activity是否处于finishing状态,分别调用其onStop和onDestroy接口。
同时,AMS也会清理一些无实际工作的进程。

最后需要补充的是:
我们利用am start -W启动Activity时,需要等待返回结果,详细代码可以参考启动Activity的过程:一。
在ActivityStarter的startActivityMayWait函数中:

final int startActivityMayWait(.........) {    .............    //outResult != null,说明启动命令发送成功    if (outResult != null) {        outResult.result = res;        if (res == ActivityManager.START_SUCCESS) {            mSupervisor.mWaitingActivityLaunched.add(outResult);            do {                try {                    //等待Task移动到前台                    mService.wait();                } catch (InterruptedException e) {                }            } while (outResult.result != START_TASK_TO_FRONT                    && !outResult.timeout && outResult.who == null);            if (outResult.result == START_TASK_TO_FRONT) {                res = START_TASK_TO_FRONT;            }        }        if (res == START_TASK_TO_FRONT) {            ActivityRecord r = stack.topRunningActivityLocked();            if (r.nowVisible && r.state == RESUMED) {                outResult.timeout = false;                outResult.who = new ComponentName(r.info.packageName, r.info.name);                outResult.totalTime = 0;                outResult.thisTime = 0;            } else {                outResult.thisTime = SystemClock.uptimeMillis();                mSupervisor.mWaitingActivityVisible.add(outResult);                do {                    try {                        //等待Activity可见                        mService.wait();                    } catch (InterruptedException e) {                    }                } while (!outResult.timeout && outResult.who == null);             }        }    }    ..................}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

上面代码中,startActivityMayWait等待的信号均由ActivityStackSupervisor触发。

在启动Activity的过程:一中简单提到过,在startActivityLocked函数的最后,调用了postStartActivityUncheckedProcessing函数进行通知:

void postStartActivityUncheckedProcessing(......) {    .............    // We're waiting for an activity launch to finish, but that activity simply    // brought another activity to front. Let startActivityMayWait() know about    // this, so it waits for the new activity to become visible instead.    if (result == START_TASK_TO_FRONT && !mSupervisor.mWaitingActivityLaunched.isEmpty()) {        mSupervisor.reportTaskToFrontNoLaunch(mStartActivity);    }    ............}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

我们看ActivityStackSupervisor的reportTaskToFrontNoLaunch函数:

void reportTaskToFrontNoLaunch(ActivityRecord r) {    boolean changed = false;    for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {        WaitResult w = mWaitingActivityLaunched.remove(i);        //who表示componentName,Activity未可见前为null        if (w.who == null) {            changed = true;            // Set result to START_TASK_TO_FRONT so that startActivityMayWait() knows that            // the starting activity ends up moving another activity to front, and it should            // wait for this new activity to become visible instead.            // Do not modify other fields.            w.result = START_TASK_TO_FRONT;        }    }    if (changed) {        //notifyAll通知ActivityStarter待启动Activity对应的Task移动到了前台        mService.notifyAll();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

同样,当Activity可见时,WindowManagerService将回调ActivityRecord中的windowsVisible函数:

public void windowsVisible() {    synchronized (mService) {        ActivityRecord r = tokenToActivityRecordLocked(this);        if (r != null) {            r.windowsVisibleLocked();        }    }}void windowsVisibleLocked() {    mStackSupervisor.reportActivityVisibleLocked(this);    ...........}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

跟进一下ActivityStackSupervisor的reportActivityVisibleLocked函数:

void reportActivityVisibleLocked(ActivityRecord r) {    sendWaitingVisibleReportLocked(r);}void sendWaitingVisibleReportLocked(ActivityRecord r) {    boolean changed = false;    for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {        WaitResult w = mWaitingActivityVisible.get(i);        if (w.who == null) {            changed = true;            w.timeout = false;            if (r != null) {                //构造出ComponentName等信息                w.who = new ComponentName(r.info.packageName, r.info.name);            }            w.totalTime = SystemClock.uptimeMillis() - w.thisTime;            w.thisTime = w.totalTime;        }    }    if (changed) {        //notifyAll通知ActivityStarter待启动Activity可见        mService.notifyAll();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

五、总结


大图地址

至此,AMS启动Activity的后一部分基本介绍完毕。
这一部分的代码整体流程如上图所示,我们省略一些细节,例如绘制等。

从整个逻辑来看,这部分流程比较清晰,主要思想如下:
1、启动进程,创建自己的ActivityThread和ApplicationThread。
2、进程与AMS通信,其实就是完成一个注册过程(将ApplicationThread作为Binder通信接口交给AMS保存),AMS毕竟要统一管理系统中所有的应用进程。
3、AMS通知进程创建自己的Android运行环境,加入到Android体系。
4、AMS通知进程可以启动进程中的组件了,注意四大组件的顺序以此是ContentProvider、Activity、Service、BroadcastReceiver(参考上述代码,可以容易看出这个结论,本文我们仅分析了Activity的启动过程)。
5、Activity启动完成后,通知AMS更新相关的状态,并进行一些扫尾工作。

整体而言,所有的实际工作都是由进程自己完成的,AMS仅起到一个管理的作用。

阅读全文
0 0
原创粉丝点击