android广播的注册和接收过程

一、广播的注册过程

1、静态注册过程

   在Androidmanifest中进行注册,在receiver中加入关键字<intent-filter>:

<application >
    <receiver 
        android:name=".MyBroadcastReceiver"
        android:exported="true">
        <intent-filter>
            <action android:name="com.unknow.jason.broadcasttest.MY_BROADCAST"/>
        </intent-filter>
    </receiver>
</application>

2、动态注册过程:

在Java代码中进行手动添加广播注册

intentFilter = new IntentFilter();
intentFilter.addAction("com.unknow.jason.broadcasttest.MY_BROADCAST");

myBroadcastReceiver = new MyBroadcastReceiver();
registerReceiver(myBroadcastReceiver, intentFilter);

unregisterReceiver(myBroadcastReceiver);

 3、两个主要的类的广播可以用来接收。
     1).普通广播:(使用 Context.sendBroadcast发出)是完全异步的。所有接收者都运行在一个未定义的顺序里,有时甚至同时接收。这很高效,但也意味着不能使用结束或暂停API。
     2).有序广播:(使用 Context.sendOrderedBroadcast发出)同一时间只传递一个接收器。每个接收器依次执行,它可以传送结果到下一个接收器,当然也可以暂停传送。这个顺序在android:priority属性里通过 intent-filter定义,如果定义同样的优先级则是随机顺序
4、广播注册流程

   1)动态注册过程。

在整个注册过程中,先从activity-> ContextWrapper.registerReceiver() ->ContextImpl.registerReceiver() -> 获取handler ->loadApk -> ActivityManagerService中进行注册.

ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
    rl = new ReceiverList(this, callerApp, callingPid, callingUid,
            userId, receiver);
    if (rl.app != null) {
        rl.app.receivers.add(rl);
    } else {
        receiver.asBinder().linkToDeath(rl, 0);
        rl.linkedToDeath = true;
    }
    mRegisteredReceivers.put(receiver.asBinder(), rl);
}
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
        permission, callingUid, userId);
rl.add(bf);
mReceiverResolver.addFilter(bf);
...
return sticky;

核心注册的地方是在ActivityManagerService中:把广播接收器receiver保存一个ReceiverList列表中,这个列表的宿主进程是rl.app,这里就是MainActivity所在的进程了,在ActivityManagerService中,用一个进程记录块来表示这个应用程序进程,它里面有一个列表receivers,专门用来保存这个进程注册的广播接收器。接着,又把这个ReceiverList列表以receiver为Key值保存在ActivityManagerService的成员变量mRegisteredReceivers中,这些都是为了方便在收到广播时,快速找到对应的广播接收器的。最后把广播接收器receiver和filter关联起来并保存到AMS的成员mReceiverResolver里。

2)静态注册过程

静态注册是在每个应用的AndroidManifest.xml中进行定义。静态注册的广播最后保存在PMS(Package Manage Service)中的receiver列表中,在查询时是由AMS去PMS查找该广播,查到后再由AMS交给用户处理。

5、广播接收流程

下图为广播的发送流程图:

 

在整个的发送流程中可以大致分成三个部分:

1)  从MainActivity -> ActivityManagerService这个过程,通过自己的sendBroadcast把一个广播通过Binder进程间通信机制发送给AMS,AMS根据这个广播的Action类型找到相应的广播接收器,然后把这个广播放进自己的消息队列BroadQueue中去。

2) 从Handler -> Handler, 由于广播的的发送和处理是异步的(否则长时间的处理容易出现ANR),这里处理异步操作主要体现在两个handler的作用,第一个handler是接收AMS发送过来的广播,然后AMS就可以直接返回去处理下一个广播, 然后在收到这个广播后

    会去检查广播发送和接收的权限,如果权限不符合则直接返回。最后进入到LoadApk.ReceiverDispatcher,这里的ReceiverDispatcher就是之前mainActivity在注册的时候写入的,这样就找到了对应需要接收的activity。

    再通过第二个handler进行广播分发给对应的Activiy,然后自己返回继续处理下一个广播。

    所以这里通过两个handler对广播分发和查找对应接收器来达到异步效果。

3) 最后这个广播进入到activity的onReceiver函数中处理。整个广播发送阶段结束

 

posted on 2017-03-30 10:48  kma  阅读(374)  评论(0编辑  收藏  举报

导航