Broadcast(广播) 是 Android 的四大组件之一,用于进程/线程间通讯。java
广播最大的特色就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的,它只负责「说」而无论你「听不听」。android
广播能够来之系统,例如,Android 系统在发生各类系统事件时发送广播(系统启动或者设备开始充电时)。git
也能够来自于其余应用程序,例如,应用程序也能够发送自定义广播,来通知其余应用程序接受他们可能感兴趣的内容(更新数据)。github
是一种「彻底异步执行」的广播,没有任何前后顺序,全部的广播接收器几乎同一时刻接收到这条广播消息,效率高,没法被截断。安全
是一种「同步执行」的广播,有前后顺序,同一时刻只有一个接收器能够接收这个广播消息,优先级高的广播接收器能够先收到广播消息,而且前面的广播接收器还能够截断正在传递的广播,这样后面的广播接收器就没法接收广播消息了。网络
无论应用程序是否处于活动状态,都会进行监听。每次触发都会创建新的 Receiver 对象。app
在代码中进行注册,注意动态注册的广播必定要取消注册才行,一般是在 onDestroy()
方法中调用 unregisterReceiver()
方法来实现。异步
从开始建立直到其被解除注册会使用同一个 Receiver,不管这个广播被触发几回。ide
Android 系统中内置了多个系统广播,每一个系统广播都具备特定的 IntentFilter,其中主要包括具体的 Action,系统广播发出后,将被相应的 BroadcastReceiver 接收。系统广播在系统内部当特定事件发生时,由系统自动发出。学习
由应用程序开发者本身定义的广播。
发出的广播能够被其余任意的应用程序接收,或者能够接收来自其余任意应用程序的广播。
只能在应用程序的内部进行传递的广播,广播接收器也只能接收内部的广播,不能接受其余应用程序的广播。
使用广播咱们须要先建立 BroadcastReceiver(广播接收器) ,直接继承 BroadcastReceiver 建立子类并实现父类的 onReceive()
方法便可,以下示例代码。
public class MyReceiver extends BroadcastReceiver {
// 自定义 action
private static final String ACTION = "com.jeanboy.broadcast.MyReceiverFilter";
@Override
public void onReceive(Context context, Intent intent) {
//TODO: 接收到广播进行处理
}
}
复制代码
在使用广播时还须要在 AndroidMainfest 文件中定义,也就是注册静态广播。
<receiver android:name=".ui.broadcast.MyReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<!-- 例如:接收系统开机广播 -->
<action android:name="android.intent.action.BOOT_COMPLETED" />
<!-- 例如:接收自定义的广播 -->
<action android:name="com.jeanboy.broadcast.MyReceiverFilter" />
</intent-filter>
</receiver>
复制代码
上面的 enabled 设置为 true 意味着可以接受到广播信息。exported 为 true 意味着可以接收到外部 APK 发送的广播信息。
使用动态广播不须要在 AndroidMainfest 文件中定义,只需在代码中注册便可。
// 建立广播
MyReceiver myReceiver = new MyReceiver();
// 建立 IntentFilter
IntentFilter intentFilter = new IntentFilter();
// 例如:添加系统广播 action 接受网络变化
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
// 例如:添加自定义的 action
intentFilter.addAction(MyReceiver.ACTION);
// 注册广播
registerReceiver(myReceiver, intentFilter);
// 注销广播
unregisterReceiver(myReceiver);
复制代码
发送广播比较简单,不管静态广播仍是动态广播,都是以下方式(系统广播 Android 系统会自动发送,不在本文讨论范围)。
// 建立 Intent
Intent intent = new Intent();
// 例如:添加自定义的 action
intent.setAction(MyReceiver.ACTION);
// 发送广播
sendBroadcast(intent);
复制代码
因为 Android 8.0 废除大部分静态广播,对于代码须要修改某些部分。
发送广播部分须要设置 ComponetName
。
Intent intent = new Intent(MyReceiver.ACTION);
// ComponetName("自定义广播的包名", "自定义广播的路径")
ComponentName component = new ComponentName("com.jeanboy.app.broadcast", "com.jeanboy.app.broadcast.MyReceiver");
intent.setComponent(component);
sendBroadcast(intent);
复制代码
使用广播可能引起的安全问题:
为了不以上安全问题,Android 为咱们提供了权限机制。
首先在注册静态广播时能够在 AndroidMainfest 文件中添加权限。
<manifest ...>
<!-- 自定义一个本身的权限 -->
<permission android:name="com.jeanboy.permissions.MY_BROADCAST"/>
<!-- 使用自定义的权限 -->
<uses-permission android:name="com.jeanboy.permissions.MY_BROADCAST"/>
<application ...>
<!-- 添加权限 -->
<receiver android:name=".ui.broadcast.MyReceiver" android:permission="com.jeanboy.broadcast.MY_BROADCAST" android:enabled="true" android:exported="true">
<intent-filter>
<!-- 例如:接收自定义的广播 -->
<action android:name="com.jeanboy.broadcast.MyReceiverFilter" />
</intent-filter>
</receiver>
</application>
</manifest>
复制代码
而后在咱们发送广播时,能够为它指定一个权限,只有具备该权限的应用才能接收到广播,以下所示:
// 建立 Intent
Intent intent = new Intent();
// 例如:添加自定义的 action
intent.setAction(MyReceiver.ACTION);
// 发送广播,添加权限
sendBroadcast(intent, "com.jeanboy.permissions.MY_BROADCAST");
复制代码
上面介绍的 BroadcastReceiver 用于应用之间的传递消息,本质上它是跨进程的,还有可能被其余应用拦截。
而 LocalBroadcast(本地广播)用于应用内部传递消息,比 BroadcastReceiver 更加高效,它只在应用内部有效,不须要考虑安全问题。
本地广播的建立仍然是继承 BroadcastReceiver 建立子类,并实现父类的 onReceive()
方法。在注册、发送、注销广播时使用 LocalBroadcastManager 来进行相关操做。
// 建立广播
MyReceiver myReceiver = new MyReceiver();
// 建立 IntentFilter
IntentFilter intentFilter = new IntentFilter();
// 例如:添加自定义的 action
intentFilter.addAction(MyReceiver.ACTION);
// 注册本地广播
LocalBroadcastManager.getInstance(this)
.registerReceiver(myReceiver, intentFilter);
// 发送广播
Intent intent = new Intent(MyReceiver.ACTION));
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
// 注销本地广播
LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);
复制代码
欢迎关注个人公众号,分享各类技术干货,各类学习资料,职业发展和行业动态。
欢迎加入技术交流群,来一块儿交流学习。