《第一行代码》笔记之 Broadcast

Broadcast

本篇内容整理自郭霖的 《第一行代码》

广播机制介绍

  • Android 系统广播更加灵活
    • 应用对喜欢的广播注册,只接收想要的内容
    • 广播来自系统其他应用

发送广播需要借助Intent
接收广播需要广播接收器(Broadcast Receiver)

  • 广播是一种跨进程的通信方式,因此这个应用发出广播,其他应用也可以收到

  • 广播类型:标准广播、有序广播


标准广播(Normal broadcasts)

  • 完全异步执行的广播(广播发出后,所有广播接收器同时收到广播消息),效率较高
  • 无序
  • 无法截断

这里写图片描述


有序广播(Ordered broadcasts)

  • 同步执行的广播(同一时刻只会有一个广播接收器 能接收到这条广播消息
  • 广播接收器逻辑执行完毕才会继续传递广播
  • 有序
  • 可以截断

这里写图片描述

接收系统的广播

  • Android 内置了很多系统级别的广播:

  • 手机开机会发出一条广播

  • 电池电量发生变化会发出一条广播

  • 时间或者时区发生改变会发出一条广播

  • 广播接收器注册广播,就可以接收该广播,并在内部处理相应的逻辑

  • 在代码中注册:动态注册

  • 在 AndroidManifest.xml 中注册:静态注册


动态注册 —— 监听网络变化

  1. 新建个类继承 BroadcastReceiver
  2. 重写父类的 onReceive() 方法:接收广播后的逻辑处理在此方法中

监听网络变化例子

public class MainActivity extends Activity{
	
	private IntentFilter intentFilter;
	
	private NetworkChangeReceiver networkChangeReceiver;

	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		intentFilter = new IntentFilter();
		intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
		//网络状态发生变化,系统发出的就是这一条值为 android.net.conn.CONNECTIVITY_CHANGE 的广播

//(3)实例化广播接收器
		networkChangeReceiver = new NetworkChangeReceiver();

//(4)对广播进行注册。两个参数,第一:广播接收器	第二:要注册的广播		
		registerReceiver(networkChangeReceiver, intentFilter);
	}

	protected void onDestroy(){
		super.onDestroy();

//(5)动态注册的广播接收器一定要取消注册
		unregisterReceiver(networkChangeReceiver);
	}
	
// (1)新建一个内部类(广播接收器)继承 BroadcastReceiver
	class NetworkChangeReceiver extends BroadcastReceiver{
	
// (2)重写父类的 onReceive() 方法
		public void onReceive(Context context, Intent intent){
			// 接收到广播后具体的业务处理
			ConnectiviyManager connectionManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();
			if(networkInfo != null && networkInfo.isAvailable()){
				Toast.makeText(context, "network is available", Toast.LENGTH_SHORT).show();
			}else{
				Toast.makeText(context, "network is unavailable", Toast.LENGTH_SHORT).show();
			// 查询系统的网络状态需要在配置文件中声明权限 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE />"
			}
		}
	}
}

静态注册 —— 开机启动

  • 可以使应用程序未启动的状态下接收广播

开机启动例子:

// (1)新建一个 BootCompleteReceiver(不是内部类) 继承自 BroadcastReceiver
public class BootCompleteReceiver extends BroadcastReceiver{
	
	public void onReceiver(Context context, Intent intent){
		// 接收到广播后具体的业务处理
	}
}

(2)在 AndroidManifest 中注册广播

....
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <-- 监听系统开机是需要权限 -->
<application
.....
>
<receiver android:name=".BootCompleteReceiver"> <-- 指定具体的广播接收器 -->

	<intent-filter>
		<action android:name="android.intent.action.BOOT_COMPLETED" /> <-- 指定想要接收的广播 -->
	</intent-filter>
	
</receiver>
</application>

onReceive()方法不能开启线程,无法进行耗时操作。长时间运行程序会报错(广播接收器更多用处是打开程序其他组件。创建一条状态栏通知,启动服务之类

发送自定义广播


发送标准广播

超级简单

public void onClick(){
	Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
	sendBroadcast(intent);
	//点击事件发送了一条值为 com.example.broadcasttest.MY_BROADCAST 的广播
}

发送有序广播

同样超级简单

  • 发送有序广播
public void onClick(){
	Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
	sendOrderedBroadcast(intent, null);// 将 sendBroadcast 改为 sendOrderedBroadcast 即可发送有序广播
	
	// sendOrderedBroadcast() 接收两个参数,第一:Intent 第二:与权限相关的字符
}
  • 设置有序广播接收器优先级

只需在 AndroidManifest 中设置优先级

<receiver ....>
	<intent-filter android:priority="99"> <--设置广播接收器优先级为99-->
	<action ... />
	</intent-filter>
</receiver>
  • 广播接收器阻断有序广播
public void onReceive(Context context, Intent intent){
	// 接收到广播后具体的业务处理
	
	abortBroadcast(); // 阻断广播
}

使用本地广播

  • 本地广播:广播只在本应用中传播,其他应用接收不到。无法使用静态注册

使用 LocalBroadcastManager 来对广播进行管理,并提供了发送广播和注册广播接收器的方法

private LocalReceiver localReceiver;

private LocalBroadcastManager localBroadcastManager;

protected void onCreate(...){
....

localBroadcastManager = LocalBroadcastManager.getInstance(this); // 获取 LocalBroadcastManager 实例

intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();

localBroadcastManager.registerReceiver(localReceiver, intentFilter);// 注册广播
}
public void onClick(){
	Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
	localBroadcastManager.sendBroadcast(intent); //发送本地广播
 }
public void onDestroy(){
	localBroadcastManager.unregisterReceiver(localReceiver);
}

class LocalReceiver extends BroadcastReceiver{
	public void onReceive(Context context, Intent intent){
		// 接收到广播后具体的业务处理
	}
}

本地广播的优点:

  1. 广播不会发送到其他程序,不用担心数据泄漏问题
  2. 其他广播不会发送到程序内部,不会有安全漏洞
  3. 更加高效
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值