目录
一、Android APK的构建过程
通过IDE可以生成可以在android设备中安装的apk文件,Google官方提供的构建APK的过程流程图如下:
- 打包APK流程总结如下:
- AAPT(Android Asset Packaging Tool)工具会打包应用中的资源文件,如AndroidManifest.xml、layout布局中的xml等,并将xml文件编译为二进制形式,当然assets文件夹中的文件不会被编译,图片及raw文件夹中的资源也会保持原来的形态,需要注意的是raw文件夹中的资源也会生成资源id。AAPT编译完成之后会生成R.java文件。
- AIDL工具会将所有的aidl接口转化为java接口。
- 所有的java代码,包括R.java与aidl文件都会被Java编译器编译成.class文件。
- Dex工具会将上述产生的.class文件及第三库及其他.class文件编译成.dex文件(dex文件是Dalvik虚拟机可以执行的格式),dex文件最终会被打包进APK文件。
- ApkBuilder工具会将编译过的资源及未编译过的资源(如图片等)以及.dex文件打包成APK文件。
- 生成APK文件后,需要对其签名才可安装到设备,平时测试时会使用debug keystore,当正式发布应用时必须使用release版的keystore对应用进行签名。
- 如果对APK正式签名,还需要使用zipalign工具对APK进行对齐操作,这样做的好处是当应用运行时会提高速度,但是相应的会增加内存的开销。
我们知道,通过Intent就可以执行APK安装的,执行如下代码后,我们就会打开安装apk文件的程序并执行安装逻辑了,大家应该都知道这段代码执行的结果是打开一个隐式的Activity,即PackageInstallerActivity。
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.parse("file://" + path),"application/vnd.android.package-archive");
context.startActivity(intent);
- 安装APK流程总结如下:
- 代码中执行intent.setDataAndType(Uri.parse(“file://” + path),”application/vnd.android.package-archive”);可以打开隐士的PackageInstallerActivity。
- PackageInstallerActivity主要用于执行解析apk文件;解析manifest.xml、解析签名等操作。
- 点击安装按钮,调起InstallAppProcess,这个Activity主要用于执行安装apk逻辑,用于初始化安装界面,用于初始化用户UI;并调用PackageInstaller执行安装逻辑。
- InstallAppProcess内注册有广播,当安装完成之后接收广播,更新UI。显示apk安装完成界面。
二、Android 应用进程启动过程
首先,Android在系统架构分为四个层面。从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和linux核心层。另外,进程是系统的执行单位。Linux系统是核心底层,那么Android的其他进程都是基于Linux进程的根进程init进程,因此它可以算作是整个android操作系统的第一个进程。最后,我们知道android系统的Zygote进程是所有的android进程的父进程,包括SystemServer和各种应用进程都是通过Zygote进程fork出来的。而Zygote进程则是通过linux系统的init进程启动的,也就是说,android系统中各种进程的启动方式及顺序是:
init进程 –> Zygote进程 –> SystemServer进程 –>各种应用进程
各种应用进程:启动自己编写的客户端应用时,一般都是重新启动一个应用进程,有自己的虚拟机与运行环境;
init进程在启动Zygote进程时一般都会调用ZygoteInit类的main方法,Zygote进程mian方法主要执行逻辑:
-
初始化DDMS;
-
注册Zygote进程的socket通讯;
-
初始化Zygote中的各种类,资源文件,OpenGL,类库,Text资源等等;
-
初始化完成之后fork出SystemServer进程;
-
fork出SystemServer进程之后,关闭socket连接;
其实,SystemServer进程主要的作用是启动各种系统服务,比如ActivityManagerService,PackageManagerService,WindowManagerService等服务。我们平时熟知的各种系统性的服务其实都是在SystemServer进程中启动的,而当我们的应用需要使用各种系统服务的时候,其实也是通过与SystemServer进程通讯获取各种服务对象的句柄来执行相应的操作。
-
SystemServer进程启动服务的启动函数为main函数;
-
SystemServer在执行过程中首先会初始化一些系统变量,加载类库,创建Context对象,创建SystemServiceManager对象等之后才开始启动系统服务;
-
SystemServer进程将系统服务分为三类:boot服务,core服务和other服务,并逐步启动;
-
SystemServer进程在尝试启动服务之前会首先尝试与Zygote建立socket通讯,只有通讯成功之后才会开始尝试启动服务;
-
创建的系统服务过程中主要通过SystemServiceManager对象来管理,通过调用服务对象的构造方法和onStart方法初始化服务的相关变量;
-
服务对象都有自己的异步消息对象,并运行在单独的线程中;
其实,我们知道SystemServer进程主要用于启动系统的各种服务,而且其中就包含负责启动Launcher程序的服务-LauncherAppService。Launcher 程序就是我们平时看到的桌面程序,它其实也是一个android应用程序,只不过这个应用程序是系统默认第一个启动的应用程序,这里我们就简单的分析一下Launcher应用的启动流程。
前面说SystemServer调用三个内部方法分别启动boot service、core service和other service。在调用startOtherService方法中就会通过调用mActivityManagerService.systemReady()方法。
public void systemReady(final Runnable goingCallback) {
...
// Start up initial activity.
mBooting = true;
startHomeActivityLocked(mCurrentUserId, "systemReady");
...
}
这个方法体中调用了startHomeActivityLocked方法,看名字就知道开始执行启动homeActivity的操作。好了,既然如此,我们再看一下startHomeActivityLocked的具体实现