8.1 BroadcastReceiver 广播使用

1.概述

广播是Android四大组件之一,监听 / 接收 应用 App 发出的广播消息,并做出响应。
可以在Android不同组件间的通信(含 :应用内 / 不同应用之间)或多线程通信 或 Android 系统在特定情况下的通信。
一个完整的广播流程:

  • 1.注册广播
  • 2.创建广播接收器
  • 3.发送广播
  • 4.取消注册

广播从注册方式上分为两种形式,一种是静态注册,一种是动态注册。

2.静态注册

静态注册,就是在清单文件里注册广播

        <receiver
            android:name=".MyReceiver"
            android:enabled="true">
            <intent-filter>
                <action android:name="com.example.test_broadcast" />
            </intent-filter>
        </receiver>

广播接收器 接收到事件去处理逻辑

public class MyReceiver extends BroadcastReceiver {

    private static final String TAG = "MyReceiver";
    //接收事件的方法
    @Override
    public void onReceive(Context context, Intent intent) {


        Log.d(TAG, "onReceive: "+intent.getStringExtra("msg"));
    }
}

      Intent intent = new Intent("com.example.test_broadcast");
      intent.putExtra("msg", "我是广播数据!");
      sendBroadcast(intent);

注意:静态广播没有取消注册,因为它在清单文件里注册,它是常驻形式的。

3.动态注册

动态注册意思就是在代码里注册,所以动态注册需要取消注册,一般都是界面销毁的时候。

   /**
     * 动态注册广播
     */
    private void initRegister() {

        DynamicBroadcastReceiver dynamicBroadcastReceiver = new DynamicBroadcastReceiver();

        // intent过滤器 且添加action
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("I am DynamicBroadcastReceiver");

        registerReceiver(dynamicBroadcastReceiver, intentFilter);

    }
/**
* 动态注册广播,要使用代码注册,不能在清单文件里注册
 */
public class DynamicBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = "DynamicBroadcastReceive";
    @Override
    public void onReceive(Context context, Intent intent) {

        Log.d(TAG, "onReceive: "+intent.getStringExtra("msg"));
    }
}

发送广播

   Intent dynamicIntent = new Intent();
   dynamicIntent.setAction("I am DynamicBroadcastReceiver");
   dynamicIntent.putExtra("msg", "我是动态的广播");
    sendBroadcast(dynamicIntent);

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

        unregisterReceiver(dynamicBroadcastReceiver);
    }

3.1静态和动态注册的区别

  1. 静态注册是常驻型,在清单文件里注册。不受组件生命周期的影响。也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。
  2. 动态注册广播不是常驻型广播,动态广播比静态广播优先级高。灵活,跟随组件的生命周期变化。也就是说广播跟随activity的生命周期。注意: 在activity结束前,取消注册。

4.本地广播

普通的Android中的广播可以跨App直接通信(exported对于有intent-filter情况下默认值为true)

  • 可能出现的问题:
    其他App针对性发出与当前App intent-filter相匹配的广播,由此导致当前App不断接收广播并处理;
    其他App注册与当前App一致的intent-filter用于接收广播,获取广播具体信息;即会出现安全性 & 效率性的问题。

  • 解决方案
    使用App应用内广播(Local Broadcast),也叫本地广播。

  • 区别:

    1.App应用内广播可理解为一种局部广播,广播的发送者和接收者都同属于一个App。
    2.相比于全局广播(普通广播),App应用内广播优势体现在:安全性高 & 效率高

1.创建本地广播接收器

  BroadcastReceiver localBroadCast = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            Log.d(TAG, "onReceive: "+intent.getStringExtra("hh"));
        }
    };


2.注册本地广播

 IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("xx.yy.zz");

        LocalBroadcastManager.getInstance(this).registerReceiver(localBroadCast,intentFilter);


3、取消注册本地广播

LocalBroadcastManager.getInstance(this).unregisterReceiver(localBroadCast);

4、发送本地广播

  	Intent intent = new Intent();
    intent.putExtra("hh","hello");
    intent.setAction("xx.yy.zz");
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

5.系统广播

系统广播就是系统已经预制了很多和系统有关得广播。如关闭屏幕,打开屏幕,电量变化。

5.1每个广播都有特定的Intent - Filter(包括具体的action)

在这里插入图片描述

5.2 只能动态注册的广播:

    android.intent.action.SCREEN_ON//屏幕打开
    android.intent.action.SCREEN_OFF//屏幕关闭
    android.intent.action.BATTERY_CHANGED//电量变化
    android.intent.action.CONFIGURATION_CHANGED//设备的配置信息已经改变
    android.intent.action.TIME_TICK//时间相关的广播
       android.net.conn.CONNECTIVITY_CHANGE//网络状态发生改变,Android7.0之后只能动态注册

6.有序广播

发送出去的广播被多个广播接收者按照先后顺序接收,有序是针对广播接收者而言的。
广播接受者接收广播的顺序规则(同时面向静态和动态注册的广播接受者)
按照Priority属性值从大-小排序;数值越大,优先获取信息。
Priority属性相同者,动态注册的广播优先;

特点
接收广播按顺序接收
先接收的广播接收者可以对广播进行截断,即后接收的广播接收者不再接收到此广播;
先接收的广播接收者可以对广播进行修改,那么后接收的广播接收者将接收到被修改后的广播

发送有序广播

sendOrderedBroadcast(intent);
  private void register() {

        one = new OneReceiver();
        IntentFilter intentFilter2 = new IntentFilter();
        intentFilter2.setPriority(0);
        intentFilter2.addAction("com");
        registerReceiver(one, intentFilter2);

        two = new TwoReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.setPriority(1000);
        intentFilter.addAction("com");
        registerReceiver(two, intentFilter);

        three = new ThreeReceiver();
        IntentFilter intentFilter3 = new IntentFilter();
        intentFilter3.setPriority(-1000);
        intentFilter3.addAction("com");
        registerReceiver(three, intentFilter3);
    }

    @Override
    protected void onPause() {
        super.onPause();

        unregisterReceiver(one);
        unregisterReceiver(two);
        unregisterReceiver(three);
    }

7.注意

对于不同注册方式的广播接收器回调OnReceive(Context context,Intent intent)中的context返回值是不一样的:

对于静态注册(全局+应用内广播),回调onReceive(context, intent)中的context返回值是:ReceiverRestrictedContext;
对于全局广播的动态注册,回调onReceive(context, intent)中的context返回值是:Activity Context;
对于应用内广播的动态注册(LocalBroadcastManager方式),回调onReceive(context, intent)中的context返回值是:Application Context。
对于应用内广播的动态注册(非LocalBroadcastManager方式),回调onReceive(context, intent)中的context返回值是:Activity Context;
在广播中启动activity的话,需要为intent加入FLAG_ACTIVITY_NEW_TASK的标记,不然会报错,因为需要一个栈来存放新打开的activity。
广播中弹出AlertDialog的话,需要设置对话框的类型为:TYPE_SYSTEM_ALERT不然是无法弹出的。

发布了138 篇原创文章 · 获赞 18 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/chentaishan/article/details/105286353