Android中有序广播的基本使用方法

之前的博客中分析过Android广播机制相关的源码。

我们知道,如果仅将广播分类为有序广播和无序广播,
那么二者最大的区别在于:
Android系统(AMS)向一个广播接收器发送无序广播时,
并不需要等待该广播接收器返回结果,就会继续向下一个广播接收器发送广播。
因此,无序广播可近似地看作同步发送到所有的广播接收器。

但是,当Android系统发送有序广播时,将会等待前一个广播接收器返回结果后(除非处理超时),
才会继续发送向下一个广播接收器发送广播。
因此,有序广播将会按照先后顺序,依次递交给每个广播接收器。

根据有序广播发送的特点,前一个广播接收器可以向后一个广播接收器传递消息。


例如,假设有如下场景:
后台服务完成一些业务后,需要决定是否弹出一个通知栏。
如果判断应用没有在前台运行,就弹出通知栏;否则,就不弹出通知栏。

这个需求有很多种实现方式,我们仅以此场景为例,
看看如果使用有序广播的话,如何来解决这个问题。

//假设后台服务完成业务,调用该接口发送通知
private void showBackgroundNotification(int requestCode, Notification notification) {
    //构造一个Intent
    Intent i = new Intent(ACTION_SHOW_NOTIFICATION);
    i.putExtra(REQUEST_CODE, requestCode);
    i.putExtra(NOTIFICATION, notification);

    //Service继承Context,具有发送有序广播的接口
    //这里仅传入的intent、要求的权限及广播初始携带的Result Code
    sendOrderedBroadcast(i, PERM_PRIVATE, null, null, Activity.RESULT_OK,null,null);
}

现在,在前台的Fragment中动态注册一个广播接收器:

public class VisibleFragment extends Fragment {
    ..............

    //Fragment在前台时,就注册广播接收器
    @Override
    public void onStart() {
        super.onStart();

        IntentFilter filter = new IntentFilter(JobPollService.ACTION_SHOW_NOTIFICATION);
        getActivity().registerReceiver(
                mOnShowNotification, filter, JobPollService.PERM_PRIVATE, null);
    }

    //Fragment离开前台时,就反注册广播接收器
    @Override
    public void onStop() {
        super.onStop();
        getActivity().unregisterReceiver(mOnShowNotification);
    }

    private BroadcastReceiver mOnShowNotification = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            ............
            //调用BroadcastReceiver中的接口,更改广播携带的Result Code
            setResultCode(Activity.RESULT_CANCELED);
        }
    };
    ..............
}

从上面的代码我们知道,当应用在前台时,就会收到后台发送的有序广播,然后修改广播携带的Result Code。


然后,我们再定义一个静态广播接收器:

//AndroidManifest.xml中的定义
............
<receiver android:name=".receiver.NotificationReceiver"
    //外部应用无法发送消息给该BroadcastReceiver
    android:exported="false">
        //指定其优先级最低,确保其最后收到有序广播
        //实际上,从之前博客分析的源码来看,广播本来就会先发送给动态注册的接收器,其次才会发送给静态广播接收器
        <intent-filter android:priority="-999">
                <action android:name="stark.a.is.zhang.photogallery.SHOW_NOTIFICATION"/>
        </intent-filter>
</receiver>
............

在该静态广播接收器的实现代码中:

public class NotificationReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //判断Result Code
        if (getResultCode() != Activity.RESULT_OK) {
            return;
        }

        int requestCode = = intent.getIntExtra(JobPollService.REQUEST_CODE, 0);
        Notification notification = intent.getParcelableExtra(JobPollService.NOTIFICATION);

        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
        notificationManager.notify(requestCode, notification);
    }
}

静态广播接收器在发送通知前,先判断广播携带的Result Code是否满足条件。
根据上文的代码容易看出,如果应用在前台,那么动态注册的广播接收器将会先收到有序广播,
并修改其中的Result Code,于是静态广播接收器收到广播后,就不会弹出通知;
反之,如果应用不在前台,那么静态广播接收器收到广播时,其携带的Result Code与初始时一致,
就会弹出通知栏。


以上案例仅作为静态广播的使用示例,实际上静态广播还可以携带一些其它的数据,
具体使用方式,可以参考对应的api。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值