Android App安装以及启动流程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android App安装以及启动流程相关的知识,希望对你有一定的参考价值。

参考技术A

android App的安装可以分为有界面的安装和无界面的安装。

有界面的安装其实就是调用系统App(PackageInstaller)去安装apk,打开安装apk应用之后,点击安装按钮执行startInstall方法,然后就进入安装中界面开始安装,安装成功或者失败都会有对应的回调。内部其实也是使用PackageManager的installExistingPackage方法,通过binder机制,调用到PackageManagerService的installExistingPackage方法,最终调用到installExistingPackageAsUser方法安装,而 安装的核心原理其实就是将apk文件拷贝到系统可识别的重要的文件目录

无界面安装是调用adb命令,执行到一个c写的commandline脚本,调用 install_app 方法,然后再调用 pm_command ,然后执行到pm脚本,执行 run 方法,调用 runinstall ,然后调用 installPackageAsUser 通过AMS执行安装。

说到App的启动,就需要从开机开始说起,Android开机会先把所有应用安装一遍就是把apk拷贝到对应的目录(这也是Android开机慢的原因)。

整个流程如下:

其实App的启动,除了刚开机是不一样之外,正常时候基本与Activity的启动非常接近。

Android系统启动流程分析

一、启动初探

在android手机上,当我们点击桌面上的按钮启动一个应用,就能打开应用的界面。这里我们所说的桌面其实就是android系统启动后的就已经帮我们运行的第一个程序,launcher程序。

launcher程序可以理解为作为其它应用app入口管理的一个系统自带的app,正常情况下,安装一个新的应用,就会在桌面(laucher)程序中显示一个相应的图标。

上述点击桌面上的图标打开应用的过程,本质上是通过lancher应用的提供的桌面图标启动另一个app的过程,并打开了新应用的首个Activity。

很显然,上述的过程是两个应用之间的一个交互,属于跨进程的通信。

针对于上述流程中,今天我们先搞清楚第一个问题:

Android手机系统启动的流程,都干了些什么?另外,从launcher程序中打开一个应用的流程,暂不分析。

说明:不会涉及太多的源码分析,尤其相对底层非java层源码,本篇主要分析Android系统启动、App启动的流程,部分涉及到的源码为Android10.0源码。

二、Android系统启动流程

首先,我们来看一下android系统的启动架构图:

Android系统启动的过程是自下而上的一个过程,是由Boot Loader引导开机,然后依次进入:

Kernel->Native->FrameWork->App,从上图中也能看到在App层启动了我们的launcher应用。

1、BootLoader

板子上电后,芯片从固化在ROM里预设的代码(BOOT ROM)开始执行,BOOT ROM会加载BootLoader到RAM,然后把控制权交给BootLoader。

BootLoader并不属于Android系统,它的作用是初始化硬件设备,加载内核文件等,为Android系统内核启动搭建好所需的环境。

BootLoader是针对特定的主板和芯片的(与CPU以及电路板的配置情况有关),因此对于不同的设备制造商,他们的引导程序都是不同的。目前大多数系统都是是uboot来修改的。

BootLoader引导程序一般分两个阶段执行:

1.基本的硬件初始化,目的是为了下一个阶段的执行以及随后的kernel的执行准备好一些基本的硬件环境。这一阶段的代码通常是用汇编语言写的,以达到短小精焊的目的。

2.初始化Flash设备,设置网络、内存等等,将kernel映像和根文件系统映像从Flash上读到RAM空间中,然后启动内核。这段代码通常是用C语言来写的,以便于实现复杂的功能和取得更好的代码可读性和可移植性。

实际上BootLoader还需要根据misc分区的设置来决定是要正常启动系统内核还是要进入recovery进行系统升级,复位等工作。

2、Linux kernel

Linux内核负责初始化各种软硬件环境,加载驱动程序,挂载根文件系统等。最重要的是内核启动完成后,它会在根文件系统中寻找”init“文件,然后启动init进程

3、init进程

init进程是Linux系统中用户空间的第一个进程,进程号为1,我们可以说它是root进程或者是所有进程的父进程。

在init进程中,挂载虚拟文件系统、启动property服务、当然更重要的是包括了启动的各种系统服务:serviceManager、adbd、mediasever、zygote、bootanmation等。

4、zygote进程

zygote进程是Android系统最重要的进程之一。后续Android中的应用进程都是由zygote进程fork出来的。因此,zygote是Android系统所有应用进程的父进程。zygote进程实际执行文件并不是zygote,而是/system/bin/app_process。它会调用 frameworks/base/core/jni/AndroidRuntime.cpp 提供的接口启动 java 层的代码 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java。

public static void main(String argv[]) 
  .....
 zygoteServer = new ZygoteServer(isPrimaryZygote);
 Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
  .....

上面的ZygoteInit.java中的核心代码,ZygoteServer的构造函数:

/**
 * 初始化一个带有server socket的ZygoteServer进程。
 */
ZygoteServer(boolean isPrimaryZygote) 
    ....
        mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
        
    .....

”后续Android中的应用进程都是由zygote进程fork出来的“,上述zogoteInit的主要工作:

1、启动socket服务,监听socket,当有启动应用的请求到达的时候,fork生成app应用进程。

2、启动SystemServer进程。

5、systemServer进程

SystemServer进程,被称为系统服务进程,属于Android framework层的源码实现,通过android studio打开SystemServer.java,能够看到其中声明了大量的android的系统服务。简单看一下SystemServer.java的源码实现:

/**
 * zygote进程调用入口点
 */
public static void main(String[] args) 
    // systemServer的实际创建,并run起来
    new SystemServer().run();

private void run() 
   // 初始化系统上下文.
    createSystemContext();
   // 创建service manager.
     mSystemServiceManager = new SystemServiceManager(mSystemContext);
   // Start services.(启动服务)
    try 
       traceBeginAndSlog("StartServices");
       startBootstrapServices();//引导程序服务
       startCoreServices();//核心服务
       startOtherServices();//其它服务
       SystemServerInitThreadPool.shutdown();
      catch (Throwable ex) 
           ...
      

SystemServer的主要作用就是启动各种系统的服务和管理它们,包含三大类服务:

  1. BootstrapService:我们日常常用的ActivityMangerService、PowerManagerService、PackageManagerService;
  2. CoreService:BatteryService、UsageStatsService、WebViewUpdateService
  3. OtherService: WindowManagerService、InputManagerService、WatchDog(印象中做ANR采集的时候用到过,原来在这启动的服务)

6、launcher的启动

上述systemServer进程中启动的ActivityManagerService,最后会调用systemReady

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) 
  ...
    //9.0源码,此处的api有区别,建议直接查看10.0源码
     mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
    ...

上述代码,就是laucher程序的启动的入口函数,这里不做详细深入的launcher程序启动过多细节,Android10.0的源码和之前的源码有一些差别,主要是将很多职责交给了ActivityTaskManagerService来处理,需要追看源代码的可以从这里入手继续看。简单概括一下launcher程序的启动的流程:

  1. SystemServer完成启动Launcher Activity的调用(intent);
  2. Zygote进程进行Laucher进程的fork操作
  3. 进入到ActivityThread的main(),最终完成Launcher的onCreate方法的调用

2、3步骤,分析过Activity的启动过程源码的同学,一眼就能看出一致性。

7、BootAnimation退出

Launcher启动完成之后,开机动画会进行出,这样给用户的体验就是开机后,就直接进入到桌面了。

本篇文章部分文字描述摘自其它网络资源,源码部分皆为自行查看和注释。

参考文章:http://gityuan.com/android/,https://qiushao.net/
及时获得最新文章更新,关注gongzhonghao:Hym4Android

以上是关于Android App安装以及启动流程的主要内容,如果未能解决你的问题,请参考以下文章

Android系统启动流程分析

Android系统启动流程分析

从launcher程序启动App流程分析

Android 启动流程

Android 桌面应用启动APP的流程

Android 桌面应用启动APP的流程