BroadcastReceiver

来源:互联网 发布:windows 安装程序 编辑:程序博客网 时间:2024/09/21 08:15

说到BroadcastReceiver,就得先提下Broadcast。


Broadcast

Android中的广播类型主要有两种:

  • Normal broadcasts标准广播):通过Context.sendBroadcast方法发送。是一种完全异步执行的广播。所有该广播的接收器都是无序运行的,在广播发出之后,几乎都会在同一时刻接收到这条广播消息。这种广播效率会比较高,但同时也意味着它是无法被截断的。

  • Ordered broadcasts有序广播):通过Context.sendOrderedBroadcast方法发送。是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递,并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播就无法收到广播消息了。


BroadcastReceiver简介

Android四大组件之一,本质上就是一个全局监听器,用于监听系统全局的广播消息。它可以非常方便地实现系统中不同组件之间的通信。

:这种监听器与各种OnXxxListener不同,OnXxxListener只是程序级别的监听器,这些监听器运行在指定程序所在进程中,当程序退出时,OnXxxListener监听器也就随之关闭了,但BroadcastReceiver属于系统级的监听器,它拥有自己的进程,只要存在与之匹配的Intent被广播出来,BroadcastReceiver就会被触发。


发送广播

BroadcastReceiver用于接受程序(包括用户开发的程序和系统内建的程序)所发出的Broadcast Intent,与应用程序启动Activity、Service相同的是,程序启动BroadcastReceiver也只需要两步:

1. 创建需要启动的BroadcastReceiver的Intent。

2. 调用Context的sendBroadcast()和sendOrderedBroadcast()方法来启动指定的BroadcastReceiver。


生命周期

一个BroadcastReceiver对象只有在被调用onReceive(Context, Intent)的才有效的,当从该函数返回后,该对象就无效了,结束生命周期。
因此,我们在在所调用的onReceive(Context, Intent)函数里,不能有过于耗时的操作,不能使用线程来执行。对于耗时的操作,请start service来完成。因为当得到其他异步操作所返回的结果时,BroadcastReceiver 可能已经无效了。

关于Service可见Service | CSDN.凌俊琦


接收广播

通过定义一个继承BroadcastReceiver的类来实现,继承该类后覆盖其onReceiver方法,并在该方法中响应事件。

public class MyReceiver extends BroadcastReceiver {      private static final String TAG = "MyReceiver";      @Override      public void onReceive(Context context, Intent intent) {          String msg = intent.getStringExtra("msg");          Log.i(TAG, msg);      }  }  

在onReceive方法内,我们可以获取随广播而来的Intent中的数据,这就像无线电一样,包含很多有用的信息。
在创建完我们的BroadcastReceiver之后,还不能够使它进入工作状态,我们需要为它注册一个指定的广播地址。没有注册广播地址的BroadcastReceiver就像一个缺少选台按钮的收音机,虽然功能俱备,但也无法收到电台的信号。


注册Receiver


静态注册

这种注册方式可以实现在程序未启动的情况下便能接收到广播,注册方式为在AndroidManifest.xmlapplication里定义receiver设置要接收的action

比如我们来实现一条开机广播。

首先新建一个类继承BroadcastReceiver:

public class BootCompleteReceiver extends BroadcastReceiver{    @Override    public void onReceive(Context context,Intent intent){        Toast.makeText(Context,"启动完毕",Toast.LENGTH_LONG).show();    }}

我们并没有使用内部类的方式来定义广播接收器,现在我们在AndroidManifest.xml文件里进行注册,找到application在按如下方式定义receiver:

<receiver android:name=".BootCompleteReceiver">    <intent-filter>        <action android:name="android.intent.action.BOOT_COMPLETED"/>    </intent-filter></receiver>

由于监听系统开机广播是需要权限的,所以我们需要加入

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

这样,一个可以监听系统开机的广播就完成了。


动态注册

动态注册也就是在代码中注册,它的优势在于非常灵活,可是它必须要在程序启动后才能收到广播。

public class Demo extends Activity {            private BroadcastReceiver receiver;            @Override         protected void onStart() {                 super.onStart();                 receiver = new CallReceiver();                 registerReceiver(receiver, new IntentFilter("android.intent.action.PHONE_STATE"));         }         @Override         protected void onStop() {                 unregisterReceiver(receiver);                 super.onStop();         } }

需要注意的是,一个receiver可以是接收多个action的,即可以有多个intent-filter,需要在onReceive里面对intent.getAction(action name)进行判断。

还有,在退出程序前要记得调用Context.unregisterReceiver()方法。一般在activity的onStart()里面进行注册, onStop()里面进行注销。

如果在Activity.onResume()里面注册了,就必须在Activity.onPause()注销。


小结

我们最好使用静态注册的方式来进行注册,由系统来管理receiver,而且程序里的所有receiver,可以在xml里面一目了然。而动态注册方式,隐藏在代码中,比较难发现。


附上几篇关于BroadcastReceiver的博文,供自己也供某个有缘看到此文章的人查看:

Android BroadcastReceiver 学习

基础总结篇之五:BroadcastReceiver应用详解


知识点参考自Android官方文档,《第一行代码》| 郭霖

0 0
原创粉丝点击