Android App安装以及启动流程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android App安装以及启动流程相关的知识,希望对你有一定的参考价值。
参考技术Aandroid 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的主要作用就是启动各种系统的服务和管理它们,包含三大类服务:
- BootstrapService:我们日常常用的ActivityMangerService、PowerManagerService、PackageManagerService;
- CoreService:BatteryService、UsageStatsService、WebViewUpdateService
- 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程序的启动的流程:
- SystemServer完成启动Launcher Activity的调用(intent);
- Zygote进程进行Laucher进程的fork操作
- 进入到ActivityThread的main(),最终完成Launcher的onCreate方法的调用
2、3步骤,分析过Activity的启动过程源码的同学,一眼就能看出一致性。
7、BootAnimation退出
Launcher启动完成之后,开机动画会进行出,这样给用户的体验就是开机后,就直接进入到桌面了。
本篇文章部分文字描述摘自其它网络资源,源码部分皆为自行查看和注释。
参考文章:http://gityuan.com/android/,https://qiushao.net/
及时获得最新文章更新,关注gongzhonghao:Hym4Android
以上是关于Android App安装以及启动流程的主要内容,如果未能解决你的问题,请参考以下文章