A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© shw1072047958 中级黑马   /  2016-6-10 00:12  /  1440 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

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非常类似。
在上文说列举的广播机制具体可以使用的场景中,现分析实际应用中的适用性
第一种情形:同一app内部的同一组件内的消息通信(单个或多个线程之间),实际应用中肯定是不会用到广播机制的(虽然可以用),无论是使用扩展变量作用域、基于接口的回调还是Handler-post/Handler-Message等方式,都可以直接处理此类问题,若适用广播机制,显然有些“杀鸡牛刀”的感觉,会显太“重”;
第二种情形:同一app内部的不同组件之间的消息通信(单个进程),对于此类需求,在有些教复杂的情况下单纯的依靠基于接口的回调等方式不好处理,此时可以直接使用EventBus等,相对而言,EventBus由于是针对统一进程,用于处理此类需求非常适合,且轻松解耦。可以参见文件《Android各组件/控件间通信利器之EventBus》。
第三、四、五情形:由于涉及不同进程间的消息通信,此时根据实际业务使用广播机制会显得非常适宜。下面主要针对Android广播中的具体知识点进行总结。

2.BroadcastReceiver自定义BroadcastReceiver自定义广播接收器需要继承基类BroadcastReceivre,并实现抽象方法onReceive(context, intent)方法。广播接收器接收到相应广播后,会自动回到onReceive(..)方法。默认情况下,广播接收器也是运行在UI线程,因此,onReceive方法中不能执行太耗时的操作。否则将因此ANR。一般情况下,根据实际业务需求,onReceive方法中都会涉及到与其他组件之间的交互,如发送Notification、启动service等。
下面代码片段是一个简单的广播接收器的自定义:
[java] view plain copy
print?

  • public class MyBroadcastReceiver extends BroadcastReceiver {  
  •     public static final String TAG = "MyBroadcastReceiver";  
  •     public static int m = 1;  
  •   
  •     @Override  
  •     public void onReceive(Context context, Intent intent) {  
  •         Log.w(TAG, "intent:" + intent);  
  •         String name = intent.getStringExtra("name");  
  •         Log.w(TAG, "name:" + name + " m=" + m);  
  •         m++;  
  •   
  •         Bundle bundle = intent.getExtras();  
  •   
  •     }  
  • }  

    public class MyBroadcastReceiver extends BroadcastReceiver {        public static final String TAG = "MyBroadcastReceiver";        public static int m = 1;        @Override        public void onReceive(Context context, Intent intent) {            Log.w(TAG, "intent:" + intent);            String name = intent.getStringExtra("name");            Log.w(TAG, "name:" + name + " m=" + m);            m++;            Bundle bundle = intent.getExtras();        }    }

BroadcastReceiver注册类型BroadcastReceiver总体上可以分为两种注册类型:静态注册和动态注册。
1).静态注册:直接在AndroidManifest.xml文件中进行注册。规则如下:
[html] view plain copy
print?

  • <receiver android:enabled=["true" | "false"]  
  • android:exported=["true" | "false"]  
  • android:icon="drawable resource"  
  • android:label="string resource"  
  • android:name="string"  
  • android:permission="string"  
  • android:process="string" >  
  • . . .  


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马