Android 中广播主要分为两类:标准广播和有序广播
1、标准广播(异步执行)
标准广播又分为动态注册和静态注册
动态注册:
首先定义一个广播接收器
class MyBroadCastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { //do something } }
接着
IntentFilter intentFilter; MyBroadCastReceiver myBroadCastReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); intentFilter = new IntentFilter("com.example.action");//"com.example.action"自定义的广播 myBroadCastReceiver = new MyBroadCastReceiver(); registerReceiver(myBroadCastReceiver,intentFilter); }
intentFilter为广播过滤器,只能接收"com.example.action"广播(广播可以是系统广播也可以是自定义的广播),同时通过registerReceiver注册广播接收器和过滤器。
接着,发送广播
Intent intent = new Intent(); intent.putExtra("temp","qh"); sendBroadcast(intent);
最后,动态注册广播需要在onDestroy()方法中主动去注销广播。
代码如下
@Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(myBroadCastReceiver); }
动态注册的广播接收器可以自由地控制注册和注销,非常灵活,但是因为注册逻辑是写在onCreate()方法中的,所以只能在程序启动后才能接收到广播,不能实现在程序未启动的情况下接收广播。
静态注册
静态注册则可以弥补动态注册的不足。
广播接收器实现和动态注册时一样的。
class MyBroadCastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { //do something } }
但是,实现静态注册的时候,我们的广播接收器需要设置为 独立外部类 或者是 静态内部类
这是因为:
系统从XML实例化只会实例化注册的类。当我们定义广播接收器为非静态内部类的时候,其需要依赖外部类的实例来实例化,而在XML中注册Receiver,并不能实例化其外部类,故要么使用静态内部类,要么直接使用独立外部类来实现接收器。
使用Android Studio提供的快捷方式来创建一个广播接收器,点击New--Other--Broadcast Receiver,弹出窗口,自定义Class Name,勾选Exported和Enabled属性,Finish完成创建。生成代码如下
<receiver android:name=".MyReceiver" android:enabled="true" android:exported="true"> </receiver>
但是这里还没有实现对任何广播的监听,这里做修改:
<receiver android:name=".MyReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/> </intent-filter> </receiver>
这样即可完成注册。
PS:<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>这里是任意选择的一个系统广播。
2、有序广播(同步执行)
同一时刻只有一个广播接收器能够接收到这个广播,只有这个广播接收器逻辑执行完毕后,广播才会继续传递,有先后顺序。优先级高的广播可以先接收到,并且可以截断正在传递的广播。
(1)发送有序广播只要修改一行代码
sendOrderedBroadcast(intent,null);
其中第二个参数是与权限相关的字符串。
(2)设置广播接收器的优先级:
<receiver android:name=".MyReceiver" android:enabled="true" android:exported="true"> <intent-filter android:priority="100"> <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/> </intent-filter> </receiver>
增加了 android:priority="100"一行代码,这里是将次广播优先级设置为100。
(3)是否允许广播继续传递:
abortBroadcast();
在广播接收器的onReceive中调用如上方法即可。
以上的发送和接收的广播都是全局广播,可以被任何应用程序接收到,也可以接收任何应用程序的广播,下面介绍本地广播,提高广播的安全性。
3、本地广播
LocalBroadcastManager localBroadcastManager;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); localBroadcastManager = LocalBroadcastManager.getInstance(this); intentFilter = new IntentFilter(""); myBroadCastReceiver = new MyBroadCastReceiver(); localBroadcastManager.registerReceiver(myBroadCastReceiver,intentFilter); }
发送本地广播:
Intent localIntent = new Intent(); intent.putExtra("temp","qh"); localBroadcastManager.sendBroadcast(localIntent); 注销广播: @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(myBroadCastReceiver); localBroadcastManager.unregisterReceiver(myBroadCastReceiver); }
class LocalBroadCastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { //do something } }
和动态注册基本类似。
发送本地广播比发送系统全局广播更高效。