架构师学习--插件化之占位式静态注册广播(apk解析原理)

首先需要知道静态广播是在什么时候注册的?带着这个疑问就不得不分析apk的解析原理。

一、apk解析原理

1、静态广播注册

首先,手机在启动的时候,会把所有的apk的都安装一遍,然后立马就会解析所有apk的配置文件信息,如果配置文件中有广播,就会把它注册。

2、apk安装过程会产生3个目录
  1. data/app : apk的放置目录
  2. data/data/包名/ :应用所属目录,也就是数据库、sp等保存的目录
  3. data/dalvik-cache :虚拟机去加载执行指令

针对这三个目录,我们应该去分析那个目录呢?由于安装以后会全盘扫描apk,所以应该分析data/app目录。也就是说,当apk安装完成以后,立马就回去全盘扫描data/app 目录,解析xml配置文件。

3、如何解析

离不开PMS!!! PMS服务是什么时候启动的呢?

(1)PMS启动流程

大致流程如下:
当手机启动的时候,首先Linux内核启动,然后启动init进程,init进程启动以后,又会启动一个很重要的进程zygote进程,然后孵化SystemServer服务,SystemServer服务便会启动PMS服务、AMS服务等。

(2)PMS解析apk流程
9.0源码跟踪流程如下:
在这里插入图片描述
最终进入submit()方法
在这里插入图片描述
最后调用parsePackage()方法,将解析的结果保存在PackageParser.Package,在去看一下这个对象到底存了那些信息?

(3)PackageParser.Package

该类源码太长,只截取部分有用的代码,伪代码如下:

 public final static class Package implements Parcelable {
	......
        public final ArrayList<Permission> permissions = new ArrayList<Permission>(0);
        public final ArrayList<PermissionGroup> permissionGroups = new ArrayList<PermissionGroup>(0);
        public final ArrayList<Activity> activities = new ArrayList<Activity>(0);
        public final ArrayList<Activity> receivers = new ArrayList<Activity>(0);
        public final ArrayList<Provider> providers = new ArrayList<Provider>(0);
        public final ArrayList<Service> services = new ArrayList<Service>(0);
        public final ArrayList<Instrumentation> instrumentation = new ArrayList<Instrumentation>(0);
	......
}

看到这里,应该注意到系统会将解析到权限信息,activity信息,广播信息等等保存到集合中,我们这里只关注广播信息receivers 。它的类型是Activity,注意这里的Activity并不是四大组件中的Activity,而是一个内部类,主要代码如下:

public final static class Activity extends Component<ActivityIntentInfo> implements Parcelable {
        public final ActivityInfo info;
        ....
 }

类里面有个局部变量ActivityInfo ,它其实里面存放了类的名称,比如com.xxx.xxx.MyReCeiver,这点很重要。
既然拿到广播的类名称,那么intentFilter从哪里来呢?注意Activity是继承Component的,Component代码如下:

public static abstract class Component<II extends IntentInfo> {
        public final ArrayList<II> intents;
        .....
}

public static abstract class IntentInfo extends IntentFilter {
	.....
}

没错Component的局部变量intents就存放了所有的intentFilter信息。

(4)实现

拿到了静态广播的类名和intentFilter信息,就可以进行在宿主中注册了。

二、代码实现

1、拿到Package对象

在这里插入图片描述

2、拿到receivers对象

在这里插入图片描述

3、遍历receivers,过程中拿到每一个receiver的广播名称

通过ActivityInfo来拿
在这里插入图片描述

4、遍历receivers,过程中拿到每一个receiver的intentFilter在这里插入图片描述
5、遍历receivers,注册每一个receiver

在这里插入图片描述
完成以上代码,就实现了插件中静态广播的注册。

完整代码:

插件化代码传送门

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值