zoukankan      html  css  js  c++  java
  • 转载__广播机制

    http://www.cnblogs.com/RMBP975/archive/2013/03/12/2955733.html

    Android广播机制简介

      Android中的广播跟传统意义上的电台广播类似,广播机制最大的特点就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的。另外,广播可以被不只一个应用程序所接收,当然也可能不被任何应用程序所接收。

    Android广播机制的三要素

      Android广播机制包含三个基本要素:广播(Broadcast) - 用于发送广播;广播接收器(BroadcastReceiver) - 用于接收广播;意图内容(Intent)-用于保存广播相关信息的媒介。Broadcast是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver是对发送出来的Broadcast进行过滤接受并响应的一类组件。

    广播(Broadcast)

      Android广播可分为有序广播、普通广播(无序广播)和sticky广播(滞留广播)。

      1.普通广播

        普通广播是完全异步的,通过Context.sendBroadcast()方法来发送,消息传递的效率比较高,但所有的receivers(接收器)的执行顺序不确定,缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播,直到没有与之匹配的广播接收器为止。

      2.有序广播

         有序广播通过Context.sendOrderedBroadcast()来发送,所有的receiver依次执行。当广播接收器接收到广播后可以使用setResult()函数来结果传给下一个广播接收器接,然后通过getResult()函数来取得上个广播接收器接返回的结果,并可以abort()函数来让系统丢弃该广播,使用该广播不再传送到别的广播接收器接。

         可以通过在receiver的intent-filter中设置android:priority属性来设置receiver的优先级。

      3. sticky广播

        sticky广播通过Context.sendStickyBroadcast()方法来发送,用此方法发送的广播会一直滞留(等待),当有匹配此广播的广播接收器被注册后,且此广播接收器处于活跃状态,该广播接收器就会收到此条广播。使用此方法发送广播时,需要获得BROADCAST_STICKY权限。

        sendStickyBroadcast只保留最后一条广播,并且一直保留下去,这样即使已经有广播接收器处理了该广播,当再有匹配的广播接收器被注册时,此广播仍会被接收。如果你只想处理一遍该广播,可以通过removeStickyBroadcast()方法。

      广播的接收优先级

        有序广播:如果静态注册的广播接收器的优先级高于动态注册的广播接收器的优先级,那么还是静态注册的广播接收器先接收到广播

        无序广播:动态注册的广播接收器高优先级 > 动态注册的广播接收器低优先级 > 静态注册的广播接收器高优先级 > 静态注册的广播接收器低优先级

        同等优先级的广播接收器接收广播的顺序有个普适原则:

          1) 同等优先级的动态注册的广播接收器,先注册的先接收

          2) 同等优先级的静态接收器,接收广播的顺序与String[] java.io.File.list()顺序一致

        该结果来源于:http://su1216.iteye.com/blog/1747706

    广播接收器(BroadcastReceiver)

      BroadcastReceiver(广播接收器)一个用于监听应用程序运行环境变化,并且对变化事件作出响应的组件,Broadcast Reciver和事件处理机制类似,不同的是事件处理机制是应用程序组件级别的,比如一个按钮的OnClickListener事件,只能够在一个应用程序中处理。而广播事件处理机制是系统级别的,不同的应用程序都可以处理广播事件。

      我们也可以在自己的应用程序中开发BroadcastReceiver,然后把广播接收器这个类或者对象注册到Android操作系统上去,让操作系统知道现在有这样一个广播接收器正在等待接收Android操作系统的广播,即在自己的应用程序中实现BroadcastReceiver来监听和响应广播的Intent。

      当有广播事件产生时,Android操作系统首先告诉注册到其上面的广播接收器产生了一个怎么样的事件,每个接收器首先判断是不是我这个接收器需要的事件,如果是它所需要的事件,再进行相应的处理。  

       1.注册BroadcastReceiver

      BroadcastReceiver用于监听被广播的事件(Intent),为了达到这个目的,BroadcastReceiver必须进行注册,注册的方法有以下两种:

      1)静态注册(常驻广播)

          静态注册方式是在AndroidManifest.xml的application里面定义receiver并设置要接收的action。特点是:不管改应用程序是否处于活动状态,都会进行监听。

    1 <receiver android:name="MyReceiver">
    2     <intent-filter>
    3         <action android:name="MyReceiver_Action"/>
    4     </intent-filter>
    5 </receiver>

         <intent-filter>标签设置过滤器,接收指定action广播。   

      2)动态注册(非常驻广播)

         动态注册方式在activity里面调用函数来注册,和静态的内容差不多。一个形参是receiver,另一个是IntentFilter,其中里面是要接收的action。特点是:在代码中进行注册后,当应用程序关闭后,就不再进行监听。

    1 //创建一个广播接受者
    2 MyReceiver receiver = new MyReceiver();
    3 //创建过滤器,并指定action,使之用于接收同action的广播
    4 IntentFilter filter = new IntentFilter("MyReceiver_Action");
    5 //注册广播接收器
    6 registerReceiver(receiver, filter);  

      2.发送广播

        创建一个Intent(意图)对象,指定意图的action,通过sendBroadcast(mIntent)方法发送广播,可以通过Intent携带参数数据。

    1 // 指定广播目标Action
    2 Intent intent = new Intent("MyReceiver_Action");
    3 // 可通过Intent携带消息
    4 intent.putExtra("msg", "发送广播");
    5 // 发送广播消息
    6 sendBroadcast(intent);

      3.注销BroadcastReceiver

        通过静态方式注册的广播接收器,不需要手动注销,该对象的实例在onReceive被调用之后就会在任意时间内被销毁,而通过动态方式注册的广播接收器,则需要在Activity进入停止或者销毁状态的时候使用unregisterReceiver方法手动注销。

    1 //注销广播接收器
    2 unregisterReceiver(receiver);

        一般来说BroadcastReceiver对象在onStart中注册,在onStop中注销。

      4.BroadcastReceiver的生命周期

        BroadcastReceiver对象只有在被调用onReceive(Context, Intent)时才有效,当从该函数返回后,该对象就无效的了,结束生命周期。

        拥有一个活跃状态的广播接收器的进程被保护起来而不会被杀死,但仅拥有失活状态组件的进程则会在其它进程需要它所占有的内存的时候随时被杀掉。所以,如果响应一个广播信息需要很长的一段时间,我们一般会将其纳入一个衍生的线程中去完成,而不是在主线程内完成它,从而保证用户交互过程的流畅。
    1 public class MyReceiver extends BroadcastReceiver {   
    2     @Override  
    3     public void onReceive(Context context, Intent intent) {   
    4         //接受到广播之后的处理逻辑  
    5     }   
    6 }
        MyReceiver为继承BroadcastReceiver的类,重写了onReceiver方法,并在onReceiver方法中对广播进行处理。
  • 相关阅读:
    logger日志工具类
    主机连不上虚拟机中的Redis的原因分析、以及虚拟机网络配置
    sudo密码错误的解决办法
    FileReader和FileInputStream的区别
    用DriverBackUp备份了文件 装好系统后怎么把备份的驱动文件还原
    surface pro系统按键+重装系统
    修复漏洞需要很多时间
    Mybatis一对多查询得不到多方结果
    推荐几个好的 Maven 常用仓库网址
    Math.round(),Math.ceil(),Math.floor()的区别
  • 原文地址:https://www.cnblogs.com/awkflf11/p/4175900.html
Copyright © 2011-2022 走看看