apk简单介绍(组成以及打包安装流程)
apk简单介绍
- APK 的组成
- apk安装流程
- app的启动过程
- apk打包流程
- AIDL
- AIDL介绍
- 为什么要设计这门语言
- 它有哪些语法?
- 默认支持的数据类型包括
- 什么是apk打包流程
- 了解打包流程能做什么操作
APK 的组成
APK 其实是一个 zip 类型的压缩包,而一个典型的 APK 通常都会包含了以下七部分的内容:
- AndroidManifest.xml:如果 App 是一本书,那么这个文件就是它的 “封面” 和 “目录” 。它记载了 App 的名称、权限声明、所包含的组件等一系列信息。
- classes.dex:它是由项目源码生成的 .class 文件经过进一步地转换而生成的 Android 系统可识别的 Dalvik Byte Code。并且,由于 Android 系统中的字节码和标准 JVM 中的字节码是有区别的,所以如果 App 中引用了第三方 jar 包的话,那么通常情况下它也会被包含在 classes.dex 中。
- resources.arsc:资源索引表,包含编译后的二进制资源文件。每当在 res 文件夹下放一个文件时,aapt 就会自动生成对应的 id 并保存在 .R 文件中,但 .R 文件仅仅只是保证编译程序不会报错,实际上在应用运行时,系统会根据 ID 寻找对应的资源路径,而 resources.arsc 文件就是用来记录这些 ID 和 资源文件位置对应关系 的文件。
- res 目录:未编译的资源文件。
- asserts:额外建立的资源文件夹。res 和 assets 的不同在于 res 目录下的文件会在 .R 文件中生成对应的资源 ID,而 assets 不会自动生成对应的 ID,而是通过 AssetManager 类的接口来获取。
- libs 目录:如果存在的话,存放的是 ndk 编出来的 so 库 。
- META-INF 目录:用于保存 App 的签名和校验信息,以保证程序的完整性。当生成 APK 包时,系统会对包中的所有内容做一次校验,然后将结果保存在这里。而手机在安装这一 App 时还会对内容再做一次校验,并和 META-INF 中的值进行比较,以避免 APK 被恶意篡改。其中包含如下三个文件:
- MANIFEST.MF:其中每一个资源文件都有一个对应的 SHA-256-Digest(SHA1) 签名,MANIFEST.MF 文件的 SHA256(SHA1) 经过 base64 编码的结果即为 CERT.SF 中的 SHA256(SHA1)-Digest-Manifest 值。
- CERT.SF:除了开头处定义的 SHA256(SHA1)-Digest-Manifest 值,后面几项的值是对 MANIFEST.MF 文件中的每项再次 SHA256(SHA1) 经过 base64 编码后的值。
- CERT.RSA:其中包含了公钥、加密算法等信息。首先,对前一步生成的 CERT.SF 使用了 SHA256(SHA1)生成了数字摘要并使用了 RSA 加密,接着,利用了开发者私钥进行签名。然后,在安装时使用公钥解密。最后,将其与未加密的摘要信息(MANIFEST.MF文件)进行对比,如果相符,则表明内容没有被修改。
apk安装流程
Android apk的安装过程主要氛围以下几步:
- 复制apk到/data/app目录下,解压并扫描安装包
- 资源管理器解析apk里的资源文件
- 解析AndroidManifest文件,并在/data/data/目录下创建对应的应用数据目录
- 然后对.dex文件进行优化,并保存在dalvik-cache目录下
- 将AndroidManifest文件解析出的四大组件信息注册到PackageManagerService中
- 安装完成后,发送广播
app的启动过程
- 当点击桌面app时,launch进程中的startActvity方法通过binder通信调用system_server进程管理的AMS中的startActivity,而AMS又继续调用ATMS(ActivityTaskManagerService)的startActivity方法进行真正的启动
- system_server进程收到消息后向Zygote进程发送创建进程的请求(通过socket通信)
- Zygote进程fork出app进程,并执行ActivityThread的main方法
- 从main方法中可以看到创建ActivityThread之后调用了thread.attach(false, startSeq)方法,并同时初始化ApplicationThread用于和AMS通信
- App进程,通过Binder向sytem_server进程发起attachApplication请求,这里实际上就是APP进程通过Binder调用sytem_server进程中AMS的attachApplication方法,AMS的attachApplication方法的作用是将ApplicationThread对象与AMS绑定
- system_server进程在收到attachApplication的请求,进行一些准备工作后,再通过binder IPC向App进程发送handleBindApplication请求(初始化Application并调用onCreate方法)和scheduleLaunchActivity请求(创建启动Activity)
- App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送BIND_APPLICATION和LAUNCH_ACTIVITY消息,这里注意的是AMS和主线程并不直接通信,而是AMS和主线程的内部类ApplicationThread通过Binder通信,ApplicationThread再和主线程通过Handler消息交互
- 主线程在收到Message后,创建Application并调用onCreate方法,再通过反射机制创建目标Activity,并回调Activity.onCreate()等方法
- 到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染后显示APP主界面
apk打包流程
生成一个Apk包需要经历的过程,大致可以分为9步
- aapt把resources目录下的资源生成R.java文件 ,并为AndroidManifest.xml生成Manifest.java类
- 通过AIDL工具处理AIDL文件,生成对应的java类
- JavaCompiler把所有的Java源文件编译成class文件,包括:aapt生成的、aidl生成的、项目中自有的java源文件
- 使用proguard混淆,并生成一个proguardMapping.xml文件(可选项:可以混淆也可以不混淆)
- 使用dex工具把所有的class文件生成.dex文件
- 使用aapt资源打包工具把resources、assets目录下的资源打包成一个_ap文件
- 使用apkbuilder把所有的dex、_ap文件、AndroidManifest.xml文件打包成一个未签名的apk
- 使用jarsinger生成一个签名过的apk包
- 使用zipalign工具对要发布的apk文件进行对齐操作,以便在运行时节约内存
AIDL
AIDL介绍
AIDL(Android 接口定义语言),可以使用它定义客户端与服务端进程间通信(IPC)的编程接口。在Android系统中,每个进程都运行在一块独立的内存中,在其中完成自己的各项活动,与其他进程都分隔开来。可是有时候我们又有应用间进行互动的需求,比较传递数据或者任务委托等,AIDL就是为了满足这种需求而诞生的。通过AIDL,可以在一个进程中获取另一个进程的数据和调用其暴露出来的方法,从而满足进程间通信的需求。
AIDL是用于定义服务端和客户端通信接口的一种描述语言,可以拿来生产IPC代码,从某种意义上说AIDL其实就是一个模板,因为在使用过程中,实际起作用的并不是AIDL文件,而是据此生产的一个Interface的实例代码, AIDL其实是为了避免我们重复写代码而出现的一个模板。
为什么要设计这门语言
设计这门语言的目的是为了实现进程间通信,尤其是在涉及多进程并发情况下的进程间通信
它有哪些语法?
AIDL这门语言比较简单,基本上它的语法和 Java 是一样的,只是在一些细微处有些许差别,毕竟它只是被创造出来简化Android程序员工作的,太复杂不好,所以在这里我就着重的说一下它和 Java 不一样的地方。主要有下面这些点:
- 文件类型
用AIDL书写的文件的后缀是 .aidl,而不是 .java- 数据类型
AIDL默认支持一些数据类型,在使用这些数据类型的时候是不需要导包的,但是除了这些类型之外的数据类型,在使用之前必须导包,就算目标文件与当前正在编写的 .aidl 文件在同一个包下,在 Java 中这种情况是不需要导包的。比如现在我们编写了两个文件,一个叫做Book.java ,另一个叫做 BookManager.aidl,它们都在com.lypeer.aidldemo包下 ,现在我们需要在.aidl 文件里使用Book对象,那么我们就必须在 .aidl 文件里面写上 import com.lypeer.aidldemo.Book,哪怕 .java 文件和 .aidl 文件就在一个包下
默认支持的数据类型包括
- Java中的八种基本数据类型:byte,short,int,long,float,double,boolean,char
- String 类型
- CharSequence类型
- List类型:List中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable(List可以使用泛型)
- Map类型:Map中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable(Map是不支持泛型的)
什么是apk打包流程
app的打包流程是指通过把资源(图片、文本)、源代码等资源打包成一个apk的过程
了解打包流程能做什么操作
通过了解打包流程我们可以对app打包的过程进行干涉
比如:
- 在热更新项目中我们可以干涉R.java中资源id的生成来防止宿主app和插件app资源冲突
- 我们可以在编译前通过注解的形式生成辅助类从而优化代码量和代码结构(ButterKnife、Digger)
- 通过javac把源代码编译成class文件后,在生成dex前我们可以对class文件进行干涉,动态的生成class文件(无痕埋点)
相关文章:
apk简单介绍(组成以及打包安装流程)
apk简单介绍APK 的组成apk安装流程app的启动过程apk打包流程AIDLAIDL介绍为什么要设计这门语言它有哪些语法?默认支持的数据类型包括什么是apk打包流程了解打包流程能做什么操作APK 的组成 APK 其实是一个 zip 类型的压缩包,而一个典型的 APK 通常都会包…...
ffmpeg学习笔记之SDL视频播放器
看了雷神的 100行代码实现最简单的基于FFMPEGSDL的视频播放器(SDL1.x) 后手痒难耐,决定将里面的代码重新建一个 首先建立一个空项目,新建一个Mysimplest.cpp的文件。在里面写代码 #include <stdio.h>extern "C" …...

【Git】合并多条 commit 注释信息
文章目录1、查看 commit 记录2、合并 commit 注释1、查看 commit 记录 # 3 指的是查看最近 3 次的 commit 记录,如果要查看多次的可以修改数字 # -3 不加,则表示查看所有 commit 记录,一般还是用数字去指定 git log -32、合并 commit 注释 …...

【gcc/g++】程序的翻译(.c -->.exe)
环境:centos7.6,腾讯云服务器Linux文章都放在了专栏:【Linux】欢迎支持订阅🌹前言我们在写完代码运行时会发现生成了一个.exe的可执行程序,那么该程序是如何形成的呢?本次章节将在linux下用编译器gcc进行一…...

电话号码的字母组合-力扣17-java
一、题目描述给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。示例 1:输入:digits "23"输出…...

Archery-SQL审核查询平台
Archery-SQL审核查询平台 文章目录Archery-SQL审核查询平台一、功能列表介绍1.1、SQL审核MySQL实例非MySQL实例审核执行分离SQL工单自动审批、高危语句驳回快速上线其他实例定时执行1.2、SQL查询多类型数据库支持授权管理页面体验1.3、SQL优化慢日志管理SQL语句优化1.4、实例管…...

MySQL8.0安装教程
文章目录1.官网下载MySQL2.下载完记住解压的地址(一会用到)3.进入刚刚解压的文件夹下,创建data和my.ini在根目录下创建一个txt文件,名字叫my,文件后缀为ini,之后复制下面这个代码放在my.ini文件下ÿ…...

一文详解工业知识模型互联平台MoHub
1月8日,MWORKS 2023产品发布会落下帷幕。会上,同元软控隆重推出了云原生的工业知识模型互联平台MoHub,引起广泛关注。本文将从服务定位、架构方案、核心服务、持续运营等方面对MoHub平台进行全面介绍。1 MoHub平台的服务定位装备数字化的必要…...
MySQL入门篇-MySQL表连接小结
备注:测试数据库版本为MySQL 8.0 这个blog我们来聊聊常见的表连接的方法 测试数据: create table t1(id int); create table t2(id int);insert into t1 values(1); insert into t1 values(2);insert into t2 values(2); insert into t2 values(3); commit;内连接 --求交集 …...

使用纹理(Textures)
当物体表面并非是纯色的时候,比如带波点,斑纹或者表面有刮痕或被裂纹等,这些效果该如何实现呢? 这里我们需要提到一个概念是贴图(Maps)。Maps是覆盖在游戏物体上的2D图片,用来设置表面的颜色、s…...
android 11 添加开机铃声
需求:在11.0在定制化系统中,默认是没有开机铃声的,有客户提出需要要添加开机铃声,所以为了完成需求,就来实现这一个功能关于开机铃声 都是在bootanimation_main.cpp 这里面负责管理。添加添加开机铃声的核心类framewor…...

操作系统考试突击复习笔记
0 基础概念补充特权命令:有特殊权限的指令,比如清内存、置时钟、分配系统资源、修改虚拟内存的段表和页表,修改用户的访问权限。系统调用:操作系统为应用程序提供的使用接口,可以理解为一种可供应用程序调用的特殊函数…...
java8函数式接口分布式事务简单实现方式
import java.util.List; import java.util.function.Function;/*** @ClassName TransactionFunctionDTO* @Description* @Author SD.LIU* @Date 2023/2/13 22:41* @Version 1.0**/ public class TransactionFunctionDTO...

最后一个单词的长度-力扣58-java
一、题目描述给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。示例 1:输入:s "Hello World"输出&#x…...

Java开发学习(四十九)----MyBatisPlus更新语句之乐观锁
1、概念 在讲解乐观锁之前,我们还是先来分析下问题: 业务并发现象带来的问题:秒杀 假如有100个商品或者票在出售,为了能保证每个商品或者票只能被一个人购买,如何保证不会出现超买或者重复卖 对于这一类问题,其实有很多的解决方…...

力扣SQL刷题11
目录标题1194. 锦标赛优胜者--做出来了1225. 报告系统状态的连续日期-勉强1159. 市场分析 II1205. 每月交易II1194. 锦标赛优胜者–做出来了 题型:看题 解答:先处理matches表,整出分数列和players表连接 注意点: union all 时…...
Fluent Python 笔记 第 9 章 符合 Python 风格的对象
得益于 Python 数据模型,自定义类型的行为可以像内置类型那样自然。实现如此自然的行为,靠的不是继承,而是鸭子类型(duck typing):我们只需按照预定行为实现对象所需的方法即可。 9.1 对象表示形式 实现 __repr__ 和 __str__ 特…...
档案管理数字化,成功的领导者,往往只问这3个问题
随着数字经济时代的到来,信息技术的更迭演进,逐渐改变了企业的办公业务流程,传统的办公业务模式已不能满足当前的企业业务需求。数字化转型成为当下企业的必选项。随着公司部门架构的日益复杂,流程繁多,产生海量的企业…...

自学软件测试从哪里开始?给还在迷茫的人一条出路
这两天和朋友谈到软件测试的发展,其实软件测试已经在不知不觉中发生了非常大的改变,前几年的软件测试行业还是一个风口,随着不断地转行人员以及毕业的大学生疯狂地涌入软件测试行业,目前软件测试行业“缺口”已经基本饱和。当然&a…...

配置MyBatis Plus 的分页查询功能
配置MyBatis Plus 的分页查询功能一. 回顾Mysql分页查询二. 配置MyBatis Plus 分页功能2.1 定义分页拦截器2.2 进行分页查询 selectPage()三. 开启MyBatis Plus的运行日志一. 回顾Mysql分页查询 limit 是MySQL当中特有的!其他数据库没有!不通用…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...

Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...