本地广播&有序广播—实现即时通讯的消息提醒
问题描述:
完成及时通信过程系统中的消息未读提醒功能。当用户已经阅读过接受的消息那么就不对信息进行标记。
解决思路:
1.handler机制
handler可以实现子线程与UI主线程之间的消息通信,当接受到来自服务器的消息后首先判断客户端所展现页面,当页面为消息所展现的页面时直接将信息发送给该页面,如果用户没有驻留在该页面,则将信息发送给Home页面,现实出未读消息标记。
以上方法只是提供了一个解决思路,我并没有实现该方法,该方法在实现的过程中应该相对比较复杂。
2.广播机制
广播顾名思义,很好理解,有一方发送广播,其他的在“该频道的人”可以接受到该广播。有序广播是广播的一种,有序广播就是接受者按照一定顺序的接受广播(有先后之分),本地广播是指广播发送者发出的广播信息只能由在同一App中的广播接收者接受。
本地广播或有序广播的运行可以很好的实现即时通信的消息提醒功能。本地广播可以节省性能保证安全性,有序广播可以完成需求。下面详细的介绍本地广播,有序广播的实现机制。
实现过程
1.有序广播
有序广播的实现过程想多比较简单,在注册广播接收者时需要声明优先级。有序广播的声明可以分为三部:
- 创建广播接收者
- 注册广播接受者
- 发送广播
在广播接受者的创建过程中,无论实现的是何种广播,都需要继承BroadcastReceiver。广播接收者在接受到广播时会执行onReceive中的代码。该过程的代码如下:
public class ReceiverLocal extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//业务逻辑
}
}
注册广播接收者就是将广播接收者与要接受到的广播想关联,当发送指定广播时接收者会做出相关操作。注册方法时Activity中的方法,也就是说当在activity中调用注册广播的方法时会自动的给广播接收者传递一个context对象,方便在广播内部进行相关UI操作。注册广播时需要传递两个参数,广播接受者的对象和IntentFilter对象,IntentFilter对象帮助设置广播接收者所需要监听的广播信息以及接收者优先级。广播注册的代码如下。
IntentFilter filter1 = new IntentFilter();
filter1.addAction(INTENT);
filter1.setPriority(1);
registerReceiver(new ReceiverOrderOne(), filter1);
发送广播的过程是向所有的广播接收者发送广播信息,该过程在有序广播和标准广播中的实现方式是相同的。代码如下:
context.sendOrderedBroadcast(INTENT, null);
总结:
通过以上步骤我们不难发现有序广播和标准广播的差别并不大,只是在广播接收者的注册过程中设置优先级参数而已。实现有序广播时只有广播接收者的创建,而并不需要创建广播发送者,那是因为广播是有activity对象发送的(也可能使service)。在整个广播通信过程中最少涉及到两个activity,一个负责发送广播,另一个绑定广播接收者。也就是说广播是依附于activity存在的(也可以是service)。
2.本地广播
本地广播相比较全局广播有着私密性好,性能高的优点。在实现本地广播的过程中需要首先导入support v4包,eclipse需要导入的是jar包(需要的同学可以联系我)。
本地广播需要创建广播管理者对象,该广播管理者使用的是单例模式。本地广播的发送广播发送方式不同于全局广播,主要发送方法有:
localBroadcastManager.sendBroadcast(INTENT);
localBroadcastManager.sendBroadcastSync(INTENT1);
根据上述名字可以判断出后者是线程安全的,sendBroadcastSync的源码如下:
public void sendBroadcastSync(Intent intent) {
if (sendBroadcast(intent)) {
executePendingBroadcasts();
}
}
private void executePendingBroadcasts() {
while (true) {
BroadcastRecord[] brs = null;
synchronized (mReceivers) {
final int N = mPendingBroadcasts.size();
if (N <= 0) {
return;
}
brs = new BroadcastRecord[N];
mPendingBroadcasts.toArray(brs);
mPendingBroadcasts.clear();
}
for (int i=0; i<brs.length; i++) {
BroadcastRecord br = brs[i];
for (int j=0; j<br.receivers.size(); j++) {
br.receivers.get(j).receiver.onReceive(mAppContext, br.intent);
}
}
}
}
本地广播的sendBroadcast方法是依靠list链表实现的,也就是说监听本地广播的广播收听者获取广播都是有序的,安装注册顺序首先获取广播。
总结:
本文只是对广播机制进行简单的讲解,并描述了广播的实现方式。并未对源码层次进行深刻讲解,源码的具体刨析以后写出。有问题或者写的不足的地方欢迎指正。本文重点:本地广播就是一种有序广播。