安卓--广播机制总结

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

1.Android广播机制概述Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广播接收者(广播接收器)。广播作为Android组件间的通信方式,可以使用的场景如下:1.同一app内部的同一组件内的消息通信(单个或多个线程之间);2.同一app内部的不同组件之间的消息通信(单个进程);3.同一app具有多个进程的不同组件之间的消息通信;4.不同app之间的组件之间消息通信;5.Android系统在特定情况下与App之间的消息通信。从实现原理看上,Android中的广播使用了观察者模式,基于消息的发布/订阅事件模型。因此,从实现的角度来看,Android中的广播将广播的发送者和接受者极大程度上解耦,使得系统能够方便集成,更易扩展。具体实现流程要点粗略概括如下:1.广播接收者BroadcastReceiver通过Binder机制向AMS(ActivityManagerService)进行注册;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等。下面代码片段是一个简单的广播接收器的自定义:1publicclassMyBroadcastReceiverextendsBroadcastReceiver{2publicstaticfinalStringTAG=MyBroadcastReceiver;3publicstaticintm=1;45@Override6publicvoidonReceive(Contextcontext,Intentintent){7Log.w(TAG,intent:+intent);8Stringname=intent.getStringExtra(name);9Log.w(TAG,name:+name+m=+m);10m++;1112Bundlebundle=intent.getExtras();1314}15}BroadcastReceiver注册类型BroadcastReceiver总体上可以分为两种注册类型:静态注册和动态注册。1).静态注册:直接在AndroidManifest.xml文件中进行注册。规则如下:receiverandroid:enabled=[true|false]android:exported=[true|false]android:icon=drawableresourceandroid:label=stringresourceandroid:name=stringandroid:permission=stringandroid:process=string.../receiver其中,需要注意的属性android:exported——此broadcastReceiver能否接收其他App的发出的广播,这个属性默认值有点意思,其默认值是由receiver中有无intent-filter决定的,如果有intent-filter,默认值为true,否则为false。(同样的,activity/service中的此属性默认值一样遵循此规则)同时,需要注意的是,这个值的设定是以application或者applicationuserid为界的,而非进程为界(一个应用中可能含有多个进程);android:name——此broadcastReceiver类名;android:permission——如果设置,具有相应权限的广播发送方发送的广播才能被此broadcastReceiver所接收;android:process——broadcastReceiver运行所处的进程。默认为app的进程。可以指定独立的进程(Android四大基本组件都可以通过此属性指定自己的独立进程)常见的注册形式有:receiverandroid:name=.MyBroadcastReceiverintent-filteractionandroid:name=android.net.conn.CONNECTIVITY_CHANGE//intent-filterintent-filteractionandroid:name=android.intent.action.BOOT_COMPLETED//intent-filter/receiver其中,intent-filter由于指定此广播接收器将用于接收特定的广播类型。本示例中给出的是用于接收网络状态改变或开启启动时系统自身所发出的广播。当此App首次启动时,系统会自动实例化MyBroadcastReceiver,并注册到系统中。之前常说:静态注册的广播接收器即使app已经退出,主要有相应的广播发出,依然可以接收到,但此种描述自Android3.1开始有可能不再成立,具体分析详见本文后面部分。2).动态注册:动态注册时,无须在AndroidManifest中注册receiver/组件。直接在代码中通过调用Context的registerReceiver函数,可以在程序中动态注册BroadcastReceiver。registerReceiver的定义形式如下:1registerReceiver(BroadcastReceiverreceiver,IntentFilterfilter)2registerReceiver(BroadcastReceiverreceiver,IntentFilterfilter,StringbroadcastPermission,Handlerscheduler)典型的写法示例如下:1publicclassMainActivityextendsActivity{2publicstaticfinalStringBROADCAST_ACTION=com.example.corn;3privateBroadcastReceivermBroadcastReceiver;45@Override6protectedvoidonCreate(BundlesavedInstanceState){7super.onCreate(savedInstanceState);8setContentView(R.layout.activity_main);910mBroadcastReceiver=newMyBroadcastReceiver();11IntentFilterintentFilter=newIntentFilter();12intentFilter.addAction(BROADCAST_ACTION);13registerReceiver(mBroadcastReceiver,intentFilter);14}1516@Override17protectedvoidonDestroy(){18super.onDestroy();19unregisterReceiver(mBroadcastReceiver);20}2122}注:Android中所有与观察者模式有关的设计中,一旦涉及到register,必定在相应的时机需要unregister。因此,上例在onDestroy()回到中需要unregisterReceiver(mBroadcastReceiver)。当此Activity实例化时,会动态将MyBroadcastReceiver注册到系统中。当此Activity销毁时,动态注册的MyBroadcastReceiver将不再接收到相应的广播。3.广播发送及广播类型经常说”发送广播“和”接收“,表面上看广播作为Android广播机制中的实体,实际上这一实体本身是并不是以所谓的”广播“对象存在的,而是以”意图“(Intent)去表示。定义广播的定义过程,实际就是相应广播”意图“的定义过程,然后通过广播发送者将此”意图“发送出去。被相应的BroadcastReceiver接收后将会回调onReceive()函数。下段代码片段显示的是一个普通广播的定义过程,并发送出去。其中setAction(..)对应于BroadcastReceiver中的intentFilter中的action。1Intentintent=newIntent();2intent.setAction(BROADCAST_ACTION);3intent.putExtra(name,qqyumidi);4sendBroadcast(intent);根据广播的发送方式,可以将其分为以下几种类型:1.NormalBroadcast:普通广播2.SystemBroadcast:系统广播3.Orderedbroadcast:有序广播4.StickyBroadcast:粘性广播(在android5.0/api21中deprecated,不再推荐使用,相应的还有粘性有序广播,同样已经deprecated)5.LocalBroadcast:App应用内广播下面分别总结下各种类型的发送方式及其特点。1).NormalBroadcast:普通广播此处将普通广播界定为:开发者自己定义的intent,以context.sendBroadcast_AsUser(intent,...)形式。具体可以使用的方法有:sendBroadcast(intent)/sendBroadcast(intent,receiverPermission)/sendBroadcastAsUser(intent,userHandler)/sendBroadcastAsUser(inten

1 / 9
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功