Android-APP启动流程

引言

Android系统非常庞大、错综复杂,其底层是采用Linux作为基底,上层采用包含虚拟机的Java层以及Native层,通过系统调用(Syscall)连通系统的内核空间与用户空间。用户空间主要采用C++和Java代码,通过JNI技术打通用户空间的Java层和Native层(C++/C),从而融为一体。

Google官方提供了一张经典的四层架构图,从下往上依次分为Linux内核、系统库和Android运行时环境、框架层以及应用层这4层架构,其中每一层都包含大量的子模块或子系统。

在这里插入图片描述

系统启动

在这里插入图片描述

序号进程启动概述
1init进程Linux系统中用户空间的第一个进程, Init.main
2zygote进程所有App进程的父进程, ZygoteInit.main
3system_server进程系统各大服务的载体
4servicemanager进程binder服务的大管家, 守护进程循环运行在binder_loop
5app进程通过Process.start启动App进程, ActivityThread.main

AMS

AMS功能概述

  • 组件状态管理:包括四大组件的开启,关闭等一系列操作。如startActivity,startActivityAndWait,activityPaused,startService,stopService,removeContentProvider等
  • 组件状态查询:查询组件当前运行等情况。如getCallingActivity,getService等
  • Task相关:包括removeTask,removeSubTask,moveTaskBackwards,moveTaskToFront等
    AMS是通过ActivityStack及其他数据结构来记录,管理系统中的Activity及其他组件状态的,并提供查询功能的一个系统服务。

AMS启动

  • AMS在SystemServer的main()中启动。看代码:

    public static void main(String[] args) {
    new SystemServer().run();
    }

看run方法

  private void run() {
                             //创建消息Looper
               Looper.prepareMainLooper();
                             //加载动态库
               System.loadLibrary("android_servers");
     
               //创建系统Context
               createSystemContext();
   
               //创建SystemManager
               mSystemServiceManager = new SystemServiceManager(mSystemContext);
                             //启动引导服务
               startBootstrapServices();
                     //启动核心服务
               startCoreServices();
                     //启动其他服务
               startOtherServices();
                     //开启消息循环
               Looper.loop();
           throw new RuntimeException("Main thread loop unexpectedly exited");
       }

可以看到,这里创建了SystemManager,然后在startBootstrapServices()中用SystemManager创建了AMS,看代码:

    private void startBootstrapServices() {
             //创建AMS
           mActivityManagerService = mSystemServiceManager.startService(
                   ActivityManagerService.Lifecycle.class).getService();
}

可以看到这里调用了SystemManager.startService(),并传入了ActivityManagerService.Lifecycle来创建AMS,看代码:

       public <T extends SystemService> T startService(Class<T> serviceClass) {
                              //通过反射的方式创建service,并调用了构造方法
               Constructor<T> constructor = serviceClass.getConstructor(Context.class);
               service = constructor.newInstance(mContext);
                           //调用startService
               startService(service);
               return service;
       }

这里首先通过反射的方式创建了service,并调用了它的构造,最后调用()。startService0这个serviceClass是传进来的ActivityManagerService.Lifecycle,看一下这个类:

   public static final class Lifecycle extends SystemService {
           private final ActivityManagerService mService;
                
           public Lifecycle(Context context) {
               super(context);
                 //在构造里创建AMS
               mService = new ActivityManagerService(context);
           }
   
           @Override
           public void onStart() {
                 //调用AMS的start()
               mService.start();
           }
                 //返回AMS
           public ActivityManagerService getService() {
               return mService;
           }
       }

可以看到构造里构造了AMS。那么再看上一步的startService()

    public void startService(@NonNull final SystemService service) {
           //将创建的service保存到ArrayList类型的mServices中,完成注册
           mServices.add(service);
             //调用ActivityManagerService.Lifecycle的onStart()
           service.onStart();
      }

这里传入的service就是AMS,将它保存到ArrayList类型的mServices中完成注册,最后调用了service.onStart(),从上一步可知,最后调用的是AMS的start()。同样从上一步可知getService()也返回的是构造的AMS。

那么到这里AMS就启动并且返回了。

在这里插入图片描述

在这张图中,绿色的部分是在SDK中开放给应用程序开发人员的接口,蓝色的部分是一个典型的Proxy模式,红色的部分是底层的服务实现,是真正的动作执行者。这里的一个核心思想是Proxy模式。

APP启动

在这里插入图片描述

Activity启动
在经过前文的学习以后,我们一起来整理一下Activity的启动机制。就从Activity的startActivity()函数开始吧。

startActivity()函数调用了startActivityForResult()函数,该函数有源码如下:

    public void startActivityForResult(Intent intent, int requestCode) {

        ……

            Instrumentation.ActivityResult ar =

                mInstrumentation.execStartActivity(

                    this, mMainThread.getApplicationThread(), mToken, this,

                    intent, requestCode);

                   ……

    }

可见,功能被委托给Instrumentation对象来执行了。这个类的功能是辅助Activity的监控和测试,在此我们不详细描述,我们来看它的execStartActivity()函数。

    public ActivityResult execStartActivity(

        Context who, IBinder contextThread, IBinder token, Activity target,

        Intent intent, int requestCode) {

                   ……

        try {

            int result = ActivityManagerNative.getDefault()

                .startActivity(whoThread, intent,

                        intent.resolveTypeIfNeeded(who.getContentResolver()),

                        null, 0, token, target != null ? target.mEmbeddedID : null,

                        requestCode, false, false);

            checkStartActivityResult(result, intent);

        } catch (RemoteException e) {

        }

        return null;

    }

在这个函数里,我们看到了前文熟悉的ActivityManagerNative.getDefault(),没错,利用了ActivityManagerService。通过前文的线索,利用Proxy模式,我们可以透过ActivityManagerProxy,通过Binder的transact机制,找到真正的动作执行者,即ActivityManagerService类的startActivity()函数,并沿此线索继续追踪源码,在startActivityLocked()函数里边看到了mWindowManager.setAppStartingWindow的语句调用,mWindowManager是WindowManagerService对象,用于负责界面上的具体窗口调试。

通过这样的源码追踪,我们了解到了Activity启动的底层实现机制,也加深了对Proxy模式和Binder机制的理解。

在这里插入图片描述

Android启动

在这里插入图片描述

init

init程序:创建用户空间
init处理的重要事情:
1.挂载文件
2.设置selinux – 安全策略
3.开启属性服务,注册到epoll中
4.解析init.rc
5.循环处理脚本-- 启动zygote
6.循环等待

init.rc :启动zygot

zygote

zygote的cpp启动: AndroidRuntime:start启动android环境 ->启动startVM(虚拟机):一系列初始化-》startReg(注册JNI)->
env->CailstaticVoidMethod(startClass,startMeth,strArray); --》 main@ZygoteInit

zygote的java启动:
1、preload(bootTimingsTraceLog); // 预加载,加快进程的启动
2、zygoteServer = new ZygoteServer(isPrimaryZygote); //socket
3、Runnable r = forkSystemServer // 启动 systemServer 进程,AMS
4、caller = zygoteServer.runSelectLoop(abiList);// 死循环,接收AMS传过来的消息

zygote总结:
1、初始化运行环境,创建jvm
2、注册jni
3、调用zygote.main

java
1、预加载
2、socket
3、循环等待

进程和虚拟机是什么关系?
zygote进程 ->startVm 启动虚拟机(进程里面)(虚拟机实现内存管理功能)

1、多个进程,每个进程里都有一个虚拟机JVM、Native
2、zygote也是一个进程,负责初始化jvm,fork其他进程

为什么使用socket通信,不使用binder?
答:因为binder是多线程运行,fork的时候是复制,锁在线程上,fork的时候线程没有了,导致无法解锁,造成死锁

在这里插入图片描述

            pid = Zygote.forkSystemServer(
                    parsedArgs.mUid, parsedArgs.mGid,
                    parsedArgs.mGids,
                    parsedArgs.mRuntimeFlags,
                    null,
                    parsedArgs.mPermittedCapabilities,
                    parsedArgs.mEffectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
          //判断pid 是否为0 如果是0,则为孩子进程的id就说明的zygote进程,不是0则为自己zygote
      if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
            //关掉子进程的socket服务器关掉
            zygoteServer.closeServerSocket();
            //调用zygoteInit -》  native void nativeZygoteInit() 调用jni方法
            return handleSystemServerProcess(parsedArgs);
        }

在这里插入图片描述

SystemServer

在这里插入图片描述

理解: SystemServer就是系统用来启动service的入口。
Android系统在启动的时候,在启动两个重要的进程,一个是Zygote进程
另一个是由zygote进程fork出来的system_server进程;
SystemServer会启动我们在系统中所需要的一系列service

1、startServer里由SystemSeriveManager进行管理,服务都要继承SystemSerice。

共有两种方式:
a、内部类,继承SystemSerice,解决了只能集成一个父类的问题。
ActivityTaskManagerService、ActivityManagerService等,因为需要提供给APP使用,必须继承binder服务,所以使用了内部类继承SystemSerice

SystemServer.java ->
//SystemServer里启动ActivityTaskManagerService
        ActivityTaskManagerService atm = mSystemServiceManager.startService(
                ActivityTaskManagerService.Lifecycle.class).getService();

ActivityTaskManagerService.java ->

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {


    public static final class Lifecycle extends SystemService {
        private final ActivityTaskManagerService mService;

        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityTaskManagerService(context);
        }

        @Override
        public void onStart() {
        //将ATMS注册到ServerManage里(binder),服务注册,客户端可使用
            publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
            mService.start();
        }

        @Override
        public void onUserUnlocked(@NonNull TargetUser user) {
            synchronized (mService.getGlobalLock()) {
                mService.mTaskSupervisor.onUserUnlocked(user.getUserIdentifier());
            }
        }

        @Override
        public void onUserStopped(@NonNull TargetUser user) {
            synchronized (mService.getGlobalLock()) {
                mService.mTaskSupervisor.mLaunchParamsPersister
                        .onCleanupUser(user.getUserIdentifier());
            }
        }

        public ActivityTaskManagerService getService() {
            return mService;
        }
    }

    }

b、直接继承:PowerManagerService extends SystemService

SystemServer.java ->
        mPowerManagerService  = mSystemServiceManager.startService(PowerManagerService.class);



public final class PowerManagerService extends SystemService

管理90多个服务

Android系统启动面试

主要分为三步,init、zygote、systemserve。

init:

创建用户空间
init处理的重要事情:
1.挂载文件
2.设置selinux – 安全策略
3.开启属性服务,注册到epoll中
4.解析init.rc
5.循环处理脚本-- 启动zygote
6.循环等待
init.rc :启动zygot

zygote:

1、初始化运行环境,创建jvm
2、注册jni
3、调用zygote.main(java层)

zygote.main(java层):
1、预加载
2、创建socket服务
3、fork systemServer 进程
4、执行systemServer的main方法
5、循环监听是否需要fork进程

SystemServer

负责管理和启动70多个不同的服务,AMS,WMS,电源等。内部有systemServeiceManager对SystemService进行管理,电池等服务都要继承SystemService,AMS,ATMS这些需要继承binder的方法就会使用内部类的方式,去关联SystemService

AMS面试

android10.0之前,startActivity启动的是system_server里的AMS,10.0之后是ATMS。

AMS

在这里插入图片描述

ActivityTaskManageService作用:对Activity的管理

ActivityManageService作用:对四大组件的管理,启动注册进程的一些服务(如下代码)

ActivityManageService.java
    public void setSystemProcess() {
        try {
           // 注册服务activity
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,DUMP_FLAG_PRIORITY_CRITICAL |DUMP_FLAG_PRIORITY_NORMAL|DUMP_FLAG_PROTO);
            // 注册服务procstats,进程状态
            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
            //注册服务meminfo,内存信息
            ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
                    DUMP_FLAG_PRIORITY_HIGH);
           //注册服务qfxinfo,图像信息
            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
            //注册服务dbinfo,数据库信息
            ServiceManager.addService("dbinfo", new DbBinder(this));
            //注册服务cpuinfo,cpu信息
            mAppProfiler.setCpuInfoService();
            //注册服务permission和processinfo,权限和进程信息
            ServiceManager.addService("permission", new PermissionController(this));
            //注册进程信息
            ServiceManager.addService("processinfo", new ProcessInfoService(this));
            //注册缓存信息
            ServiceManager.addService("cacheinfo", new CacheBinder(this));
            }
        }

注册服务。首先将ActivityManagerService注册到ServiceManager中,其次将几个与系统性能调试相关的服务注册到ServiceManager。
查询并处理Applicationlnfo。首先调用PackageManagerService的接口,查询包名为android的应用程字的Applicationlnfo信息,对应于framework-res.apk。然后以该信息为参数调用ActivityThread上的installSystemApplicationlnfo方法
创建并处理ProcessRecord,调用ActivityManagerService上的newProcessRecordLocked,创建一ProcessRecord类型的对象,并保存该对象的信息

执行Activity的启动

第一阶段:启动的Activity的各种参数进行解读
第二阶段:ActivityStack,处理栈里的要启动和未启动的Activity进行管理和处理,再真正的进行startActivity,将启动的事件封装成clinentTransaction,里面包含了启动Activity的所有的命令
第三阶段:将clinentTransaction命令,通过跨进程通信,转交给app,执行onResume、onCreate等方法
第四阶段:空闲的时候,发命令给ATMS,ATMS也是一样传命令给ActivityA,执行stop

AMS

关键函数:
ActvityManagerServcie的重要功能:
start()函数知道: 1)启动 CPU 监控线程; 2) 注册电池状态和权限管理服务
startObservingNativeCrashes()函数知道: 监听所有的crash事件
setSystemProcess()函数知道: 添加各种管理app状态信息的服务还有进程等等信息,以及初始化

processList:有Activity的基本参数

AMS持有 ProcessList 去管理 ProcessRecord(代表一个APP进程) ——》AppThread
第一个流程
解读参数
启动黑白屏的时候,Activity的进程还没启动,因为启动Activity是很漫长的过程

先启动黑白屏,再启动Activity
window的显示

第二个流程
A -》 B 先创建进程,再

AMS:app进程封装clientTransaction schele

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值