Android的Broadcast知识点总结

1.定义

  广播是Android为了让app内部或者app之间或者app和系统之间的交互所使用的一个机制,其主要的特点就是,broadcast只负责发送广播,不负责对应事件的处理和处理结果,也就是说它只负责发送广播,而听到广播后所采取的动作和事件与他无关。

2.广播的组成

 广播主要是由三个部分组成。

  1. 广播(Broadcast):用于发送广播,当发送完广播之后,相应的广播接收器会有响应。
  2. 广播接收器(BroadcastReceiver):用于接收广播,当接收到广播之后,处理对应事件。
  3. 意图(Intent):用于保存广播相关的数据。

2.广播分类

  • 标准广播(Normal broadcasts):广播的最标准的形式,为异步执行。当发出这种广播的时候,所有的广播接收器都会无差别的在同一时刻内接收到这条广播,效率高,但是也无法截断,一般情况下都会采用这种广播。
  • 有序广播(Ordered broadcasts):广播的同步执行的形式。当发出这种广播之后,所有的广播接收器会按照设定好的优先级顺序依次接收到广播。
    • 只有在前面一个广播接收器的逻辑执行完之后,后面的广播接收器才能收到广播。
    • 有序广播中,后面的广播接收器所接收到的数据,是前面的广播接收器已经修改过的。
    • 有序广播是可以从中间截断的,截断之后,后面的广播接收器就收不到广播了。
  • 本地广播:仅在当前app内部所传播的广播,发出的广播不会被其他app监听到。
  • 系统广播:由Android系统所发出的广播,发出的广播所有的app都能监听到。

3.广播的注册方式

首先,无论是哪种广播的注册,都需要一个广播接收器,新建一个类继承BroadcastReceiver,并重写其中的onReceive()方法,这样一个广播接收器就完成了。

public class ToastBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "It's a broadcastReceiver", Toast.LENGTH_SHORT).show();
    }
}

3.1动态注册

动态注册:在代码中注册,在注册之后,每当发出广播的时候,广播接收器就会响应,并且完成相应的事件。

  • 在MainActivity中注册一个监听网络变化的广播。在我们实机上改变网络环境时(模拟器不太好使),比如开关数据连接和开关wifi的时候,就会弹出这个toast。顺带一提,广播的执行是无关app的,也就是说,当你切换网络环境的时候,即使在桌面或者其他app,也会弹出这个toast。
public class MainActivity extends AppCompatActivity {

    public IntentFilter intentFilter = new IntentFilter();
    
    //实例化一个广播
    ToastBroadcastReceiver toastBroadcastReceiver = new ToastBroadcastReceiver();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        
        //android.net.conn.CONNECTIVITY_CHANGE是Android系统在每当网络环境变化的时候发出的系统广播
        //在intentfilter添加这个动作之后,就会对这个行为进行监听     
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        
        //动态注册广播必须要有context,而activity本身就是一个context
        registerReceiver(toastBroadcastReceiver, intentFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //动态注册广播的优势就是,在不需要使用的时候,就注销,注销之后就不会再有监听了。
        unregisterReceiver(toastBroadcastReceiver);
    }
}

3.2静态注册

静态注册:在AndroidManifest.xml中注册,用静态方式注册的广播不能取消注册,不过好处是,静态广播一经注册,即使没有打开app,也会在接收到广播的时候使用。

  • 删除动态注册的代码,在AndroidManifet.xml中添加监听手机开机的广播,这样在手机开机的时候就会有对应Toast,当然,手机刚开机的时候我们的app自然是没有打开。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.broadcastdemo">

    <!-- 添加app可以监听开机的权限 -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

	
       <!-- 这个receiver就是我们的广播接收器了 -->
        <receiver
            android:name=".ToastBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <!-- 为广播接收器添加监听开机的广播 -->
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

    </application>

</manifest>
  • 其中android:enabled="true"表示广播接收器可以被实例化;android:exported="true"表示广播接收器可以被其他app所看见。

  • 为什么不监听网络的原因1:android的SDKVersion上24的时候,不能再用静态监听了,不过动态监听不受影响。

  • 注意2:从Android8.0开始,绝大部份的静态广播都不再被允许注册了,不过刚刚测试用到的开机广播还是可以使用的。

4.自定义广播

广播不仅是指接收来自系统发出的广播,我们自己也可以写一个广播来使用。

  1. 删除Android静态广播的receiver部分。
  2. 布局中随意添加一个button作为发出广播的条件。
  3. 由于这个广播只是内部使用,所以就正好用本地广播。在MainActivity添加本地广播的代码。
  4. 要注意的是,本地广播和普通广播是分开计算,不能互相监听,本地广播发出的广播只能被本地注册的接收器接收到,普通注册的接收不到。
public class MainActivity extends AppCompatActivity {

   //意图过滤器,用这个添加我们所需要的广播,也就是过滤掉不需要的广播
   private IntentFilter intentFilter = new IntentFilter();

   ToastBroadcastReceiver toastBroadcastReceiver = new ToastBroadcastReceiver();

   //本地广播所需要的本地广播管理类。
   private LocalBroadcastManager localBroadcastManager;

   Button button;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       button = findViewById(R.id.button);

       //获取实例
       localBroadcastManager = LocalBroadcastManager.getInstance(this);

       //既然是自定义广播,那广播名字自然也是自定义
       intentFilter.addAction("test_Aciton");

       //注册本地广播
       localBroadcastManager.registerReceiver(toastBroadcastReceiver, intentFilter);
       //注册广播
       //registerReceiver(toastBroadcastReceiver, intentFilter);

       button.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View view) {
               //实例化意图和添加广播
               Intent intent = new Intent("test_Aciton");

               //通过本地广播管理类发出本地广播
               localBroadcastManager.sendBroadcast(intent);

               //如果是发送普通广播就用下面这个,当然注册广播的时候也要注册普通广播
               //sendBroadcast(intent);

           }
       });
   }

   @Override
   protected void onDestroy() {
       super.onDestroy();
       //注销本地广播
       localBroadcastManager.unregisterReceiver(toastBroadcastReceiver);
       //注销广播
       //unregisterReceiver(toastBroadcastReceiver);

   }
}

效果还是弹出Toast

5.其他

5.1 同时注册的静态动态广播

有一个广播同时用静态和动态的方式注册了,那么在发出广播的时候,会先执行动态注册的那个广播。

5.2 多个广播接收器中指定其中一个

如果一个广播可以同时被多个广播接收器给接受,那么要如何做才能只让其中的一个广播接收器收到广播呢?

在AndroidManifest文件中,为广播加上自定义权限。广播接收器所在的app必须声明了这个权限才能收到该广播。

在发出广播的app中声明:

<permission android:name="broad.ok.receiver" android:protectionLevel="normal"/>
<uses-permission android:name="broad.ok.receiver" />

发出广播的时候加上权限字符串。

Intent intent = new Intent();
intent.putExtra("info", "消息内容");
intent.setAction("myBroadcast.action.call");
sendBroadcast(intent, "broad.ok.receiver");
//sendOrderedBroadcast(intent,"broad.ok.receiver");

只有声明了该权限的app才能收到该广播。

<uses-permission android:name="broad.ok.receiver"/>

参考材料

Android总结篇系列:Android广播机制
http://www.cnblogs.com/lwbqqyumidi/p/4168017.html%20
第一行代码——Android(第2版)
p170 - p185
17 个必须掌握的 BroadcastReceiver 知识点「建议收藏」 - 圆号本昊 - 博客园
https://www.cnblogs.com/yuanhao-1999/p/11817955.html


  1. 静态注册不监听网络的原因参考这篇:
    https://blog.csdn.net/c6e5uli1n/article/details/81351511 ↩︎

  2. 新版本不能静态注册广播的原因参考这篇:
    https://www.cnblogs.com/fuyaozhishang/p/8580610.html ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值