2023年3月24日(软件工程日报)

App在运行的时候有各种各样的数据流转,有的数据从上一个页面流向下一个页面,此时可通过意图在
活动之间传递包裹;有的数据从应用内存流向存储卡,此时可进行文件读写操作。还有的数据流向千奇
百怪,比如活动页面向碎片传递数据,
随着App工程的代码量日益增长,承载数据流通的管道会越发不够用,好比装修房子的时候,给每个房
间都预留了网线插口,只有插上网线才能上网。可是现在联网设备越来越多,除了电脑之外,电视也要
联网,平板也要联网,乃至空调都要联网,如此一来网口早就不够用了。那怎样解决众多设备的联网问
题呢?原来家家户户都配了无线路由器,路由器向四周发射WiFi信号,各设备只要安装了无线网卡,就
能接收WiFi信号从而连接上网。于是“发射器+接收器”的模式另辟蹊径,比起网线这种固定管道要灵活得
多,无须拉线即可随时随地传输数据。
Android的广播机制正是借鉴了WiFi的通信原理,不必搭建专门的通路,就能在发送方与接收方之间建
立连接。同时广播(Broadcast)也是Android的四大组件之一,它用于Android各组件之间的灵活通
信,与活动的区别在于:
1)活动只能一对一通信;而广播可以一对多,一人发送广播,多人接收处理。
2)对于发送方来说,广播不需要考虑接收方有没有在工作,接收方在工作就接收广播,不在工作就丢
弃广播。
3)对于接收方来说,因为可能会收到各式各样的广播,所以接收方要自行过滤符合条件的广播,之后
再解包处理。
与广播有关的方法主要有以下3个。
sendBroadcast:发送广播。
registerReceiver:注册广播的接收器,可在onStart或onResume方法中注册接收器。
unregisterReceiver:注销广播的接收器,可在onStop或onPause方法中注销接收器。
具体到编码实现上,广播的收发过程可分为3个步骤:发送标准广播、定义广播接收器、开关广播接收
器,分别说明如下。1.发送标准广播
广播的发送操作很简单,一共只有两步:先创建意图对象,再调用sendBroadcast方法发送广播即可。
不过要注意,意图对象需要指定广播的动作名称,如同每个路由器都得给自己的WiFi起个名称一般,这
样接收方才能根据动作名称判断来的是李逵而不是李鬼。下面是通过点击按钮发送广播的活动页面代
码:
public class BroadStandardActivity extends AppCompatActivity implements
View.OnClickListener {
private final static String TAG = "BroadStandardActivity";
// 这是广播的动作名称,发送广播和接收广播都以它作为接头暗号
private final static String STANDARD_ACTION =
"com.example.chapter09.standard";
private TextView tv_standard; // 声明一个文本视图对象
private String mDesc = "这里查看标准广播的收听信息";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broad_standard);
tv_standard = findViewById(R.id.tv_standard);
tv_standard.setText(mDesc);
findViewById(R.id.btn_send_standard).setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_send_standard) {
Intent intent = new Intent(STANDARD_ACTION); // 创建指定动作的意图
sendBroadcast(intent); // 发送标准广播
}
}
}
2.定义广播接收器
广播发出来之后,还得有设备去接收广播,也就是需要广播接收器。接收器主要规定两个事情,一个是
接收什么样的广播,另一个是收到广播以后要做什么。由于接收器的处理逻辑大同小异,因此Android
提供了抽象之后的接收器基类BroadcastReceiver,开发者自定义的接收器都从BroadcastReceiver派生
而来。新定义的接收器需要重写onReceive方法,方法内部先判断当前广播是否符合待接收的广播名
称,校验通过再开展后续的业务逻辑。
private class StandardReceiver extends BroadcastReceiver {
// 一旦接收到标准广播,马上触发接收器的onReceive方法
@Override
public void onReceive(Context context, Intent intent) {
// 广播意图非空,且接头暗号正确
if (intent != null && intent.getAction().equals(STANDARD_ACTION)) {
mDesc = String.format("%s\n%s 收到一个标准广播", mDesc,
DateUtil.getNowTime());
tv_standard.setText(mDesc);
}
}
}
3.开关广播接收器
为了避免资源浪费,还要求合理使用接收器。就像WiFi上网,需要上网时才打开WiFi,不需要上网时就
关闭WiFi。广播接收器也是如此,活动页面启动之后才注册接收器,活动页面停止之际就注销接收器。
在注册接收器的时候,允许事先指定只接收某种类型的广播,即通过意图过滤器挑选动作名称一致的广
播。接收器的注册与注销代码示例如下:
private StandardReceiver standardReceiver; // 声明一个标准广播的接收器实例
@Override
protected void onStart() {
super.onStart();
standardReceiver = new StandardReceiver(); // 创建一个标准广播的接收器
// 创建一个意图过滤器,只处理STANDARD_ACTION的广播
IntentFilter filter = new IntentFilter(STANDARD_ACTION);
registerReceiver(standardReceiver, filter); // 注册接收器,注册之后才能正常接收广播
}
@Override
protected void onStop() {
super.onStop();
unregisterReceiver(standardReceiver); // 注销接收器,注销之后就不再接收广播
}
完成上述3个步骤后,便构建了广播从发送到接收的完整流程。运行测试App,初始的广播界面如图9-1
所示,点击发送按钮触发广播,界面下方立刻刷新广播日志,如图9-2所示,可见接收器正确收到广播并
成功打印日志
posted @ 2023-03-24 22:55  摆烂达人  阅读(11)  评论(0编辑  收藏  举报