【Android 笔记】BroadcastReceiver

Author Avatar
vecrates 12月 14, 2017

 BroadcastReceiver 是用于接收系统或其他应用程序广播的组件,广播实际上是 Intent,Intent 中可以携带一些数据发送来实现进程间通信,不过也需要对方注册广播接收器。

分类

  • 普通广播
     sendBroadcast(),异步发送广播,同时向所有 BroadcastReceiver 发送广播,但它们未必同时接收到
  • 有序广播
     sendOrderBroadcast(),同步发送广播,BroadcastReceiver 优先级高的会先接收到广播(同级随机),优先级高的可以修改数据然后传给优先级低的接收器,也可以拦截广播

BroadcastReceiver 定义

 定义 BroadcastReceiver 只需继承 BroadcastReceiver 类,重写 onReceive() 方法即可,onReceive() 方法不能做耗时的操作,超过10s就会 ANR

BroadcastReceiver 注册

有两种注册方式,在 Manifest.xml 或 Java 代码中注册,在 xml 注册的广播在系统启动时就会启动广播,而在 Java 中注册的广播在执行注册方法的时候才会启动

  • 静态 注册(Manifest.xml)
    <receiver
          android:name=".MyReceiver">
          <intent-filter android:priority="99">
              <action android:name="cn.vecrates.STATIC"/>
          </intent-filter>
    </receiver>
    
      用于权限过滤
  • 动态注册(代码)

      private MySecondReceiver mSecondReceiver;
    
      IntentFilter intentFilter = new IntentFilter();
      intentFilter.addAction(ACTION_SEND_DYNOMIC);
      registerReceiver(mSecondReceiver, intentFilter);
    
      unregisterReceiver(mSecondReceiver);  //取消注册
    

发送广播

发送广播的方法和 activity、service 类似,调用 Context.sendBroadcast() 或 Context.sendOrderBroadcast() 发送 Intent,然后在 onReceive() 中接收 Intent 即可
普通广播

        Intent intent = new Intent(this, MySecondReceiver.class);
        intent1.setAction(ACTION_SEND_DYNOMIC);
        intent1.putExtra("msg", "普通广播");
        sendBroadcast(intent);

有序广播
发送有序广播需要在设置广播的优先级,优先级高的广播会先接收到广播(同级随机),在 中使用 android:priority属性设置,取值范围为[-1000,1000],数值越大优先级越高

        <receiver android:name=".MyFirstReceiver">
            <intent-filter android:priority="100">
                <action android:name="cn.vecrates.STATIC"/>
            </intent-filter>
        </receiver>

        <receiver
            android:name=".MyThirdReceiver">
            <intent-filter android:priority="99">
                <action android:name="cn.vecrates.STATIC"/>
            </intent-filter>
        </receiver>

发送

        Intent intent = new Intent();
        intent.setAction(ACTION_SEND_STATIC);
        intent.putExtra("msg", "有序广播");
        sendOrderedBroadcast(intent, null);

优先级高的接收器将率先收到广播,此时接收器可以对接收器修改或者阻停广播,阻停广播后比它优先级低的广播将接收不到广播

    //超过10s ANR
    @Override
    public void onReceive(Context context, Intent intent) {
        String msg = intent.getStringExtra("msg");
        Log.v("_v", "MyFirstReceiver " + msg);

        abortBroadcast(); //阻止有序广播

        //添加数据发送给优先级低的广播
        Bundle bundle = new Bundle();
        bundle.putString("msg", "这是优先级高的广播存放的消息");
        setResultExtras(bundle);
    }

特殊的广播

本地广播

即发送的广播只能在本应用内传播,本地广播不能在 xml 文件中注册,因为 manifest.xml 中的广播在系统启动时就启动了,失去了本地的含义

        LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getBaseContext());
        manager.registerReceiver(mSecondReceiver, intentFilter); //注册广播
        manager.sendBroadcastSync(intent); //发送同步广播
        manager.sendBroadcast(intent); //发送异步广播
        manager.unregisterReceiver(mSecondReceiver); //取消注册
粘性广播

  BroadcastReceiver 注册前如果有广播发送了,那么注册之后接受器依然能接受到最后一条广播

  • 粘性普通广播
  • 粘性有序广播