您的位置:首页 > 移动开发 > Android开发

Android 系统广播机制

2016-02-01 23:50 330 查看
    本博文的内容来自罗升阳的Android系统源代码情景分析。

    在Android系统中,广播(Broadcast)是一种在组件之间进行消息传递的方式。这些组件可以运行在同一个进程中,也可以运行在不同的进程中。当两个不在同一个进程中的组件通过广播机制来传递消息时,广播机制就有点类似Binder进程间通信机制。事实上,广播机制就是在Binder进程间通信机制的基础上实现的。

    既然如此,Android系统为什么还需要提供广播机制呢?我们知道,在Binder进程间通信机制中,Client组件在和Service组件通信之前,必须先获取它的一个代理对象,即Client组件事先要知道Service组件的存在。然而,在广播机制中,广播发送者事先是不需要知道广播接收者的存在的,这样可以降低广播发送者和广播接收者之间的耦合度,进而提高系统的可扩展性和可维护性。因此,Andriod系统需要提供广播机制。

    广播机制是一种基于消息发布和订阅的事件驱动模型,即广播发送者负责发布消息,而广播接收者需要先订阅消息,然后才能接受到消息。Android系统将广播接收者抽象为一种Broadcast Receiver组件,它是Android应用程序的四大组件之一。同时,Android应用程序的另外两种组件,即Activity组件和Service组件被赋予了发送广播的能力。因此,在Android系统中,使用广播机制在组件之间传递消息是非常方便的。

    广播机制存在一个注册中心,它是由ActivityManagerService来担当的。广播接收者订阅消息的表现形式就是将自己注册到ActivityManagerService中,并且指定要接收的广播的类型。当广播发送者向广播接收者发送一个广播时,这个广播首先发送到ActivityManagerService,然后ActivityManagerService根据这个广播的类型找到相应的广播接收者,最后将这个广播发送给它们处理。

    广播接收者的注册方式分为静态注册和动态注册两种。在静态注册方式中,用来描述广播接收者的BroadcastReceiver组件必须要在配置文件AndroidManifest.xml中注明它们所感兴趣的广播的类型,以便ActivityManagerService可以找到它们。在动态注册方式中,我们需要在代码中手动地调用Context接口的成员函数registerReceiver将BroadcastReceiver组件注册到ActivityManagerService中。Activity组件和Service组件都实现了Context接口,因此,我们可以方便地在一个Activity组件或者Service组件中注册一个Broadcast
Receiver组件。同等情况下,动态注册的广播接收者要比静态注册的广播接收者优先接收到广播。

    广播的发送方式分为有序和无序两种。我们在注册广播接收者时,可以指定它们的优先级。当ActivityManagerService接收到有序广播时,它就会先将这个有序广播发送给符合条件的、优先级较高的广播接收者处理,然后再发送给符合条件的、优先级较低的广播接收者处理;而当ActivityManagerService接收到无序广播时,它就会忽略广播接收者的优先级,并行地将这个无序广播发送给符合条件广播接收者处理。

广播接收者的注册:

    在Android系统的广播机制中,ActivityManagerService扮演着注册中心的角色,用来注册广播接收者以及转发广播。因此,Android应用程序注册广播的过程实际上就是把一个广播接收者注册到 ActivityManagerService中的过程。

    IntentFilter counterActionFilter = new IntentFilter(CounterService.BROADCAST_COUNTER_ACTION);

    registerReceiver(counterActionReceiver, counterActionFilter);

    private BroadcastReceiver counterActionReceiver = new BroadcastReceiver(){

        public void onReceiver(Context context, Intent intent){

        ..............

        }

    }

    前面的例子中,Activity组件Broadcounter调用其父类ContextWrapper的成员函数registerReceiver向ActivityManagerService注册了一个广播接收者counterActionReceiver,用来接受类型为BROADCAST_COUNTER_ACTION的广播。

广播的发送过程:

    (1)广播发送者,即一个Activity组件或者一个Service组件,将一个特定类型的广播发送给ActivityManagerService。

    (2)ActivityManagerService接收到一个广播之后,首先找到与这个广播对应的广播接收者,然后将它们添加到一个广播调度队列中,最后向ActivityManagerService所运行的线程的消息队列发送一个类型为BROADCAST_INTENT_MSG的消息。这时候对广播发送者来说,一个广播就发送完成了。

   (3)当发送到ActivityManagerService所运行在的线程的消息队列中的BROADCAST_INTENT_MSG消息被处理时,ActivityManagerService就会从广播调度队列中找到需要接收广播的广播接收者,并且将对应的广播发送给它们所运行在的应用程序进程。

    (4)广播接收者所运行在的应用程序进程接收到ActivityManagerService发送过来的广播之后,并不是直接将接收到的广播分发给广播接收者来处理,而是将接收到的广播封装成一个消息,并且发送到主线程的消息队列中。当这个消息被处理时,应用程序进程才会将它所描述的广播发送给相应的广播接收者处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android