Android AMS源码阅读分析(一)

最近学习了柯元旦所著《Android内核剖析》之AMS原理篇章,结合自己的理解以及对源码的分析,记录一下学习心得,AMS代码非常多,而且和Application以及Activity之间的交互也相对繁杂,这里学习大致的主干流程,之后有时间会再去细看。

AMS的功能

AMS的功能可以概述为以下三个:

在这里插入图片描述

首先来看看这个统一调度各个应用程序之间的activity,可以把AMS理解成一个管理员,管理着手机里面的所有应用程序,每当一个应用程序想要启动activity,都要先报告AMS,AMS认为该应用程序可以启动,那么就通知该应用程序去执行启动activity操作,当应用程序启动完毕,也要报告AMS,AMS会记录对应的进程以及对应的activity,以便对activity进行管理和调控,例如内存不足时选择杀死某些优先级的activity。

既然应用程序启动activity需要AMS的调控,那么我们就来看看activity的启动过程以及过程中,AMS如何对应用程序加以调度,并且和应用程序之间进行交互的。

Activity的启动入口是startActivityForResult(),startActivity()其实也是调用了startActivityForResult(),那么就从这个入口去看看具体的启动流程吧;

activity的启动流程

activity的启动流程大概总结为:

启动Activity B -> 当前有正在显示的activity吗 -> 有就先pause() -> B的进程存在吗 -> 不存在则创建 -> B进程启动指定的Activity

首先来看一下这个过程的具体流程图,其实就是上面流程简介的具体化:
在这里插入图片描述

现在从源码开始,一步一步的去看看具体的startActivity()的执行流程:

一.首先是startActivity的调用流程

从Activity中调用了startActivity()之后,经过一系列跳转,会执行到Instrument的execStartActivity()方法中,这个Instrumentation是什么呢?可以说它是应用进程的管家,监控着应用进程与系统的所有交互,所有的创建、暂停、停止activity,都是通过它去发起的,它可以统计所有的开销。

那么再来看看execStartActivity()方法的内部实现:


 /** 
   * 1.先看看比较重要的参数的意义:
   * @param who:  当前的执行了startActivity的activity对象
   * @param contextThread :当前activity 的主线程,即是ApplicationThread对象
   * @param token:用于鉴定启动activity的对象
   * @param target:需要被启动的activity 对象
   **/    
 public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {

        IApplicationThread whoThread = (IApplicationThread) contextThread;
        ...
        
        //...省略关于ActivityMonitor测试工具类的部分
       
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            
            /**
              * 2.看到这里,我们发现Instrumentation将启动activity的工作交给了AMS,这里就
              * 涉及到了IPC调用了,IPC调用是同步的,而startActivity()是在主线程中调用的
              * 那么这里会导致主线程阻塞吗?
              * 答案是不会的,由于AMS内部执行startActivity()是异步的,所以会在很短时间内
              * 返回,然后最后再通过回调Activity的onActivityResult(),所以需要在这个方法
              * 中传入一个Token,即是Activity的标识
              **/
              
                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;
 

再来看下在AMS中是如何去实现这个startActivity的流程的,在AMS中经过一系列的调用,最终会调用如下startActivityAsUser()方法:

/**
  * 1.来看一下重要参数的含义:
  * @param caller :指的是ApplicationThread,代表当前要启动activity的主线程
  * @param callingPackage:发起startActivity的进程包名
  * @param resultTo:Activity传来的token变量,对应的是AMS的ActivityRecord,AMS通过来识
  *                 别客户端进程的Activity
  *           
  **/

public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值