美文网首页Android源码分析
Android 源码分析之旅3.2--Activity启动流程(

Android 源码分析之旅3.2--Activity启动流程(

作者: 小楠总 | 来源:发表于2017-03-10 09:20 被阅读1346次

为什么要学习源码?

这是源码分析系列的第三篇博客了,这里我说明一下为什么要进行Activity启动流程的源码分析。

学习源码有助于我们学习一些黑科技,比如学习插件化的从时候我们需要学习Hook机制,但是学习Hook机制的时候我们需要掌握Activity的启动流程、消息机制等等机制。

Activity启动流程分析

我们平常在Activity中调用startActivity(intent)来启动一个Activity的时候,通过调用链的分析,最终会调用Activity的startActivityForResult方法:

public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        //调用Instrumentation类的execStartActivity方法
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        if (ar != null) {
            //如果需要有结果返回的话,还需要去发送消息
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        if (requestCode >= 0) {
            mStartedActivity = true;
        }

        cancelInputsAndStartExitTransition(options);
    } else {
        if (options != null) {
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}

这个方法实际会调用Instrumentation类的execStartActivity方法,Instrumentation类与Activity的初始化有关。Instrumentation类的execStartActivity方法如下:

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    //IApplicationThread是一个AIDL接口,实现类是ActivityThread里的内部类ApplicationThread通过他可以进行进程间通信,通过ApplicationThread可以识别出一个进程。
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    //...省略一些代码
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        //ActivityManagerNative是一个AIDL接口的二分之一:Stub(存根)
        int result = ActivityManagerNative.getDefault()
            .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;
}

ActivityManagerNative是一个AIDL接口的二分之一:Stub,与AMS进行通信的。ActivityManagerNative里面还有一个内部类ActivityManagerProxy。如下图所示:

Activity启动过程

这里先对这个图进行一些必要的说明:

  1. 这是MyActivity的启动流程,流程是从左边开始,逆时针旋转。主要展示了Application怎么调到Android System Service,Android System Service如何反过来调Application。
  2. Instrumentation是Activity的一个成员,这里用聚合表示。Instrumentation用于记录Activity的一切操作。
  3. Application以及H都是ActivityThread的内部类
  4. ActivityManagerService,简称AMS,是Android系统服务中的一个核心模块,其他的还有WindowsManagerService(WMS)、PackageManagerService(PMS)、NotificationManagerService(NMS)等等。AMS主要的功能是管理应用进程以及应用进程中的组件、内存管理。
  5. 从上面的图可以看出Android系统的几个明显的层次关系。

思想

  1. 大量采用了C/S架构,交给远程进程统一管理,这样才能够实现多进程,多窗口,有条不紊。
  2. 模块化的思想,不同的模块管理不同的东西。多建立package,分模块,比如说网络访问专门一个包。
  3. 分层次思想,不能一个类所有事情都管理了。

如果觉得我的文字对你有所帮助的话,欢迎关注我的公众号:

公众号:Android开发进阶

我的群欢迎大家进来探讨各种技术与非技术的话题,有兴趣的朋友们加我私人微信huannan88,我拉你进群交(♂)流(♀)

相关文章

网友评论

    本文标题:Android 源码分析之旅3.2--Activity启动流程(

    本文链接:https://www.haomeiwen.com/subject/sqzmgttx.html