Android四大组件之BroadcastReceiver(广播)

什么是广播

  • 广播是一个全局的监听器,属于Android四大组件之一,它分为两个角色:广播发送者、广播接收者
  • 广播用于不同组件之间(应用内/不同应用之间),还有多线程之间的通信
  • -

广播的分类及区别——无序广播和有序广播

  • 广播分为无序广播和有序广播,这两种区别在于,无序广播发送的时候,几乎所有的广播接收器都能同时接收到这条广播,它们之间没有先后顺序,这种广播的效率比较高,但是一旦发出就无法截断。而有序广播则不同,在广播发出后,同一时间只会有一个广播接收器能够接收到这条广播,当这个接收器中的逻辑执行完毕后才会广播才会继续传递,所以这个时候的广播是有先后顺序的,优先级高的广播接收器会优先接收到广播并且可以截断广播或者更改广播内容

广播的注册方式及区别——静态注册和动态注册

  • 注册广播的方式一般有两种,在AndroidManifest.xml中注册的称为静态注册,在代码中注册的称为动态注册
  • 静态注册只需要在AndroidManifest.xml中添加<receiver>标签,例如:
        <receiver
            //广播接收器名字
            android:name=".MyBoradCast"
            //是否启动广播
            android:enabled="true"
            //是否能够接收其他app发出的广播
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.mytest.MY_BROADCAST" />
            </intent-filter>
        </receiver>
  • 动态注册广播我们就需要在代码中添加逻辑了,需要注意,对于动态广播,有注册就要有注销,否则会导致内存泄露
  • 广播接收器
MyBoradCast myBoradCast;
  • onResume方法中注册广播
myBoradCast = new MyBoradCast();
IntentFilter intentFilter =  new IntentFilter();
intentFilter.addAction("com.example.mytest.MY_BROADCAST");
registerReceiver(myBoradCast,intentFilter);
  • onPause方法中注销广播
unregisterReceiver(myBoradCast);

注册广播

  • 创建2个广播接收器MyBoradCastMyBoradCast2
public class MyBoradCast extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e( "onReceive: ", "MyBoradCast**********");
    }
}
public class MyBoradCast2 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e( "onReceive2: ", "MyBoradCast2**********");
    }
}

静态注册无序广播

  • AndroidManifest.xml中注册MyBoradCast
        <receiver
            //广播接收器名字
            android:name=".MyBoradCast"
            //是否启动广播
            android:enabled="true"
            //是否能够接收其他app发出的广播
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.mytest.MY_BROADCAST" />
            </intent-filter>
        </receiver>
  • 发送广播
Intent intent = new Intent("com.example.mytest.MY_BROADCAST");
sendBroadcast(intent);

静态注册有序广播

  • AndroidManifest.xml中注册MyBoradCastMyBoradCast2,不同的是在<intent-filter>标签中添加android:process优先级属性,优先级大的先接收广播,发送有序广播使用sendOrderedBroadcast方法
        <receiver
            android:name=".MyBoradCast"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:process="9">
                <action android:name="com.example.mytest.MY_BROADCAST" />
            </intent-filter>
        </receiver>
        <receiver
            android:name=".MyBoradCast2"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="10">
                <action android:name="com.example.mytest.MY_BROADCAST" />
            </intent-filter>
        </receiver>
  • 发送广播
Intent intent = new Intent("com.example.mytest.MY_BROADCAST");
sendOrderedBroadcast(intent,null);

这里写图片描述

  • 可以看到,由于MyBoradCast2的优先级比较大,所以先由MyBoradCast2接收了广播

动态注册无序广播

  • onResume方法中注册广播,在onPause方法中注销广播,上面已经说到了
myBoradCast = new MyBoradCast();
IntentFilter intentFilter =  new IntentFilter();
intentFilter.addAction("com.example.mytest.MY_BROADCAST");
registerReceiver(myBoradCast,intentFilter);
unregisterReceiver(myBoradCast);

动态注册有序广播

  • 注册有序广播相比无序只是需要多添加个属性
myBoradCast = new MyBoradCast();
IntentFilter intentFilter =  new IntentFilter();
//优先级
intentFilter.setPriority(1);
intentFilter.addAction("com.example.mytest.MY_BROADCAST");
registerReceiver(myBoradCast,intentFilter);

案例

  • 我们可以在Activity中创建一个内部类广播 ,方便调用Activity的各种属性
    class MyBroadcast extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.e("shopping: ","**********************" );
        }
    }
  • 然后在Activity的onResume方法中注册
        myBroadcast = new MyBroadcast();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.yang.paopao.shopping");
        registerReceiver(myBroadcast,intentFilter);
  • onPause方法中注销广播
        unregisterReceiver(myBroadcast);

适配器中发送广播示例

  • 在Adpater中发送广播,创建一个方法,在里面添加逻辑,Adpater中发送广播需要通过传入的对象调用sendBroadcast方法,当Activity接收到广播后执行相应的逻辑
    private void broad(){
        Intent intent = new Intent("com.example.yang.paopao.shopping");
        context.sendBroadcast(intent);
    }

Service中发送广播示例

  • 在Service中发送广播与Activity中一样直接通过sendBroadcast发送
Intent intent1 = new Intent("com.example.yang.paopao.shopping");
sendBroadcast(intent1);

系统广播

  • Android中内置了多个系统广播,只要涉及到手机的基本操作,如开机、网络状态变化等,都会发出相应的广播
  • 常见的操作有
    监听网络变化 android.net.conn.CONNECTIVITY_CHANGE
    关闭或打开飞行模式 Intent.ACTION_AIRPLANE_MODE_CHANGED
    系统启动完成后(仅广播一次) Intent.ACTION_BOOT_COMPLETED
    重启设备 Intent.ACTION_REBOOT
    屏幕被关闭 Intent.ACTION_SCREEN_OFF
    屏幕被打开 Intent.ACTION_SCREEN_ON
  • 这几种都是我们常见的系统操作,系统广播是系统发送的,我们只是接收者
  • 我们来看看监听网络变化广播的用法,首先在AndroidManifest.xml中添加权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  • 然后创建一个内部类
    class NetworkChangeReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            //ConnectivityManager主要用于管理与网络连接相关的操作用于查询网络连接状态
            ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            //查询网络连接状态
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo( );
            if (networkInfo != null || networkInfo.isAvailable()){
                Toast.makeText(context, "已连接网络", Toast.LENGTH_SHORT).show();
            }else {
                Toast.makeText(context, "没有网络", Toast.LENGTH_SHORT).show();
            }
        }
    }
  • 注册广播
        networkChangeReceiver = new NetworkChangeReceiver();
        IntentFilter intentFilter =  new IntentFilter();
        intentFilter.addAction("android.net.com.CONNECTIVITY_CHANGE");
        registerReceiver(networkChangeReceiver,intentFilter);
  • 注销广播
        unregisterReceiver(networkChangeReceiver);
  • 然后再看看屏幕唤醒与关闭的广播
    class ScreenStatusReceiver extends BroadcastReceiver {
        String SCREEN_ON = "android.intent.action.SCREEN_ON";
        String SCREEN_OFF = "android.intent.action.SCREEN_OFF";

        @Override
        public void onReceive(Context context, Intent intent) {
            if (SCREEN_ON.equals(intent.getAction())) {
                Log.e("onReceive: ", "屏幕唤醒");
            }
            else if (SCREEN_OFF.equals(intent.getAction())) {
                Log.e("onReceive: ", "屏幕关闭");
            }
        }
    }
  • 注册广播
        screenStatusReceiver = new ScreenStatusReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_SCREEN_ON);
        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
        registerReceiver(screenStatusReceiver, intentFilter);
  • onDestroy中注销广播
        unregisterReceiver(screenStatusReceiver);
  • 运行程序
  • 这里写图片描述
  • 这里需要注意,注销广播不能像前面那样写在onPause中,否则关闭屏幕的时候Activity不可见就会执行onPause然后注销广播
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值