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系统中,广播(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实例。