美文网首页
BroadcastReceiver 详细解析

BroadcastReceiver 详细解析

作者: DreamFish | 来源:发表于2017-08-21 22:48 被阅读0次

    广播是一种广泛运用的在应用程序之间传输信息的机制,主要用来监听系统或者应用发出的广播信息,然后根据广播信息作为相应的逻辑处理,也可以用来传输少量、频率低的数据。

    在实现开机启动服务和网络状态改变、电量变化、短信和来电时通过接收系统的广播让应用程序作出相应的处理。

    BroadcastReceiver 自身并不实现图形用户界面,但是当它收到某个通知后, BroadcastReceiver 可以通过启动 Service 、启动 Activity 或是 NotificationMananger 提醒用户。

    使用广播的注意事项

    当系统或应用发出广播时,将会扫描系统中的所有广播接收者,通过 action 匹配将广播发送给相应的接收者,接收者收到广播后将会产生一个广播接收者的实例,执行其中的 onReceiver() 这个方法;特别需要注意的是这个实例的生命周期只有10秒,如果10秒内没执行结束 onReceiver() ,系统将会报错。在 onReceiver() 执行完毕之后,该实例将会被销毁,所以不要在 onReceiver() 中执行耗时操作,也不要在里面创建子线程处理业务(因为可能子线程没处理完,接收者就被回收了,那么子线程也会跟着被回收掉);正确的处理方法就是通过 intent 调用 Activity 或者 Service 处理业务。

    BroadcastReceiver的注册

    BroadcastReceiver 的注册方式有且只有两种,一种是静态注册(推荐使用),另外一种是动态注册,广播接收者在注册后就开始监听系统或者应用之间发送的广播消息。

    下面通过例子看一下两种注册方式,先定义一个接收短信的 BroadcastReceiver 类:

    public class MyBroadcastReceiver extends BroadcastReceiver {
        // action 名称
        String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED" ;
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals( SMS_RECEIVED )) {
                // 一个receiver可以接收多个action的,即可以有
                // 多个intent-filter,需要在 onReceive
                // 里面对 intent.getAction(action name) 进行判断。
                ...
            }
        }
    }
    
    • 静态注册

      在 AndroidManifest.xml 的 application 里面定义 receiver 并设置要接收的action。

      < receiver android:name = ".MyBroadcastReceiver" > 
          < intent-filter android:priority = "777" >       
              <action android:name = "android.provider.Telephony.SMS_RECEIVED" />
          </ intent-filter > 
      </ receiver >
      

      这里的 priority 取值是 -1000 到 1000 ,值越大优先级越高,同时注意加上系统接收短信的限权。

      静态注册的广播接收者是一个常驻在系统中的全局监听器,当你在应用中配置了一个静态的 BroadcastReceiver ,安装了应用后而无论应用是否处于运行状态,广播接收者都是已经常驻在系统中了。同时应用里的所有 receiver 都在清单文件里面,方便查看。要销毁掉静态注册的广播接收者,可以通过调用 PackageManager 将 Receiver 禁用。

    • 动态注册

      在 Activity 中声明 BroadcastReceiver 的扩展对象,在 onResume 中注册,onPause 中卸载.

      public class MainActivity extends Activity {
          MyBroadcastReceiver receiver;
      
          @Override
          protected void onResume() {
              // 动态注册广播 (代码执行到这才会开始监听广播消息,并对广播消息作为相应的处理)
              receiver = new MyBroadcastReceiver();
              IntentFilter intentFilter = new IntentFilter( "android.provider.Telephony.SMS_RECEIVED" );
              registerReceiver( receiver , intentFilter); 
              super.onResume();
          }
      
          @Override
          protected void onPause() { 
              // 撤销注册 (撤销注册后广播接收者将不会再监听系统的广播消息)
              unregisterReceiver(receiver);
              super.onPause();
          }
      }
      
    • 静态注册和动态注册的区别

      1. 静态注册的广播接收者一经安装就常驻在系统之中,不需要重新启动唤醒接收者;动态注册的广播接收者随着应用的生命周期,由 registerReceiver 开始监听,由 unregisterReceiver 撤销监听,如果应用退出后,没有撤销已经注册的接收者应用应用将会报错。

      2. 当广播接收者通过 intent 启动一个 activity 或者 service 时,如果 intent 中无法匹配到相应的组件。动态注册的广播接收者将会导致应用报错,而静态注册的广播接收者将不会有任何报错,因为自从应用安装完成后,广播接收者跟应用已经脱离了关系。

    发送广播主要类型

    • 普通广播

      普通广播是完全异步的,可以在同一时刻(逻辑上)被所有接收者接收到,所有满足条件的 BroadcastReceiver 都会随机地执行其 onReceive() 方法。

      同级别接收是先后是随机的;级别低的收到广播;消息传递的效率比较高,并且无法中断广播的传播。

      Intent intent = new Intent("android.provider.Telephony.SMS_RECEIVED"); 
      //通过intent传递少量数据
      intent.putExtra("data", "finch"); 
      // 发送普通广播
      sendBroadcast(Intent);
      
    • 有序广播

      有序广播通过 Context.sendOrderedBroadcast() 来发送,所有的广播接收器优先级依次执行,广播接收器的优先级通过 receiver 的 intent-filter 中的 android:priority 属性来设置,数值越大优先级越高。

      当广播接收器接收到广播后,可以使用 setResult() 函数来结果传给下一个广播接收器接收,然后通过 getResult() 函数来取得上个广播接收器接收返回的结果。

      当广播接收器接收到广播后,也可以用 abortBroadcast() 函数来让系统拦截下来该广播,并将该广播丢弃,使该广播不再传送到别的广播接收器接收。

    • 本地广播

      在 API21 的 Support v4 包中新增本地广播,也就是 LocalBroadcastManager 。由于之前的广播都是全局的,所有应用程序都可以接收到,这样就会带来安全隐患,所以我们使用 LocalBroadcastManager 只发送给自己应用内的信息广播,限制在进程内使用。

      它的用法很简单,只需要把调用 context 的 sendBroadcast、registerReceiver、unregisterReceiver 的地方换为 LocalBroadcastManager.getInstance(Context context)中对应的函数即可。

      这里创建广播的过程和普通广播是一样的过程,这里就不过多介绍了

    • 系统广播

      当然系统中也会有很多自带的广播,当符合一定条件时,系统会发送一些定义好的广播,比如:重启、充电、来电电话等等。我们可以通过action属性来监听我们的系统广播,创建广播的过程和普通广播是一样的过程,这里就不过多介绍了。

      常用的广播action属性有:

      • 屏幕被关闭之后的广播:Intent.ACTION_SCREEN_OFF

      • 屏幕被打开之后的广播:Intent.ACTION_SCREEN_ON

      • 充电状态,或者电池的电量发生变化:Intent.ACTION_BATTERY_CHANGED

      • 关闭或打开飞行模式时的广播:Intent.ACTION_AIRPLANE_MODE_CHANGED

      • 表示电池电量低:Intent.ACTION_BATTERY_LOW

      • 表示电池电量充足,即电池电量饱满时会发出广播:Intent.ACTION_BATTERY_OKAY

      • 按下照相时的拍照按键(硬件按键)时发出的广播:Intent.ACTION_CAMERA_BUTTON

      值得注意的是,随着系统版本的提升,很多系统广播已经不再被支持,如果你需要使用哪个系统广播,最好看看最新版本的支持情况。

    相关文章

      网友评论

          本文标题:BroadcastReceiver 详细解析

          本文链接:https://www.haomeiwen.com/subject/vltkdxtx.html