美文网首页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