Android系统中的广播(Broadcast)机制简要介绍和学习计划
- 格式:docx
- 大小:139.83 KB
- 文档页数:14
Android中的⼴播(BroadCast)详细介绍什么是⼴播在Android中,Broadcast是⼀种⼴泛运⽤的在应⽤程序之间传输信息的机制。
我们拿⼴播电台来做个⽐⽅。
我们平常使⽤收⾳机收⾳是这样的:许许多多不同的⼴播电台通过特定的频率来发送他们的内容,⽽我们⽤户只需要将频率调成和⼴播电台的⼀样就可以收听他们的内容了。
Android中的⼴播机制就和这个差不多的道理。
电台发送的内容是语⾳,⽽在Android中我们要发送的⼴播内容是⼀个Intent。
这个Intent中可以携带我们要传送的数据。
电台通过⼤功率的发射器发送内容,⽽在Android中则是通过sendBroadcast这个⽅法来发送(很形象的名字吧)。
⽤户通过调整到具体的电台频率接受电台的内容。
⽽在Android中要接受⼴播中的内容则是通过注册⼀个BroadCastReceiver 来接收的。
只有发送⼴播的action和接收⼴播的action相同,接受者才能接受这个⼴播。
⼴播有什么⽤其实,在什么是⼴播的第⼀句就已经说明了⼴播有什么⽤了。
对了,笼统⼀点讲就是⽤来传输数据的。
具体⼀点说就是:1.实现了不同的程序之间的数据传输与共享,因为只要是和发送⼴播的action相同的接受者都能接受这个⼴播。
典型的应⽤就是android⾃带的短信,电话等等⼴播,只要我们实现了他们的action的⼴播,那么我们就能接收他们的数据了,以便做出⼀些处理。
⽐如说拦截系统短信,拦截骚扰电话等等 2.起到了⼀个通知的作⽤,⽐如在service中要通知主程序,更新主程序的UI等。
因为service是没有界⾯的,所以不能直接获得主程序中的控件,这样我们就只能在主程序中实现⼀个⼴播接受者专门⽤来接受service发过来的数据和通知了。
实现⼴播现在我们就来实现⼀个简单的⼴播程序。
Android提供了两种注册⼴播接受者的形式,分别是在程序中动态注册和在xml中指定。
他们之间的区别就是作⽤的范围不同,程序动态注册的接收者只在程序运⾏过程中有效,⽽在xml注册的接收者不管你的程序有没有启动有会起作⽤。
Android7.0Activi...Android 7.0 ActivityManagerService(5) ⼴播(Broadcast)相关流程分析(1)⼀、基础知识⼴播(Broadcast)是⼀种Android组件间的通信⽅式。
从本质上来看,⼴播信息的载体是intent。
在这种通信机制下,发送intent的对象就是⼴播发送⽅,接收intent的对象就是⼴播接收者。
在Android中,为⼴播接收者定义了⼀个单独的组件:BroadcastReceiver。
1 BroadcastReceiver的注册类型在监听⼴播前,要将BroadcastReceiver注册到系统中。
BroadcastReceiver总体上可以分为两种注册类型:静态注册和动态注册。
静态注册静态注册是指:通过在AndroidManifest.xml中声明receiver标签,来定义BroadcastReceiver。
PKMS初始化时,通过解析Application的AndroidManifest.xml,就能得到所有静态注册的BroadcastReceiver信息。
当⼴播发往这种⽅式注册的BroadcastReceiver时,若该BroadcastReceiver对应的进程没有启动,AMS需要先启动对应的进程,然后利⽤Java反射机制构造出BroadcastReceiver,然后才能开始后续的处理。
在AndroidManifest.xml中定义BroadcastReceiver时,对应的标签类似于如下形式:android:exported=["true" | "false"]android:icon="drawable resource"android:label="string resource"android:name="string"android:permission="string"android:process="string" >其中:android:enabled表⽰此broadcastReceiver是否可⽤,默认值为true。
android broadcast原理
AndroidBroadcast原理是指Android系统中用于应用程序之间通信的一种机制。
它可以让一个应用程序向所有其他应用程序广播一个消息,其他应用程序可以注册一个BroadcastReceiver(广播接收器)来接收该消息。
因此,Broadcast机制是一种非常重要的跨应用程序通信方式。
在Android系统中,一个Broadcast消息由一个Intent对象表示,它包含了要广播的消息以及相关的信息。
当一个应用程序发送一个Broadcast时,Android系统会将该消息发送给所有已注册相应IntentFilter的BroadcastReceiver。
BroadcastReceiver可以通过Intent对象中的信息来判断是否需要处理该消息,并进行相应的处理。
Android系统中有两种广播方式:普通广播和有序广播。
普通广播是一种异步广播方式,即发送者不会等待接收者的响应,而是直接发送广播。
这种广播方式的优点是速度快,但是也存在一些缺点,如接收者无法阻止其他应用程序的广播或在广播处理过程中进行拦截
和修改。
有序广播是一种同步广播方式,即发送者等待接收者的响应,每个接收者在处理完广播后,可以选择继续将广播传递给下一个接收者或者终止广播。
这种广播方式的优点是安全性高,但是也存在一些缺点,如速度比较慢。
Broadcast机制在Android系统中被广泛应用,例如在系统事件、应用程序之间的通信、插件等方面。
掌握Broadcast原理对于Android
开发人员来说是非常重要的。
Android应用程序发送广播(sendBroadcast)的过程分析前面我们分析了Android应用程序注册广播接收器的过程,这个过程只完成了万里长征的第一步,接下来它还要等待ActivityManagerService将广播分发过来。
ActivityManagerService 是如何得到广播并把它分发出去的呢?这就是本文要介绍的广播发送过程了。
广播的发送过程比广播接收器的注册过程要复杂得多了,不过这个过程仍然是以ActivityManagerService为中心。
广播的发送者将广播发送到ActivityManagerService,ActivityManagerService接收到这个广播以后,就会在自己的注册中心查看有哪些广播接收器订阅了该广播,然后把这个广播逐一发送到这些广播接收器中,但是ActivityManagerService并不等待广播接收器处理这些广播就返回了,因此,广播的发送和处理是异步的。
概括来说,广播的发送路径就是从发送者到ActivityManagerService,再从ActivityManagerService到接收者,这中间的两个过程都是通过Binder进程间通信机制来完成的,因此,希望读者在继续阅读本文之前,对Android系统的Binder进程间通信机制有所了解,具体可以参考一文。
本文继续以一文中所开发的应用程序为例子,并且结合上文的内容,一起来分析Android应用程序发送广播的过程。
回顾一下一文中所开发的应用程序的组织架构,MainActivity向ActivityManagerService注册了一个CounterService.BROADCAST_COUNTER_ACTION类型的计数器服务广播接收器,计数器服务CounterService在后台线程中启动了一个异步任务(AsyncTask),这个异步任务负责不断地增加计数,并且不断地将当前计数值通过广播的形式发送出去,以便MainActivity可以将当前计数值在应用程序的界面线程中显示出来。
第十九讲—android中的广播机制本讲内容 (2)本讲目标 (2)本讲重点 (2)本讲难点 (2)知识点1:Android中的广播机制 [30分钟] (2)知识点2:订阅广播 [20分钟] (2)知识点3:监听短信息[35分钟] (2)总结[5分钟] (3)1)考核点 (3)2)作业 (3)授课教师:尚小钢课时:90分钟本讲内容1)理解广播接收者2)订阅广播3)监听短消息本讲目标1)理解广播接收者2)订阅广播3)监听短消息本讲重点1)监听短消息本讲难点1)监听短消息课程知识点讲解:知识点1:Android中的广播机制 [30分钟]a)Android中的广播机制i.Android中的广播是android操作系统上所发生的事件,例如,收到短消息,电池电量过低,开机,收到电话等等,订阅者可以选择所关心的事件进行订阅,那么事件发生就会在onReceive方法接收到所订阅的广播(事件数据) ii.广播就像以前收音机中的电台iii.电台不向固定的听众广播,谁都可以收听iv.收听者需要订阅(调台)广播b)广播接收者i.Android中的广播接收者是继承了BroadcastReceiver类的对象知识点2:订阅广播 [20分钟]a)订阅广播a)订阅广播有两种方式i.在功能清单文件中进行配置1.长期监听,不能关闭服务b)在类中注册i.可以随时打开和关闭服务知识点3:监听短信息[35分钟]a)短信息的actiona)<action android:name="android.provider.Telephony.SMS_RECEIVED"/>b)接收短消息的权限a)<uses-permission android:name="android.permission.RECEIVE_SMS"/>c)获取短消息的内容a)获得Bundle对象i.Bundle bundle=intent.getExtras();b)//短消息以pdu为key存在bundle,数据类型为对象数组i.Object[] obj=(Object[])bundle.get("pdus");c)//获得短消息对象i.SmsMessage[] msgs=new SmsMessage[obj.length];d)获得短消息的具体数据a)for(int i=0;i<msgs.length;i++){i.//获得每一条短消息ii.msgs[i]=SmsMessage.createFromPdu(((byte[])obj[i]));iii.System.out.println("短信内容:"+msgs[i].getMessageBody());iv.System.out.println("发送者:"+msgs[i].getOriginatingAddress());v.System.out.println("发送时间:"+newDate(msgs[i].getTimestampMillis()));vi.}总结[5分钟]1)考核点监听短消息2)作业1.完成上机PPT中的作业部分。
Android Broadcast 广播机制分析一、概述广播(Broadcast)机制用于进程/线程间通信,广播分为广播发送和广播接收两个过程,其中广播接收者BroadcastReceiver 便是Android 四大组件之一。
BroadcastReceiver 分为两类:静态广播接收者:通过AndroidManifest.xml 的标签来申明的BroadcastReceiver。
动态广播接收者:通过AMS.registerReceiver()方式注册的BroadcastReceiver,动态注册更为灵活,可在不需要时通过unregisterReceiver()取消注册。
从广播发送方式可分为三类:普通广播:通过Context.sendBroadcast()发送,可并行处理有序广播:通过Context.sendOrderedBroadcast()发送,串行处理Sticky 广播:通过Context.sendOrderedBroadcast()发送二、注册广播2.1 registerReceiver 广播注册,对于应用开发来说,往往是在Activity/Service 中调用registerReceiver()方法,而Activity/Service 都间接继承于Context 抽象类,真正干活是交给ContextImpl 类。
另外调用getOuterContext()可获取最外层的调用者Activity/Service。
[ContextImpl.java]@Overridepublic Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { return registerReceiver(receiver, filter, null, null);}@Overridepublic Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) { //【见小节2.2】return registerReceiverInternal(receiver, getUserId(), filter, broadcastPermission, scheduler, getOuterContext());}当执行两参数的registerReceiver 方法,增加两个broadcastPermission=null 和scheduler=null 调用四参数的注册方法。
第7章 广播机制《Android移动开发》学习目标/Target熟悉广播机制地概述,可以归纳广播机制地实现流程掌握广播接收者地创建方式,可以独立创建广播接收者掌握自定义广播地方式,可以通过自定义广播实现饭堂小广播案例熟悉广播地类型,可以归纳有序广播与无序广播地工作流程章节概述/Summary在Android系统中,广播是一种运用在组件之间传递消息地机制,例如电池电量低时会发送一条提示广播。
如果要接收并过滤广播中地消息,则需求使用BroadcastReceiver(广播接收者),广播接收者是Android四大组件之一,通过广播接收者可以监听系统中地广播消息,实现在不同组件之间地通信,本章将针对广播与广播接收者进行详细讲解。
目录/Contents01 02 03广播机制地概述广播接收者自定义广播与广播地类型7.1广播机制地概述先定一个小目标!熟悉广播机制地概述,可以归纳广播机制地实现流程实际生活中,电台用于发送广播,收音机用于接收广播。
发送广播消息通常情况下在学校地每个教室都会装有一个喇叭,这些喇叭是接入到学校广播室地。
如果有重要通知,会发送一条广播来告知全校师生。
为了便于发送与接收系统级别地消息通知,Android系统也引入了一套类似广播地消息机制。
Android中地广播(Broadcast)机制用于进程/线程间通信,该机制使用了观察者模式,观察者模式是一种软件设计模式,该模式是基于消息地发布/订阅事件模型,该模型中地消息发布者是广播机制中地广播发送者,消息订阅者是广播机制中地广播接收者。
广播机制地具体实现流程,如下图所示。
消息发送者(广播发送者)2. 发送广播(Binder机制)处理中心(AMS)根据消息发布者要求,在已注册列表中,寻找合适地消息订阅者,寻找依据是IntentFilter/Permission3. 发送广播1. 注册广播接收者(Binder机制) 消息订阅者(广播接收者)第一种场景第二种场景第三种场景第四种场景第五种场景在同一个APP内部地同一组件内进行消息通信。
Android总结篇系列:Android广播机制1.Android广播机制概述Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广播接收者(广播接收器)。
广播作为Android组件间的通信方式,可以使用的场景如下:1.同一app内部的同一组件内的消息通信(单个或多个线程之间);2.同一app内部的不同组件之间的消息通信(单个进程);3.同一app具有多个进程的不同组件之间的消息通信;4.不同app之间的组件之间消息通信;5.Android系统在特定情况下与App之间的消息通信。
从实现原理看上,Android中的广播使用了观察者模式,基于消息的发布/订阅事件模型。
因此,从实现的角度来看,Android 中的广播将广播的发送者和接受者极大程度上解耦,使得系统能够方便集成,更易扩展。
具体实现流程要点粗略概括如下:1.广播接收者BroadcastReceiver通过Binder机制向AMS(Activity Manager Service)进行注册;2.广播发送者通过binder机制向AMS发送广播;3.AMS查找符合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BroadcastReceiver (一般情况下是Activity)相应的消息循环队列中;4.消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive()方法。
对于不同的广播类型,以及不同的BroadcastReceiver注册方式,具体实现上会有不同。
但总体流程大致如上。
由此看来,广播发送者和广播接收者分别属于观察者模式中的消息发布和订阅两端,AMS属于中间的处理中心。
广播发送者和广播接收者的执行是异步的,发出去的广播不会关心有无接收者接收,也不确定接收者到底是何时才能接收到。
显然,整体流程与EventBus非常类似。
八维教育—李军宜
Android中广播机制:
收听收音机也是一种广播,在收音机中有很多个广播电台,每个广播电台播放的内容都不相同。
接受广播时广播(发送方)并不在意我们(接收方)接收到广播时如何处理。
好比我们收听交通电台的广播,电台中告诉我们现在在交通状况如何,但它并不关心我们接收到广播时做如何做出处理,这不是广播应该关心的问题,OK,到这里我们从生活中的一些小例子浅浅的理解了一下广播,那么Android 中的广播是如何操作的呢?
在Android 里面有各种各样的广播,比如电池的使用状态,电话的接收和短信的接收都会产生一个广播,应用程序开发者也可以监听这些广播并做出程序逻辑的处理。
一个经典的电话黑名单,首先通过将黑名单号码保存在数据库里面,当来电时,我们接收到来电广播并将黑名单号码与数据库中的某个数据做匹配,如果匹配的话则做出相应的处理,比如挂掉电话、比如静音等等。
Android 中广播的作用:处理android中发出的广播的事件,对广播进行处理。
Android 中广播事件主要分为两类:
1:自定义的广播事件
2:系统广播事件
下面分别演示两种广播事件的处理。
android广播机制原理
Android广播机制是Android中一种用于组件之间进行通信的
机制。
其原理如下:
1. 广播发送:当一个组件(发送者)想要发送广播时,它会创建一个Intent对象,指定广播的Action和一些附加的数据。
然后,组件调用Context的sendBroadcast()方法将广播发送出去。
2. 广播接收:其他的组件(接收者)可以通过注册一个BroadcastReceiver来接收指定Action的广播。
当广播发送后,系统会将广播传递给所有注册了该Action的接收者。
3. 广播过滤:在广播发送时,可以指定IntentFilter来限制只有符合某些条件的接收者才能接收到广播,例如指定广播的权限、指定广播的数据类型等。
4. 广播处理:当接收者收到广播后,系统会自动调用其onReceive()方法,并将广播传递给该方法。
在onReceive()方
法中可以对广播进行处理,例如获取广播中的数据、更新UI 等。
5. 广播顺序:如果有多个接收者注册了同一个Action的广播,系统会按照其注册的顺序依次调用它们的onReceive()方法。
接收者可以通过setPriority()方法来指定自己的优先级,优先
级高的接收者会先收到广播。
通过广播机制,Android中的不同组件(Activity、Service、
BroadcastReceiver等)可以实现松耦合的通信,提高了系统的扩展性和灵活性。
同时,广播也可以用于系统事件的通知,例如屏幕开关、网络状态的改变等。
Android⼴播机制详细介绍(⼴播分类、注册⽅式)⼴播机制详细介绍(⼴播分类、注册⽅式)。
(⼀). 安卓⼴播的分类a.标准⼴播1 2 3 4 5标准⼴播发出以后,所有的⼴播接收器,可以⼏乎在同⼀时刻同时接受到这条⼴播。
优点:效率⾼缺点:不能被截断。
b.有序⼴播1 2 3 4 5 6 7有序⼴播发出以后,同⼀时刻只能有⼀个⼴播接收器收到这条⼴播。
优先级⾼的⼴播先接受到这条⼴播。
在当前⼴播接收器处理完⾃⼰的逻辑以后,可以执⾏两种动作:1.继续传递⼴播2.将⼴播截断(⼆). 注册⼴播的⽅式a. 动态注册1 2 3在代码中注册的⼴播,被称为动态注册。
动态注册的⼴播,最后必须取消注册。
这类⼴播,只有应⽤启动了,才能接收到⼴播。
动态注册⼴播需要的东西⼀个⼴播接收器类 —— 实质就是⼀个继承⾃BoradCastReceiver的类,只要继承这个类,就具体接收⼴播的能⼒了,但是能接受什么⼴播由下⾯的第三条决定。
重写⽗类的onReceive()⽅法 —— 接收到⼴播的时候,就会回调这个⽅法。
因此,⼴播接收器的处理逻辑就写在这⾥⼀个 IntentFilter 对象,⼴播接收器接收什么样的⼴播,由它的addAction()⽅法决定。
在代码中注册⼴播接收器,通过registerReceiver⽅法。
⽅法接受两个参数,⼀个是⼴播接收器实例,⼀个是IntentFilter实例。
取消注册⼴播,通过unregisterReceiver()⽅法—— 在哪⾥取消注册⽆所谓,只要保证取消注册就OK如果需要权限,则在AndroidManifest.xml⽂件申明权限代码:布局代码:1 2 3 4 5 6<!--?xml version="1.0"encoding="utf-8"?--><linearlayout android:layout_height="match_parent"android:layout_width="match_parent"android:orientation="vertical"xmlns:android=""><buttonandroid:id="@+id/btn_isNetConnect"android:layout_gravity="center"android:layout_height="wrap_content"android:layout_width="wrap_content"android:text="检测⽹络"><textview android:gravity="center"android:id="@+id/txt_show"android:layout_height="80dp"android:layout_width="match_parent"android:textsize="30sp">67</textview></button></linearlayout>1我们写⼀个简单的判断当前⽹络是否可⽤的⼴播。
android 知识点Android 是由 Google 所开发的一个开源的移动操作系统,最初是为智能手机领域设计的。
安卓系统经过近十多年的发展,现在已经广泛应用于各类移动设备,如平板电脑,电视等。
这篇文章将介绍Android 开发中的一些重要知识点。
一、活动(Activity)活动是 Android 应用程序的一个基本组成部分,它通常对应着应用程序中的一个页面。
Android 系统通过 Intent 机制启动和管理活动,活动的代码主要包括声明周期函数、布局文件和处理事件的回调函数等。
二、布局(Layout)布局是 Android 界面开发中的重要组成部分。
Android 系统提供了一种 XML 格式的布局文件来描述用户界面,开发者可以使用LinearLayout、RelativeLayout、GridLayout 等布局来完成页面的搭建。
在布局中,开发者可以设置控件的位置、大小、字体等相关属性。
三、服务(Service)服务是 Android 应用程序中一种后台运行的组件。
服务可以执行诸如下载文件、播放音乐等耗时操作,不会阻塞应用程序的其他组件。
服务的代码通常包括 onStartCommand 和 onDestroy 等生命周期函数以及具体的业务逻辑。
四、广播(BroadcastReceiver)广播是一种事件通知机制,它可以让应用程序中的不同组件相互通信。
通过注册广播接收器(BroadcastReceiver),应用程序可以响应特定的广播事件。
Android 系统提供了多种系统广播事件,例如屏幕关闭、收到短信等。
五、内容提供器(Content Provider)内容提供器是 Android 系统中的一种特殊组件,它可以提供应用程序中的数据给其他应用程序使用。
内容提供器可以访问各种持久化的数据源,如 SQLite 数据库,将数据封装后提供给其他应用程序。
六、资源文件(Resources)资源文件是 Android 应用程序中的重要组成部分,它包括各种不同类型的资源:布局、字符串、图片等等。
[安卓开发] Broadcast 三种广播的使用总结1、什么是安卓的Broadcast?安卓的四大组件之一,是一种广泛应用在应用程序之间传输信息的机制。
2、什么是安卓的BroadcastReceiver?是对发送出来的广播进行过滤接收并响应的一类组件,它就是用来接收来自系统和应用中的广播。
例如系统的广播有开机广播:系统在开机时候会发送开机广播,程序接收到之后,能进行开机自启动。
网络状态改变广播:3g变wifi、网络断开等。
电量改变广播等等。
3、Anroid为什么要这样设计?大大减少开发工作量和开发周期作为开发者,只需要掌握BroadcastReceiver4、怎么理解Broadcast和BroadcastReceiver ?Broadcast就像现实中的广播电台,他发广播信号来,然后我们用收音机来接收,然后处理,并且播放出声音,BroadcastReceiver就相当于那台收音机。
5、使用方法发送:把信息装入一个Intent对象(如:Action、Category),通过调相应的方法将Intent对象以广播的方式发送出去:sendBroadcast();sendOrederBroadcast();sendStickyBroadcast();接收:当Intent发送之后,所有已经注册receivedBroadcastReceiver会检查注册时的IntentFilter是否与发送的Intent相匹配,若匹配则就会调用BroadcastReceiver的onReceiver()方法。
所以当我们定义一个BroadcastReceiver的时候,都需要实现onReceiver()方法。
注意:BroadcastReceiver需要注册静态注册代码动态注册6、注意!!!!BroadReceiver生命周期只有十秒左右,不能直接执行耗时操作,不然会出现ANR(应用程序无响应),也不能用子线程来做,因为每次广播来的时候都会创建一个Reveiver对象,并且调用onReceiver,执行完之后,对象会立刻被销毁,子线程也没了要做耗时操作的话,应该通过发送Intent给Service,由Service来完成。
android broadcast 实现原理Android广播是Android系统中一种重要的组件,用于实现不同组件之间的通信。
广播机制可以实现应用程序的解耦,简化组件之间的通信逻辑。
本文将重点探讨Android广播的实现原理,逐步分析广播机制的工作原理。
一、概述Android广播机制是一种发布-订阅模式,通过一个组件发送广播,其他组件可以注册接收并处理该广播。
发送广播的组件称为广播发布者,接收并处理广播的组件称为广播接收者。
Android广播机制主要分为两类,即标准广播和有序广播。
二、广播发送Android中广播发送通过Intent实现。
广播发布者在发送广播时,创建一个Intent对象,并通过sendBroadcast()或sendOrderedBroadcast()方法发送广播。
Intent对象包含了广播的信息,例如广播的动作、数据等。
三、广播接收广播接收者通过在AndroidManifest.xml中注册或动态注册的方式接收广播。
其中,动态注册的方式通常用于需要动态注册和取消注册的情况,以及需要在应用程序运行期间接收广播的情况。
四、广播注册1. 静态注册广播接收者可以在AndroidManifest.xml文件中通过<receiver>标签注册。
在注册时,需要指定接收的广播类型,即IntentFilter。
IntentFilter 可以通过addAction()方法添加广播动作,还可以通过addCategory()方法添加广播的类别。
同时,可以通过android:priority属性设置广播接收优先级。
2. 动态注册广播接收者可以通过Context的registerReceiver()方法动态注册。
动态注册的广播接收者在接收到广播后,需要在适当的时候调用unregisterReceiver()方法取消注册,以免造成资源的浪费和内存泄漏。
五、广播处理广播接收者在接收到广播后,可以执行相应的操作。
在Android系统中,广播(Broadcast)是在组件之间传播数据(Intent)的一种机制;这些组件甚至是可以位于不同的进程中,这样它就像Binder机制一样,起到进程间通信的作用;本文通过一个简单的例子来学习Android系统的广播机制,为后续分析广播机制的源代码作准备。
在Android系统中,为什么需要广播机制呢?广播机制,本质上它就是一种组件间的通信方式,如果是两个组件位于不同的进程当中,那么可以用Binder机制来实现,如果两个组件是在同一个进程中,那么它们之间可以用来通信的方式就更多了,这样看来,广播机制似乎是多余的。
然而,广播机制却是不可替代的,它和Binder机制不一样的地方在于,广播的发送者和接收者事先是不需要知道对方的存在的,这样带来的好处便是,系统的各个组件可以松耦合地组织在一起,这样系统就具有高度的可扩展性,容易与其它系统进行集成。
在软件工程中,是非常强调模块之间的高内聚低耦合性的,不然的话,随着系统越来越庞大,就会面临着越来越难维护的风险,最后导致整个项目的失败。
Android应用程序的组织方式,可以说是把这种高内聚低耦合性的思想贯彻得非常透彻,在任何一个Activity中,都可以使用一个简单的Intent,通过startActivity或者startService,就可以把另外一个Activity或者Service启动起来为它服务,而且它根本上不依赖这个Activity或者Service的实现,只需要知道它的字符串形式的名字即可,而广播机制更绝,它连接收者的名字都不需要知道。
不过话又说回来,广播机制在Android系统中,也不算是什么创新的东西。
如果读者了解J2EE或者COM,就会知道,在J2EE中,提供了消息驱动Bean(Message-Driven Bean),用来实现应用程序各个组件之间的消息传递;而在COM中,提供了连接点(Connection Point)的概念,也是用来在应用程序各个组间间进行消息传递。
无论是J2EE中的消息驱动Bean,还是COM中的连接点,或者Android系统的广播机制,它们的实现机理都是消息发布/订阅模式的事件驱动模型,消息的生产者发布事件,而使用者订阅感兴趣的事件。
废话说了一大堆,现在开始进入主题了,和前面的文章一样,我们通过具体的例子来介绍Android 系统的广播机制。
在这个例子中,有一个Service,它在另外一个线程中实现了一个计数器服务,每隔一秒钟就自动加1,然后将结果不断地反馈给应用程序中的界面线程,而界面线程中的Activity在得到这个反馈后,就会把结果显示在界面上。
为什么要把计数器服务放在另外一个线程中进行呢?我们可以把这个计数器服务想象成是一个耗时的计算型逻辑,如果放在界面线程中去实现,那么势必就会导致应用程序不能响应界面事件,最后导致应用程序产生ANR(Application Not Responding)问题。
计数器线程为了把加1后的数字源源不断地反馈给界面线程,这时候就可以考虑使用广播机制了。
首先在Android源代码工程中创建一个Android应用程序工程,名字就称为Broadcast吧。
关于如何获得Android源代码工程,请参考在Ubuntu上下载、编译和安装Android最新源代码一文;关于如何在Android源代码工程中创建应用程序工程,请参考在Ubuntu上为Android系统内置Java应用程序测试Application Frameworks层的硬件服务一文。
这个应用程序工程定义了一个名为shy.luo.broadcast的package,这个例子的源代码主要就是实现在这里了。
下面,将会逐一介绍这个package里面的文件。
首先,我们在src/shy/luo/broadcast/ICounterService.java文件中定义计数器的服务接口:view plain1.package shy.luo.broadcast;2.3.public interface ICounterService {4.public void startCounter(int initVal);5.public void stopCounter();6.}这个接口很简单,它只有两个成员函数,分别用来启动和停止计数器;启动计数时,还可以指定计数器的初始值。
接着,我们来看一个应用程序的默认Activity的实现,在src/shy/luo/broadcast/MainActivity.java文件中:view plain1.package shy.luo.broadcast;2.3.import android.app.Activity;4.import android.content.BroadcastReceiver;5.import ponentName;6.import android.content.Context;7.import android.content.Intent;8.import android.content.IntentFilter;9.import android.content.ServiceConnection;10.import android.os.Bundle;11.import android.os.IBinder;12.import android.util.Log;13.import android.view.View;14.import android.view.View.OnClickListener;15.import android.widget.Button;16.import android.widget.TextView;17.18.public class MainActivity extends Activity implements OnClickListener {19.private final static String LOG_TAG = "shy.luo.broadcast.MainActivity";20.21.private Button startButton = null;22.private Button stopButton = null;23.private TextView counterText = null;24.25.private ICounterService counterService = null;26.27.@Override28.public void onCreate(Bundle savedInstanceState) {29.super.onCreate(savedInstanceState);30. setContentView(yout.main);31.32. startButton = (Button)findViewById(R.id.button_start);33. stopButton = (Button)findViewById(R.id.button_stop);34. counterText = (TextView)findViewById(R.id.textview_counter);35.36. startButton.setOnClickListener(this);37. stopButton.setOnClickListener(this);38.39. startButton.setEnabled(true);40. stopButton.setEnabled(false);41.42. Intent bindIntent = new Intent(MainActivity.this, CounterService.class);43. bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE);44.45. Log.i(LOG_TAG, "Main Activity Created.");46. }47.48.@Override49.public void onResume() {50.super.onResume();51.52. IntentFilter counterActionFilter = new IntentFilter(CounterService.BROADCAST_COUNTER_ACTION);53. registerReceiver(counterActionReceiver, counterActionFilter);54. }55.56.@Override57.public void onPause() {58.super.onPause();59. unregisterReceiver(counterActionReceiver);60. }61.62.@Override63.public void onDestroy() {64.super.onDestroy();65. unbindService(serviceConnection);66. }67.68.@Override69.public void onClick(View v) {70.if(v.equals(startButton)) {71.if(counterService != null) {72. counterService.startCounter(0);73.74. startButton.setEnabled(false);75. stopButton.setEnabled(true);76. }77. } else if(v.equals(stopButton)) {78.if(counterService != null) {79. counterService.stopCounter();80.81. startButton.setEnabled(true);82. stopButton.setEnabled(false);83. }84. }85. }86.87.private BroadcastReceiver counterActionReceiver = new BroadcastReceiver(){88.public void onReceive(Context context, Intent intent) {89.int counter = intent.getIntExtra(CounterService.COUNTER_VALUE, 0);90. String text = String.valueOf(counter);91. counterText.setText(text);92.93. Log.i(LOG_TAG, "Receive counter event");94. }95. };96.97.private ServiceConnection serviceConnection = new ServiceConnection() {98.public void onServiceConnected(ComponentName className, IBinder service) {99. counterService = ((CounterService.CounterBinder)service).getService();100.101. Log.i(LOG_TAG, "Counter Service Connected");102. }103.public void onServiceDisconnected(ComponentName className) {104. counterService = null;105. Log.i(LOG_TAG, "Counter Service Disconnected");106. }107. };108.}MainActivity的实现也很简单,它在创建(onCreate)的时候,会调用bindService函数来把计数器服务(CounterService)启动起来,它的第二个参数serviceConnection是一个ServiceConnection实例。