移动架构----AMS流程梳理

整体脑图

AMS整体脑图.png
AMS涉及到的知识点有很多,这里主要记录一下AMS相关的启动流程,主要包括:
  • Android系统启动
  • Binder启动
  • AMS注册服务
  • Activity启动
    代码说明以26版本为例。

1、Android系统启动流程

流程图
系统启动流程图.png

系统启动步骤:

  1. 引导程序BootLoader启动。

  2. Linux内核启动。

  3. 启动init进程,解析init.rc文件。

  4. Zygote进程启动。

  5. 启动Binder线程池,启动SystemServer进程。

  6. 启动一系列的服务,放到Binder线程池中。
    这里需要注意的是,系统服务与zygote是通过socket进行通信的。
    下面结合源代码对以上启动步骤做进一步的说明:

     //Zygoteinit.java    
     public static void main(String argv[]) {
         ZygoteServer zygoteServer = new ZygoteServer();
         ...
         //创建一个Server端的Socket
         zygoteServer.registerServerSocket(socketName);
         ...
         //启动SystemServer进程
         if (startSystemServer) {
             startSystemServer(abiList, socketName, zygoteServer);
         }
         Log.i(TAG, "Accepting command socket connections");
         //开启死循环,等待服务请求
         zygoteServer.runSelectLoop(abiList);
         zygoteServer.closeServerSocket();
       } catch (Zygote.MethodAndArgsCaller caller) {
         caller.run();
       } catch (Throwable ex) {
         Log.e(TAG, "System zygote died with exception", ex);
         zygoteServer.closeServerSocket();
         throw ex;
        }
     }
    

总体来说,ZogoteInit中的main方法中做了三件我们关心的事:

  1. 创建了一个Server端的Socket,用来与后续开启的服务通信。
  2. 启动了SystemServer进程,用于开启后续的服务。
  3. 开启循环,等待服务请求创建的Socket。

2、Binder启动流程

Binder模型图
binder模型图.png
流程图
binder启动流程图.png

Binder的启动流程对应Android系统启动流程中的ServiceManger创建。对binder驱动的操作主要在native层,这里不做详细的说明,只是简单的图示一下过程。

3、AMS注册服务

流程图
AMS注册流程.png

这里做下说明,图中的客户端进程是指除了SystemServer以外的进程统称为客户端进程。
AMS的注册过程主要也是在native层完成的,主要包括:

  1. 服务端初始化
  2. 客户端初始化
  3. 向binder驱动发送指令,已初始化
  4. binder驱动唤醒ServiceManger服务
  5. 注册AMS
  6. binder通知ServiceManager完成注册
  7. ServiceManager向binder驱动生成应答数据
  8. binder驱动唤醒客户端进程,通知客户端AMS注册完成

4、App启动流程

流程图
应用启动流程.png

启动App的时候,AMS通过Socket与Zygote进程进行通信,在Android系统启动流程中会有一个循环,一直等待接收服务发来的请求,当Zygote创建的socket接受到AMS的请求时,最终会调用Zygote的MethodAndArgsCaller方法,在这个方法中最终执行了ActivityThread的main方法,及App的入口方法。
下面用代码加以说明:

//ActivityManagerService.java    
private final void startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    ...
        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方法
            startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, invokeWith, entryPointArgs);
        }
        ...
}
//Process.java
public static final ProcessStartResult start(final String processClass,
                              final String niceName,
                              int uid, int gid, int[] gids,
                              int debugFlags, int mountExternal,
                              int targetSdkVersion,
                              String seInfo,
                              String abi,
                              String instructionSet,
                              String appDataDir,
                              String invokeWith,
                              String[] zygoteArgs) {
    //调用ZygoteProcess中的start方法
    return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                debugFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}

ZygoteProcess中的start会调用openZygoteSocketIfNeeded与Zygote进程通过socket进行通信:

private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
    ...
    if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
        ...
            //与Zygote进程通信
            primaryZygoteState = ZygoteState.connect(mSocket);
        ...
    }
...
    if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
        ...
            //与Zygote进程通信
            secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
        ...
    }
...
}

在Android系统启动流程中有一个死循环一直在等待Sokcet连接,当收到AMS发来的请求后最后会执行Zygote中的MethodAmdArgsCaller类中的run方法:

public static class MethodAndArgsCaller extends Exception
        implements Runnable {
    /** method to call */
    private final Method mMethod;

    /** argument array */
    private final String[] mArgs;

    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }

    public void run() {
        ...
            //这里其实就是ActivityThread的main方法
            mMethod.invoke(null, new Object[] { mArgs });
        ...
    }
}

5、Activity启动流程

Activity启动流程.png

Activity启动流程包括:

  • AMS发送请求,最终调用ApplicationThread中的scheduleReceiver

  • ApplicationThread发送消息

  • ActivityThread处理消息

  • 调用handlelaunchActivity

  • 调用Activity.onCreate
    当发送消息为LAUNCH_ACTIVITY时,会执行:

    //ActivityThread.java
    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
     ...
      Activity a = performLaunchActivity(r, customIntent);
      ...
    }
     
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
              ...
              if (r.isPersistable()) {//21版本增加的支持数据持久化标识,用于关机重启数据恢复
                  //调用Activity中的performCreate
                  mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
              } else {
                  //调用Activity中的performCreate
                  mInstrumentation.callActivityOnCreate(activity, r.state);
              }
             ...
    }
    //Instrumentation.java
    public void callActivityOnCreate(Activity activity, Bundle icicle) {
      prePerformCreate(activity);
      //调用Activity中的performCreate
      activity.performCreate(icicle);
      postPerformCreate(activity);
    }
     //Activity.java
     final void performCreate(Bundle icicle) {
       restoreHasCurrentPermissionRequest(icicle);
       //调用Activity的onCreate,生命周期开始。
       onCreate(icicle);
       mActivityTransitionState.readState(icicle);
       performCreateCommon();
     }
    

到这里,从Android系统到Activity的启动,涉及到的流程梳理完了!

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

推荐阅读更多精彩内容