android framework之Applicataion启动流程分析

  • Application启动流程框架分析

启动方式一:通过Launcher启动app
启动方式二:在某一个app里启动第二个app的Activity.
以上两种方式均可触发app进程的启动。但无论哪种方式,最终通过通过调用AMS的startActivity()来启动application的。
  

根据上图分析, 要启动一个Application,需要涉及五个进程,Launcher进程,SystemServer进程,Zygote进程,和要启动的目标Application进程,最后还有一个ServiceManager进程。通过Launcher进程是无法直接启动app的,因为启动是通过AMS或ATMS完成的。

所以第一步,Launcher必须要拿到AMS的Binder,而AMS的Binder(如上图左侧)在Launcher中的代理则是ActivityManagerProxy,它是Launcher从ServiceManager中查询获取而得到的,然后基于这个代理,向SystemServer进程中的AMS去请求startActivity().


这个过程是通过ActivityManagerProxy这个Binder远程调用了AMS的服务,让AMS去startActivity. 但是AMS在启动之前肯定要先判断一下这个Activity对应的Application进程是否已经存在。如果进程存在, 直接走上面的第五步,这一步的处理过程也是跨进程通信的,通过获取APP进程在AMS中的客户端代理即ApplicationThreadProxy, 通过这个代理Binder远程调用app进程的scheduleLauncherActivity()方法直接启动进程中的Activity,这个流程是基于APP进程已经存在了,所以走的是第5和6步分支。

但是现在要讨论的是APP进程不存在的时候,这个APP的启动流程,这种启动方式会覆盖所有app的启动流程。所以AMS当发现进程不存在时,它首先会走第2步,向Zygote进程发送创建进程的请求,这一步采用的是socket通信方式来操作的,zygote收到socket指令后,是通过调用fork()的方式来启动复制创建一个application进程的,这个就是第三步。一旦这个Application被创建,它不会立刻运行,因为它是由AMS来负责的,所以它会先将自身的Binder代理对象发给AMS,这个是第四步,它是利用ActivityManager在Application的Binder对象ActivityManagerProxy来远程调用其attach_application()方法来传递自身Binder。这样AMS也就保存了这个Application的Binder对象,
然后才是走第5步,在第5步中如上面的分析(app进程已经存在的情况下),利用Application在AMS的Binder代理即ApplicationThreadProxy进行启动,最后执行到第8步,调用Activity.onCreate方法。

  • Application进程启动流程代码分析

 现在来分析App进程的启动流程,这边分两块,一个是Application的启动流程,一个是Activity的启动,Application的启动是通过Zygote fork()创建启动的,所以它的启动只有一次,但是Activity的启动可以是多次,而且有不同的启动方式,比如通过Launcher启动,通过进程内的ActivityA->AcitityB,或由其它另外一个进程来启动这个进程的Activity,等等。因此我们这边分析的是最全的覆盖最大的Activity启动方法,其它启动方式基本类似,按此作为参考。

Application进程的启动:

进程的启动来自AMS或ATMS代码,由它们触发,但是先抛开Activity前面的启动代码,所以我们从上图中右边的第2步开始进行源码分析,如上图所示Application进程的启动流程是由ATMS发起,在启动activity过程中会经历一个类ActivityStackSupervisor.java,在这个类中会真正的去启动activity, 会先进入startSpecialActivity()这个函数如下所示:

ActivityStackSupervisor.java->startSpecialActivity():
  -->//这里面会进行app进程存在与否的判断
     if(wpc != null && wpc.hasThread() )
        //进程存在时,直接启动activity
        -->realStartActivityLocked(); //这个与文章中最前面那张图就对上了。
     ...
     //下面是进程不存在时,需要创建。
     //mService是ActivityTaskServiceManager.java对象
     mService.startProcessAsync();//为app启动一个进程。
       //ActivityManagerInternal是AMS里的一个内部类:它内部包含了AMS的绝大多数服务的函数 
       -->Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,...);
          mH.sendMessage(m);


这边过一下ActivityManagerInternal::startProcess这个函数:
  -->它是用于启动进程的,启动进程是通过socket,向zygote发送启动进程所需要的一些关键参数,
     startProcessLocked();
      //app进程相关的核心类有两个:一个是ProcessRecord类,一个是ProcessList进程的核心类,
      //在下面进一步描述:AMS通过持有进程的ProcessList列表,通过它来管理(start)进程
      -->mProcessList.startProcessLocked();
          -->判断处理进程启动前的各种参数和内容
             ...
             ProcessList.java->startProcessLocked();
              -->ProcessList.java->startProcessLocked(app, ApplicationInfo,);//重载的另一个函数
                  -->ProcessList.java->startProcessLocked();//又是重载 的另一个函数,中间会经历很多个重载的函数
                      ->...
                        final Process.ProcessStartResult startResult = startProcess();
                          -->if(usesWebviewZygote())
                                startWebView();
                             else if(usesAppZygote()) 
                                appZygote.getProcess().start(); //隔离进程的启动
                             else
                                //Process:只是一个工具类(很多静态函数),协助ProcessList或ProcessRecord去管理进程
                                return Process.start(); //正常app的启动。
                                   //ZYGOTE_PROCESS是ZygoteProcess类对象,也是工具类帮助zygote启动app进程
                                   -->return ZYGOTE_PROCESS.start(); //还是属于SystemServer进程
                                        -->ZygoteProcess.java:startViaZygote();
                                            -->//封装一系列参数
                                               ....
                                               argsForZygote.add(添加参数)
                                               zygoteSendArgsAndGetResult();
                                                -->attempZygoteSendArgsAndGetResult();
                                                    -->BufferedWriter usapWriter = new BufferedWrite();
                                                       usapWrite.write(msgStr);  
                                                       usapWrite.flush();//通过socket发给zygote.zygote进程可以接收到并执行。
  • Zygote进程接收到Socket消息处理

分析到这边,可以切换到zygote进程代码,继续分析,大致看一下Zygote进程是如何接收与处理消息的,代码如下:

ZygoteInit.main():
 -->...
    runSelectLoop();
      -->while(true) //死循环
          -->Zygoteconnection  connection = peers.get(); 
             Runnable command = connection.processOneCommand();//进行进程的处理,创建新进程
              -->args = Zygote.readArgumentList(mSocketReader);//获取socket命令参数
                 ZygoteArguments parsedArgs = new ZygoteArguments();
                 ...各种参数解析中...
                 pid = zygote.forkAndSpecialize();//Fork子进程,得到一个新的pid.
                   -->nativeForkAndSpecialize(); //调用native层接口去fork
  • 关于两个重要的数据结构

(1)ProcessRecord数据结构(代表进程运行的各类属性参数):

rocessRecord数据结构(代表进程运行的各类属性参数):
第一类数据:描述身份的数据,描述进程在AMS中的一个存在形式。
内部包括ApplicationInfo, 进程uid, userId, ProcessName, pid,
IApplicationThread(APP存放在AMS中的客户端IBinder对象)等等信息。
IApplicationThread很重要,AMS通过它给apk进程发送异步消息(管理四大组件的消息),
只有这个对象不为空时,才代码apk进程可以使用。

第二类数据:描述进程状态的数据
第三类数据:内存及和运行耗时,CPU时长,交互时长等相关的数据
第四类数据:crash和anr相关的数据。
所以它包含了APP进程的所有信息,通过它可以全方位监控并记录app的运行情况 。

上面说的ProcessRecord是代表着一个进程的所有数据信息,那AMS需要管理系统运行的所有
APP的进程,尤其是正在运行的app进程,这就需要使用一个List容器来进行管理 ,这个数据结构就是ProcessList类,

(2)ProcessList

lass ProcessList{
  ...
  private final int[] mOomAdj = new int[]{  //这里边存放着进程配置的相关优先级
    ...
  }

  ...
  //正在运行的应用ProcessRecord数组,根据最近使用的方式进行排序
  final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
  //正在运行的isolated(隔离的)进程
  final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>();
}

所以AMS通过ProcessList来持有系统上运行的所有app的ProcessRecord,但是进程也有优先级

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值