简介安卓广播机制 Android Broadcast

目录

前言——手机的“小动作”

什么是广播?

有了服务为什么还需要广播?

常见的系统action

广播有哪些成员?

广播发送者

广播的发送过程

广播发送过程时序图

广播的两种发送方式

广播接受者

广播接受者的注册过程

广播注册过程时序图

广播的两种注册方式


前言——手机的“小动作”

    如电量低到一定程度会有低电量提醒,插入电源线时炫酷的动画,充满电时又会显示电量已充满,以及当手机开机时显示“欢迎使用中国移动/联通/电信”提醒,关闭wifi、数据时会弹出“网络不可用”等,这些手机的“小动作”都需要系统或应用做出一些反应来让用户感知手机状态的变化,而广播就充当了这个大喇叭的角色,来告知系统和应用是时候做出反应了。

什么是广播?

      作为Android系统的四大组件之一,广播(Broadcast)是一种在组件之间进行消息传递的方式。这些组件可以是在同一个进程或不同进程中,所以广播机制可以让应用与应用间传递消息,也可以让应用接收系统消息。它利用了观察者模式,基于消息发布/订阅事件模型,它没有用户界面,但可以启动Service或Activity,所以它可以对感兴趣的外部事件(电话呼入、网络连接等)来接收并做出响应。

有了服务为什么还需要广播?

  广播机制类似服务的Binder机制都是进程间通信,同样也是基于Binder机制的基础上实现的,但对于Binder来说,在Client组件在和Service组件通信之前,必须要先获得它的一个代理对象,即Client组件事先要知道Service组件的存在。然而在广播机制中,广播发送者实先不需要知道广播接收者的存在,这样就可以降低广播发送者和广播接收者之间的耦合度,从而提高系统的可扩展性和可维护性。

常见的系统action

ACTION_TIME_CHANGED 系统时间被改变
ACTION_DATE_CHANGED 系统日期被改变
 ACTION_TIMEZONE_CHANGED 系统时区被改变
ACTION_BOOT_COMPLETED  系统启动完成
 ACTION_BATTERY_CHANGED 电池电量改变
ACTION_SHUTDOWN 系统被关闭
ACTION_BATTRY_LOW 电池电量低

广播有哪些成员?

    一个事件的完整周期必须有一个传达者,即广播发送者它将手机状态以广播的形式发送出去,这时候就需要一个做出反应的接收者,即广播接收器它对于接收到的广播做出一些应有的反应,如插入电源线时它接收到电源插入的广播就让系统弹出充电效果和此时电量值。

广播发送者

广播发送者负责发送消息,而广播接收者需要先订阅消息,然后才能收到消息,而广播发送者是Android的两个组件,即Activity和Service组件,它们被赋予了广播发送的能力。

广播的发送过程

  1.  广播的发送者将一个特定类型的广播发送给ActivityManagerService,(如下文章中用AMS代替)。
  2. AMS接收到一个广播之后,首先找到与这个广播对应的接收者,这个“找”就是由于应用注册了这个广播,如在AndroidManifest.xml中的静态注册,或在代码中声明对象后使用Context的registerReceiver动态注册,找到后将他们添加到一个广播调度队列中,最后由AMS所运行在的线程的消息队列发送一个类型为BROADCAST_INTENT_MSG的消息,这时候对于广播的发送者来说一个广播就发送完成了。
  3. 当发送到AMS在的线程消息队列中的BROADCAST_INTENT_MSG消息被处理时,AMS就会从广播调度队列中找到需要接收这个广播的广播接收者,并且将对应的广播发送给他们所运行在的应用程序进程。
  4. 广播接收这所运行在的应用程序接收到AMS发送过来的广播之后,并不是直接将接收到的广播分发给广播接收者来处理,而是将接收到的广播封装成一个消息,并且发送到主线程的消息队列中,当这个消息被处理时,应用程序进程才会将它所描述的广播发给相应的广播接收者。

广播发送过程时序图

简介安卓广播机制 Android Broadcast_第1张图片

广播的两种发送方式

  •  无序广播(标准广播Nomal braodcasts)是一种完全异步执行的广播,使用sendBroadcast(Intent)或sendBroadcast(Intent,String),所有的接收者几乎同一时间接收事件,没有顺序可言,这种广播的效率较高,当然也不可以被拦截或被修改。其工作流程图如下。

简介安卓广播机制 Android Broadcast_第2张图片

代码使用如下:

定义一个事件,发送无序广播

Intent intent=new Intene();
//设置任意String的动作,可自定义为了接收者方便接收
intent.setAction("com.example.broadcast");
sendBroadcast(intent)

定义一个广播接收者来接收这个广播事件

public class MyReceiver extends BroadcastReceiver{
 @Override
 public void onReceive(Context context,Intent intent){
     //do something
     Toast.makeText(context,"收到广播",Toast.LENGTH_SHORT).show();
 }
}

在Manifest.xml中配置该接收者


   
   
       
   
  

运行结果:Toast打印出“收到广播” 

  • 有序广播(Ordered broadcasts)则是一种同步执行的广播,使用sendOrderedBroadcast(Intent,String,BroadCastReceiver,Handler,int,String,Bundle),在广播发出后只有一个广播接收器能够收到这条广播,当这个广播逻辑执行完毕后按照优先级,一级一级的向下传递,接收者可以修改广播数据,也可以终止广播事件,其工作流程图如下

简介安卓广播机制 Android Broadcast_第3张图片

 代码使用如下:

定义一个事件,发送一个有序广播

Intent intent = new  Intent();
//设置intent的动作为com.example.broadcast,可以任意定义
intent.setAction("com.example.broadcast");
//发送无序广播
//第一个参数:intent
//第二个参数:String类型的接收者权限
//第三个参数:BroadcastReceiver 指定的接收者
//第四个参数:Handler scheduler
//第五个参数:int 此次广播的标记 
//第六个参数:String 初始数据
//第七个参数:Bundle 往Intent中添加的额外数据
sendOrderedBroadcast(intent, null, null, null, "这是初始数据", );

定义多个广播接收者,来接收这个广播事件。通过Toast的打印判断是否收到广播

public class MyReceiver1 extends BroadcastReceiver {
    public MyReceiver1() {
    }
    @Override
    public void onReceive(Context context, Intent intent) {
        //获取广播中的数据(即得到 "这是初始数据" 字符串)
        String message = getResultData();
        Toast.makeText(context ,message ,Toast.LENGTH_SHORT).show();
        //修改数据
        setResultData("这是修改后的数据");
    }
}
public class MyReceiver2 extends BroadcastReceiver {
    public MyReceiver2() {
    }
    @Override
    public void onReceive(Context context, Intent intent) {
        String message = getResultData();
        Toast.makeText(context ,message ,Toast.LENGTH_SHORT).show();
        //终止广播
        abortBroadcast();
    }
}
public class MyReceiver3 extends BroadcastReceiver {
    public MyReceiver3() {
    }
    @Override
    public void onReceive(Context context, Intent intent) {
        String message = getResultData();
        Toast.makeText(context ,message ,Toast.LENGTH_SHORT).show();
    }
}

在Manifest.xml中配置该接收者。并设置优先级:MyReceiver1>MyReceiver2>MyReceiver3。 



            
                            
                
                
            


                   
                   
                   
                   
            


                   
                   
                   
                   
            

运行结果:MyReceiver1得到广播数据后打印“这是初始数据”,MyReceiver2接收到广播数据打印“这是修改后的数据”,MyReceiver3没有打印。 

广播接受者

  接收到广播后的业务逻辑,直接另写一个新的类继承BroadcastReceiver随后重写onReceive(context,intent)方法,在其中执行接收到广播后所要执行的逻辑,要想接受到广播,就要注册这个广播接收者


public class MyBroadCastReceiver extends BroadcastReceiver{  
   @Override  
   public void onReceive(Context context, Intent intent)   
   {    //doSometing
       Toast.makeText(context,"手机开机了",Toast.LENGTH_LONG).show();
       //还可以从Intent中获取数据、还可以调用BroadcastReceiver的getResultData()获取数据
    }   
} 

广播接受者的注册过程

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

广播注册过程时序图

简介安卓广播机制 Android Broadcast_第4张图片

广播的两种注册方式

  •  代码中的动态注册

  1. 实例化自定义的广播接收者
  2. 实例化意图过滤器,并设置要过滤的广播类型(如,我们接收开机时系统发出的广播)
  3. 使用Context的registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)方法注册广播
//new出上边定义好的BroadcastReceiver
MyBroadCastReceiver mBroadCastReceiver = new MyBroadCastReceiver();
//实例化过滤器并设置要过滤的广播  
IntentFilter intentFilter = new IntentFilter("android.intent.action.MAIN");
//注册广播   
myContext.registerReceiver(mBroadCastReceiver,intentFilter, 
             "android.permission.RECEIVE_BOOT_COMPLETED", null);  
  •   在AndroidManifest.xml的静态注册

直接在AndroidManifest.xml文件中节点中配置广播接收者

  
            
            
              
              
  

还要在同级的位置配置可能使用到的权限


   以上就是广播的使用介绍了,以上代码在广播接收器的onReceive()方法中都只是简单使用了Toast提示了一段文本信息,当真正在项目中使用它时可编写其他逻辑,但是不能在其中添加过多的逻辑或进行任何耗时操作,因为广播接收器时不允许开启线程的,当onReceive()方法运行了较长时间而没有结束时,程序就会报错,因此广播接收器更多的是扮演一种打开程序其他组件的角色,比如创建一条状态栏通知或启动一个服务等。 

此内容均来自本小编公众号,此文章可回复“广播”搜索,主要介绍Java、Android方面知识,欢迎关注一起探讨技术问题

                                                                                        IT女小白的成长史

                                                                                 简介安卓广播机制 Android Broadcast_第5张图片

你可能感兴趣的:(Andriod,java,android)