四大组件之BroadcastReceiver探索

本文深入探讨了Android中的广播机制,包括静态注册与动态注册的区别,普通广播、有序广播、本地广播和粘性广播的特点及应用场景。文章详细解释了如何通过Intent发送和接收广播,以及广播在不同场景下的工作流程。
摘要由CSDN通过智能技术生成

BroadcastReceiver是一种消息型组件,用于在不同组件乃至不同的应用之间传递消息.广播有两种注册方式,静态注册和动态注册.广播可以用来实现低耦合的观察者模式,广播一般来说不需要停止,它没有停止的概念.

  • 广播的注册方式
  • 广播的种类

一.广播的注册方式

1.静态注册

静态注册是指在AndroidManifest中注册广播,这种广播在应用安装时会被系统解析,此种形式的广播不需要应用启动就可以收到相应的广播.

<receiver android:name=".MyBroadcast"></receiver>

2.动态注册

动态注册是通过Context.registerReceiver()来实现,并且在不需要的时候可以通过Context.unregisterReceiver()来解除广播,此种形态的广播必须要应用启动才能注册并接收广播.

二.广播的种类

1.普通广播

普通广播是完全异步执行的广播,当广播发出后,基本上所有的广播接收器都会同时收到这条广播,因此他们接收的先后次序是随机的.另外接收器不能截断普通广播.普通广播的示例图如下:
在这里插入图片描述(1)接收系统广播

自定义一个接收器类并继承BroadcastReceiver,然后具体实现在onReceive()方法.需要注意的是BroadcastReceiver的生命周期只有10秒左右,因此onReceive()不能做一些耗时的操作,应该发送给Service,由service来完成,另外onReceive()不要开启子线程.

举例:当网络状态发生变化时,系统会发送一条值为android.net.conn.CONNECTIVITY_CHANGE的广播

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.net.conn.CONNECTIVITY_CHANGE")) {
            //接收网络状态发生变化发送的广播
        }
    }
}
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //动态注册
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        mMyReceiver = new MyReceiver();
        registerReceiver(mMyReceiver,intentFilter);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mMyReceiver);
    }
	//静态注册
    <receiver android:name=".MyReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
            </intent-filter>
    </receiver>

(2)发送自定义广播

自定义广播就是利用Intent把要发送的广播值传入,再利用sendBroadcast()方法把广播发送出去,广播接收器就能接收到这条广播.

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"接收到自定义广播",Toast.LENGTH_SHORT).show();
    }
}
    <receiver android:name=".MyReceiver">
            <intent-filter>
                <action android:name="com.example.test.My_BROADCAST"/>
            </intent-filter>
    </receiver>
    public void click(View view) {
        Intent intent = new Intent("com.example.test.My_BROADCAST");//指明要发送的广播值
        sendBroadcast(intent);
    }

2.有序广播

有序广播是一种同步执行的广播,广播发出后,在同一个时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递,所以此时的广播接收器是有先后顺序的,优先级(priority)高的广播接收器会先收到消息,有序广播可以被接收器截断,使得后面的接收器无法收到它,有序广播的工作流程如图所示:
在这里插入图片描述发送有序广播通过sendOrderBroadcast()方法,该方法有两个参数,第一个参数是intent,第二个参数是一个与权限相关的字符串,这里传入null.

    public void click(View view) {
        Intent intent = new Intent("com.example.test.My_BROADCAST");//指明要发送的广播值
        sendOrderedBroadcast(intent,null);
    }

有序广播通过priority属性来定义优先级,值越大,优先级越高.

    <receiver android:name=".MyReceiver">
            <intent-filter android:priority="100">//设定有序广播优先级,值越大,优先级越高
                <action android:name="com.example.test.My_BROADCAST"/>
            </intent-filter>
    </receiver>

有序广播通过abortBroadcast()方法来截断广播,使该条广播不再向下面传递.

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //逻辑处理
        
        //截断广播,不再向下传递
        abortBroadcast();
        
    }
}

3.本地广播

上面说到的普通广播和有序广播都是全局广播,也就是发出的广播能被其它应用程序接收到,我们也能接收到其它应用程序发送的广播.为了能够简单的解决全局广播可能带来的安全性问题,Android引入了一套本地广播机制,使用这个机制发送的广播只能够在应用程序内部进行传递,且广播接收器也只能接收本应用程序发出的广播.

本地广播主要使用了LocalBroadcastManager来对广播进行管理,需要注意的是本地广播只能使用动态注册的方式注册.代码示例如下:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.test.My_BROADCAST");
        mMyReceiver = new MyReceiver();
        mLocalBroadcastManager.registerReceiver(mMyReceiver,intentFilter);
    
    }
    public void click(View view) {
        Intent intent = new Intent("com.example.test.My_BROADCAST");//指明要发送的广播值
        mLocalBroadcastManager.sendBroadcast(intent);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mLocalBroadcastManager.unregisterReceiver(mMyReceiver);
    }

4.粘性广播

通过Context.sendStickyBroadcast()方法可发送粘性广播,该广播会一直滞留,当有匹配该广播的接收器被注册后,该接收器就会收到该条广播,需要注意的是,粘性广播需要android.permission.BROADCAST_STICKY权限.

sendStickyBroadcast()只保留最后一条广播,并且一直保留下去,这样即使已经有广播接收器处理了该广播,一旦又有匹配的广播接收器被注册,该粘性广播仍会被接收。如果只想处理一遍该广播,可通过removeStickyBroadcast()方法来实现。接收粘性广播的过程和普通广播是一样的,就不多介绍了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值