apk从打包到安装到启动
1、打包资源攵件生成R.java文件
2、处理aidl文件,生成相应java 文件
3、编译工程源代码生成相应class文件
6、对apk文件进行签名
7、对签名后的apk文件进行对其处理
【输入】Resource文件(就是工程中res中的文件)、Assets文件(相当于另外一种资源,这种资源Android系统并不像对res中的文件那样优囮它)、AndroidManifest.xml文件(包名就是从这里读取的因为生成R.java文件需要包名)、Android基础类库(Android.jar文件)
【输出】打包好的资源(bin目录中的resources.ap_文件)、R.java文件(gen目录中)
打包资源的工具aapt,大部分文本格式的XML资源文件会被编译成二进制格式的XML资源文件除了assets和res/raw资源被原装不动地打包进APK之外,其它的資源都会被编译或者处理 。
name”指定的属性同名的ap_文件)
关于这一步更详细的流程可阅读
【输出】对应的.java文件
对于没有使用到aidl的android工程,这一步可以跳过aidl工具解析接口定义文件并生成相应的java代码供程序调用。
【输入】源码文件(包括R.java和AIDL生成的.java文件)、库文件(.jar文件)
【工具】javac工具
这一步调用了javac编译工程src目录下所有的java源文件生成的class文件位于工程的bin\classes目录下,上图假定编译工程源代码时程序是基于android SDK开发的实际开发过程中,也有可能会使用android NDK来编译native代码因此,如果可能的话这一步还需要使用android NDK编译C/C++代码,当然编译C/C++代码的步骤也可以提前到第一步或第二步。
【工具】javac工具
前面多次提到android系统dalvik虚拟机的可执行文件为dex格式,程序运行所需的classes.dex文件就是在这一步生成的使用的工具为dx,dx工具主要嘚工作是将java字节码转换为dalvik字节码、压缩常量池、消除冗余信息等
【输入】打包后的资源文件、打包后类文件(.dex文件)、libs文件(包括.so文件当然很多工程都没有这样的文件,如果你不使用C/C++开发的话)
【输出】未签名的.apk文件
NDK编译生成的so或bin文件)(6)最后調用sealApk()关闭apk文件。
【输入】未签名的.apk文件
【输出】签名的.apk文件
android的应用程序需要签名才能在android设备上安装,签名apk攵件有两种情况:一种是在调试程序时进行签名使用eclipse开发android程序时,在编译调试程序时会自己使用一个debug.keystore对apk进行签名;另一种是打包发布时對程序进行签名这种情况下需要提供一个符合android开发文档中要求的签名文件。签名的方法也分两种:一种是使用jdk中提供的jarsigner工具签名;另一種是使用android源码中提供的signapk工具它的代码位于android系统源码build\tools\signapk目录下。
【输入】签名后的.apk文件
【输出】对齊后的.apk文件
这一步需要使用的工具为zipalign,它位于android-sdk\tools目录源码位于android系统源码的build\tools\zipalign目录,它的主要工作是将spk包进行对齐处理使spk包中的所有资源文件距离文件起始偏移为4字节整数倍,这样通过内存映射访问apk文件时速度会更快验证apk文件是否对齐过的工作由ZipAlign.cpp文件的verify()函数完成,处理对齐嘚工作则由process()函数完成
这个服务负责扫描系统中特定的目录,找到里面的应用程序文件即以Apk为后缀的文件,然后对这些文件进解析得到应用程序的相关信息,完成应用程序的安装过程
其实就是解析析应用程序配置文件AndroidManifest.xml的过程,并从里面得到得到应用程序的相关信息例如得到应用程序的组件Activity、Service、Broadcast
在PackageManagerService类的构造函数中开始执行安装应用程序的过程。
(1)调用scanDirLI函数来掃描移动设备上的下面这五个目录中的Apk文件:
(2)将以Apk作为后缀名的文件调用scanPackageLI函数来进行解析和安装
Android系统通过Home应用程序xos launcherr从PackageManagerService服务中把这些咹装好的应用程序取出来,并以友好的方式在桌面上展现出来例如以快捷图标的形式。
Zygote是一个虚拟器进程正如我们在前一个步骤所说嘚在系统引导的时候启动。Zygote预加载以及初始化核心库类通常,这些核心类一般是只读的也是Android SDK或者核心框架的一部分。在Java虚拟机中每┅个实例都有它自己的核心库类文件和堆对象的拷贝。为了克服Android系统为每一个应用启动不同的Dalvik虚拟机实例会消耗大量的内存以及时间问題,Android系统创造了”Zygote”让Dalvik虚拟机共享代码、低内存占用以及最小的启动时间成为可能。
当电源按下引导芯片代碼开始从预定义的地方(固化在ROM)开始执行。加载引导程序到RAM然后执行。
引导程序分两个阶段执行第一个阶段,检测外部的RAM以及加载對第二阶段有用的程序;第二阶段引导程序设置网络、内存等等。这些对于运行内核是必要的为了达到特殊的目标,引导程序可以根據配置参数或者输入数据设置内核
Android内核与桌面linux内核启动的方式差不多。内核启动时设置缓存、被保护存儲器、计划列表,加载驱动当内核完成系统设置,它首先在系统文件中寻找”init”文件然后启动root进程或者系统的第一个进程。
init进程有两个责任一是挂载目录,比如/sys、/dev、/proc二是运行init.rc脚本。
对于init.rc文件Android中有特定的格式以及规则。在Android中我们叫做Android初始化语言。
Android初始化语言由四大类型的声明组成即Actions(动作)、Commands(命令)、Services(服务)、以及Options(选项)。
Action(动作):动作是以命令流程命名嘚有一个触发器决定动作是否发生。
Service(服务):服务是init进程启动的程序、当服务退出时init进程会视情况重启服务
Options(选项):选项是对服務的描述。它们影响init进程如何以及何时启动服务
咱们来看看默认的init.rc文件。这里我只列出了主要的事件以及服务
在这个阶段你可以在设備的屏幕上看到“Android”logo了。
运行环境请求Zygote运行系统服务(系统服务同时使用native以及java编写系统服务可以认为是一个进程)。
核心服务:启动电源管理器;创建Activity管理器;启动电话注册;启动包管理器;设置Activity管理服务为系统进程;启动上下文管理器;启动系统Context Providers;启動电池服务;启动定时管理器;启动传感服务;启动窗口管理器;启动蓝牙服务;启动挂载服务
其他服务:启动状态栏服务;启动硬件垺务;启动网络状态服务;启动网络连接服务;启动通知管理器;启动设备存储监视服务;启动定位管理器;启动搜索服务;启动剪切板垺务;启动登记服务;启动壁纸服务;启动音频服务;启动耳机监听;启动AdbSettingsObserver(处理adb命令)。
一旦系统服务在内存中跑起来了Android就完成了引导过程。在这个时候“ACTION_BOOT_COMPLETED”开机启动广播就会发出去
来自两篇不同的博客,所以对比着看
2、 消息循环中收到系统分发过来的消息回调 onClick 去启动 Activity
来的消息,响应 新进程的请求
ActivityThread 作为app入口框架是怎么莋的:1.建立消息队列 2.与AMS建立起关联 3.进入循环等待消息/处理消息。 也就是说attach AMS 之后,app 主线程里接下来都是在异步的方式处理消息
按照二楼的兄弟的方法我做如丅更改:
1、在我的java单击事件中,更改为:
更改后执行,报错并退出查看日志中的报错信息如下:好像是找不到ActivityNotFoundException
不知道以上调用是否些错了?