Broadcast
是应用程序之间传输信息,通过Intent传输数据,可以进行多进程通信,不同组件通信,不同App之间通信。那么广播主要分为:SendBroadcast(普通广播)、SendOrderedBroadcast(有序广播)、LocalBroadcast(只在自身App内传播):
- SendBroadcast:是一种异步执行的广播,接收者可以完全同一时刻受到消息,虽然效率高,但不可以截断。
- SendOrderedBroadcast:是一种同步执行的广播,接只有一个可以收到消息,优先级越高可以最先受到消息,收到后,下一个才可以接收到消息,可以截断。
- LocalBroadcast:只能在应用程序的内部进行传递的广播,广播接收器也只能接收内部的广播,不能接受其他应用程序的广播
首先要进行注册广播
注册有两种,为静态注册,动态注册:
- 1.静态注册在清单文件中写,但不够灵活,注册过后,无论Activity什么状态,一直会存活下去,收到消息。
- 在AndroidMainFest中的application标签下加上receiver的子标签
- 加入权限
- 与通过name属性指定注册一个广播类,也就是我们刚才定义的那个广播类,还有enabled与exported属性,enabled代表是否启用这个广播接收器,exported属性表示是否允许这个广播接收器接受本程序以外的广播(这两步可以通过Android Studio自动完成)
- 之后在receiver标签下加上intent-filter标签,设置其的action
<receiver android:name=".myreceiver" android:exported="true" android:enabled="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"> //开机完成后系统广播发出的一条值为android.intent.action.BOOT_COMPLETED的广播 </intent-filter> </receiver>
<uses-permission android:name"androir.permission.WRITE_c=CALENDAR"/>
- 2.动态注册是跟随Activity的生命周期存活,注意的是,需要在onDestory中unReceiver(),避免内存泄漏。
private myreceiver recevier;
private IntentFilter intentFilter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recevier = new myreceiver();
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
//当网络发生变化的时候,系统广播会发出值为android.net.conn.CONNECTIVITY_CHANGE这样的一条广播
registerReceiver(recevier,intentFilter);
}
机制:
1.首先创建广播类继承BroadcastReceiver.重写onReceiver()方法:
复制代码
public class myreceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//在这里写上相关的处理代码,一般来说,不要此添加过多的逻辑或者是进行任何的耗时操作
//因为广播接收器中是不允许开启多线程的,过久的操作就会出现报错
//因此广播接收器更多的是扮演一种打开程序其他组件的角色,比如创建一条状态栏通知,或者启动某个服务
}
}
- 2.通过Binder机制向AMS进行注册
- (1)那么Binder大概都了解,是进程通信的核心,可以使进程间隔离,虚拟地址空间、系统调用与binder驱动
- (2)性能高效,安全,协议进行身份验证
- (3)这里分享一篇大神博客:https://blog.csdn.net/freekiteyu/article/details/70082302
- (4)AMS 即ActivityManagerService 是贯穿四大组件核心服务,负责四大组件切换,启动,应用程序和管理调度
- 3.详细的接收广播的注册以及接收:
- (1)首先:broadcast通过binder 在AMS中注册
- (2)其次:广播发送者通过binder想AMS发送广播
- (3)接下来:AMS查找条件,符合否话在broad队列中拿到,进行接口回调。
- 4.下图为通过binder客户端和服务器之间进行通信的一个过程:
创建两个Service ,一张表,客户端通过Service1存到表中,Service2读取反馈给客户端。客户端进程持有服务端的代理模式,协助驱动完成跨境从通信。
下图为通过binder接收广播的注册以及接收的一个过程:
自定义广播:
- 1.标准广播:
Intent intent = new Intent();
intent.setAction("com.example.mymessage");
//Intent intent = new Intent("com,example.mymessage");
//也可以像注释这样写
sendBroadcast(intent);//发送标准广播
sendOrderedBroadcast(intent,null);//发送有序广播
//意思就是发送值为com.example.mymessage的这样一条广播
- 2.有序广播:
动态:
intentFilter.setPriority();
静态: 优先度的大小设置范围为-1000~1000
<intentFilter android:priority="100"/>
注册时候调用的是LocalBroadcastManager的registerReceiver方法,之前调用的是context的registerReceiver方法,两者参数就是相同的 .
注册:
- 3.本地广播:
private myreceiver recevier;
private IntentFilter intentFilter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recevier = new myreceiver();
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
//当网络发生变化的时候,系统广播会发出值为android.net.conn.CONNECTIVITY_CHANGE这样的一条广播
LocalBroadcastManager local=LocalBroadcastManager .getInstance(this);
local.recevierManager(recevier,intentFilter);
}
发送:
LocalBroadcastManager local=LocalBroadcastManager .getInstance(this);
Intent intent=new Intent("");
local.sendBroadcast(intent); //标准
local.sendBroadcastSync(intent);//有序
他有一个特点就是不必担心数据的泄漏,安全漏洞被利用。比较全局广播,本地广播更加高效。 那么为何高效?
- 1.我们看他的底层,是通过hanlder 实现的,他的sendBroadcast,是通过handler发送一个Message实现的
- 2.比Binder发送更加高效,隔离的方法无法接收到其他发来的广播
- 3.有2个map集合一个List集合接收广播对象。