什么是广播
- 广播是一个全局的监听器,属于Android四大组件之一,它分为两个角色:广播发送者、广播接收者
- 广播用于不同组件之间(应用内/不同应用之间),还有多线程之间的通信
- -
广播的分类及区别——无序广播和有序广播
- 广播分为无序广播和有序广播,这两种区别在于,无序广播发送的时候,几乎所有的广播接收器都能同时接收到这条广播,它们之间没有先后顺序,这种广播的效率比较高,但是一旦发出就无法截断。而有序广播则不同,在广播发出后,同一时间只会有一个广播接收器能够接收到这条广播,当这个接收器中的逻辑执行完毕后才会广播才会继续传递,所以这个时候的广播是有先后顺序的,优先级高的广播接收器会优先接收到广播并且可以截断广播或者更改广播内容
广播的注册方式及区别——静态注册和动态注册
- 注册广播的方式一般有两种,在
AndroidManifest.xml
中注册的称为静态注册,在代码中注册的称为动态注册 - 静态注册只需要在
AndroidManifest.xml
中添加<receiver>
标签,例如:
<receiver
//广播接收器名字
android:name=".MyBoradCast"
//是否启动广播
android:enabled="true"
//是否能够接收其他app发出的广播
android:exported="true">
<intent-filter>
<action android:name="com.example.mytest.MY_BROADCAST" />
</intent-filter>
</receiver>
- 动态注册广播我们就需要在代码中添加逻辑了,需要注意,对于动态广播,有注册就要有注销,否则会导致内存泄露
- 广播接收器
MyBoradCast myBoradCast;
myBoradCast = new MyBoradCast();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.mytest.MY_BROADCAST");
registerReceiver(myBoradCast,intentFilter);
unregisterReceiver(myBoradCast);
注册广播
- 创建2个广播接收器
MyBoradCast
与MyBoradCast2
public class MyBoradCast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.e( "onReceive: ", "MyBoradCast**********");
}
}
public class MyBoradCast2 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.e( "onReceive2: ", "MyBoradCast2**********");
}
}
静态注册无序广播
- 在
AndroidManifest.xml
中注册MyBoradCast
<receiver
//广播接收器名字
android:name=".MyBoradCast"
//是否启动广播
android:enabled="true"
//是否能够接收其他app发出的广播
android:exported="true">
<intent-filter>
<action android:name="com.example.mytest.MY_BROADCAST" />
</intent-filter>
</receiver>
Intent intent = new Intent("com.example.mytest.MY_BROADCAST");
sendBroadcast(intent);
静态注册有序广播
- 在
AndroidManifest.xml
中注册MyBoradCast
与MyBoradCast2
,不同的是在<intent-filter>
标签中添加android:process
优先级属性,优先级大的先接收广播,发送有序广播使用sendOrderedBroadcast
方法
<receiver
android:name=".MyBoradCast"
android:enabled="true"
android:exported="true">
<intent-filter android:process="9">
<action android:name="com.example.mytest.MY_BROADCAST" />
</intent-filter>
</receiver>
<receiver
android:name=".MyBoradCast2"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="10">
<action android:name="com.example.mytest.MY_BROADCAST" />
</intent-filter>
</receiver>
Intent intent = new Intent("com.example.mytest.MY_BROADCAST");
sendOrderedBroadcast(intent,null);
- 可以看到,由于
MyBoradCast2
的优先级比较大,所以先由MyBoradCast2
接收了广播
动态注册无序广播
- 在
onResume
方法中注册广播,在onPause
方法中注销广播,上面已经说到了
myBoradCast = new MyBoradCast();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.mytest.MY_BROADCAST");
registerReceiver(myBoradCast,intentFilter);
unregisterReceiver(myBoradCast);
动态注册有序广播
myBoradCast = new MyBoradCast();
IntentFilter intentFilter = new IntentFilter();
intentFilter.setPriority(1);
intentFilter.addAction("com.example.mytest.MY_BROADCAST");
registerReceiver(myBoradCast,intentFilter);
案例
- 我们可以在Activity中创建一个内部类广播 ,方便调用Activity的各种属性
class MyBroadcast extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Log.e("shopping: ","**********************" );
}
}
- 然后在Activity的
onResume
方法中注册
myBroadcast = new MyBroadcast();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.yang.paopao.shopping");
registerReceiver(myBroadcast,intentFilter);
unregisterReceiver(myBroadcast);
适配器中发送广播示例
- 在Adpater中发送广播,创建一个方法,在里面添加逻辑,Adpater中发送广播需要通过传入的对象调用
sendBroadcast
方法,当Activity接收到广播后执行相应的逻辑
private void broad(){
Intent intent = new Intent("com.example.yang.paopao.shopping");
context.sendBroadcast(intent);
}
Service中发送广播示例
- 在Service中发送广播与Activity中一样直接通过
sendBroadcast
发送
Intent intent1 = new Intent("com.example.yang.paopao.shopping");
sendBroadcast(intent1);
系统广播
- Android中内置了多个系统广播,只要涉及到手机的基本操作,如开机、网络状态变化等,都会发出相应的广播
- 常见的操作有
监听网络变化 android.net.conn.CONNECTIVITY_CHANGE
关闭或打开飞行模式 Intent.ACTION_AIRPLANE_MODE_CHANGED
系统启动完成后(仅广播一次) Intent.ACTION_BOOT_COMPLETED
重启设备 Intent.ACTION_REBOOT
屏幕被关闭 Intent.ACTION_SCREEN_OFF
屏幕被打开 Intent.ACTION_SCREEN_ON - 这几种都是我们常见的系统操作,系统广播是系统发送的,我们只是接收者
- 我们来看看监听网络变化广播的用法,首先在
AndroidManifest.xml
中添加权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
class NetworkChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo( );
if (networkInfo != null || networkInfo.isAvailable()){
Toast.makeText(context, "已连接网络", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, "没有网络", Toast.LENGTH_SHORT).show();
}
}
}
networkChangeReceiver = new NetworkChangeReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.com.CONNECTIVITY_CHANGE");
registerReceiver(networkChangeReceiver,intentFilter);
unregisterReceiver(networkChangeReceiver);
class ScreenStatusReceiver extends BroadcastReceiver {
String SCREEN_ON = "android.intent.action.SCREEN_ON";
String SCREEN_OFF = "android.intent.action.SCREEN_OFF";
@Override
public void onReceive(Context context, Intent intent) {
if (SCREEN_ON.equals(intent.getAction())) {
Log.e("onReceive: ", "屏幕唤醒");
}
else if (SCREEN_OFF.equals(intent.getAction())) {
Log.e("onReceive: ", "屏幕关闭");
}
}
}
screenStatusReceiver = new ScreenStatusReceiver()
IntentFilter intentFilter = new IntentFilter()
intentFilter.addAction(Intent.ACTION_SCREEN_ON)
intentFilter.addAction(Intent.ACTION_SCREEN_OFF)
registerReceiver(screenStatusReceiver, intentFilter)
unregisterReceiver(screenStatusReceiver);
- 运行程序
- 这里需要注意,注销广播不能像前面那样写在
onPause
中,否则关闭屏幕的时候Activity不可见就会执行onPause
然后注销广播