广播从注册方式上可以分为静态广播和动态广播。他们的区别如下:
- 静态注册的广播,需要在manifest文件中声明,这样,在应用的apk包安装时或者Android系统重启时,
PMS(PackageManagerService)就会解析apk的manifest文件,并将这些信息保存起来,所以,静态注册的
广播是保存在PMS中的。 - 动态注册的广播是通过代码在程序中注册的,通过调用Context类的registerReceiver方法,在经过一系列的
调用最终调用AMS(ActivityManagerService)的registerReceiver方法,AMS的registerReceiver方法内部将
动态注册的广播进行保存。所以,动态注册的广播是保存在AMS中的。 - 静态注册的广播,app未启动也是可以收到广播的,但是动态注册的广播,如果未执行注册的代码,是无法收到广播的。
鉴于静态注册的广播和动态注册的广播存储的地方不同,并且,接收特性的不同,对于插件广播的处理,要分两种方式,一种是针对静态广播的处理,一种是动态广播的处理。当然也可以只使用一种处理方式,即将插件中静态广播在宿主中转换成动态注册的广播,这样,就可以统一使用一种方式处理插件中的广播,即只需要处理动态注册的广播的方式处理插件中的所有广播。奔跑文章很多前提的代码都是基于Android 插件化之——启动和停止插件Service
下面先来演示如何给插件中动态注册的广播接收者发送广播,让插件中的广播接收者的onReceive方法能够执行。
- 首先编写一个插件广播接收者
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import test.cn.example.com.util.LogUtil;
public class PlugReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
LogUtil.i("插件receiver ");
}
}
-
让插件广播接收者注册在插件Service的onCreate方法中进行注册。(插件Service的生成,请看Android 插件化之——启动和停止插件Service )
-
编译项目,将这两个类生成的class文件和相关的class文件,复制到按照包名新建的文件夹目录下,然后,使用dx
工具将这些class文件打包成dex文件,然后将打包好的dex文件复制到手机的sd卡根目录下。具体操作步骤,可以参考Android 插件化之——启动和停止插件Service启动插件Servcie这篇文章中的dex文件的生成过程。 -
启动插件Service,这样,插件的广播接收者就可以进行动态注册了。关于如何启动插件Service,
可以参考Android 插件化之——启动和停止插件Service -
在宿主中给插件广播接收者发送广播
Intent receiver = new Intent("test.plugreceiver");
sendBroadcast(receiver);
打印日志信息如下:
10-22 : ProxyService.java::27::onCreate-->>代理servcie onCreate
10-22 : ProxyService.java::33::onStartCommand-->>代理servcie onStartCommand startId=1
10-22 : ProxyService.java::38::onStartCommand-->>test.cn.example.com.androidskill.hook.service.PlugService
10-22 : PlugService.java::25::onCreate-->>插件servcie onCreate
10-22 : PlugService.java::43::onStartCommand-->>插件servcie onStartCommand
10-22 : PlugReceiver.java::12::onReceive-->>插件receiver