推荐下载Android Broadcast广播机制分析Word文件下载.docx
《推荐下载Android Broadcast广播机制分析Word文件下载.docx》由会员分享,可在线阅读,更多相关《推荐下载Android Broadcast广播机制分析Word文件下载.docx(47页珍藏版)》请在冰豆网上搜索。
普通广播:
通过Context.sendBroadcast()发送,可并行处理有序广播:
通过
Context.sendOrderedBroadcast()发送,串行处理Sticky广播:
Context.sendOrderedBroadcast()发送二、注册广播2.1registerReceiver广播注册,对
于应用开发来说,往往是在Activity/Service中调用registerReceiver()方法,而
Activity/Service都间接继承于Context抽象类,真正干活是交给ContextImpl类。
另
外调用getOuterContext()可获取最外层的调用者Activity/Service。
[ContextImpl.java]
@OverridepublicIntentregisterReceiver(BroadcastReceiverreceiver,IntentFilterfilter)
{returnregisterReceiver(receiver,filter,null,null);
}@OverridepublicIntent
registerReceiver(BroadcastReceiverreceiver,IntentFilterfilter,String
broadcastPermission,Handlerscheduler){//【见小节2.2】return
registerReceiverInternal(receiver,getUserId(),filter,broadcastPermission,scheduler,
getOuterContext());
}当执行两参数的registerReceiver方法,增加两个
broadcastPermission=null和scheduler=null调用四参数的注册方法。
其中
broadcastPermission拥有广播的权限控制,scheduler用于指定接收到广播时
onRecive执行线程,当scheduler=null则默认代表在主线程中执行,这也是最常见的
用法。
再然后调用6参数的registerReceiverInternal。
2.2registerReceiverInternal[ContextImpl.java]
privateIntentregisterReceiverInternal(BroadcastReceiverreceiver,intuserId,
IntentFilterfilter,StringbroadcastPermission,Handlerscheduler,Contextcontext){
IIntentReceiverrd=null;
if(receiver!
=null){if(mPackageInfo!
=nullcontext!
=null){
if(scheduler==null){//将主线程Handler赋予scheulerscheduler=
mMainThread.getHandler();
}//获取IIntentReceiver对象【2.3】rd=
mPackageInfo.getReceiverDispatcher(receiver,context,scheduler,
mMainThread.getInstrumentation(),true);
}else{if(scheduler==null){scheduler=
}rd=newLoadedApk.ReceiverDispatcher(receiver,context,
scheduler,null,true).getIIntentReceiver();
}}try{//调用AMP.registerReceiver【2.4】
returnActivityManagerNative.getDefault().registerReceiver(
mMainThread.getApplicationThread(),mBasePackageName,rd,filter,
broadcastPermission,userId);
}catch(RemoteExceptione){return
null;
}}ActivityManagerNative.getDefault()返回的是ActivityManagerProxy对象,简称
AMP,该方法中参数有mMainThread.getApplicationThread()返回的是
ApplicationThread,这是Binder的Bn端,用于system_server进程与该进程的通
信。
2.3LoadedApk.getReceiverDispatcher[-LoadedApk.java]
publicIIntentReceivergetReceiverDispatcher(BroadcastReceiverr,Contextcontext,
Handlerhandler,Instrumentationinstrumentation,booleanregistered){synchronized
(mReceivers){LoadedApk.ReceiverDispatcherrd=null;
ArrayMapBroadcastReceiver,
LoadedApk.ReceiverDispatchermap=null;
//此处registered=true,则进入该分支if
(registered){map=mReceivers.get(context);
if(map!
=null){rd=map.get(r);
}}if
(rd==null){//当广播分发者为空,则创建ReceiverDispatcher【2.3.1】rd=new
ReceiverDispatcher(r,context,handler,instrumentation,registered);
if(registered){if
(map==null){map=newArrayMapBroadcastReceiver,
LoadedApk.ReceiverDispatchermReceivers.put(context,map);
}map.put(r,rd);
}}else
{//验证广播分发者的context、handler是否一致rd.validate(context,handler);
}
rd.mForgotten=false;
//获取IIntentReceiver对象returnrd.getIIntentReceiver();
}}不妨
令以BroadcastReceiver(广播接收者)为key,LoadedApk.ReceiverDispatcher(分发者)
为value的ArrayMap记为A。
此处mReceivers是一个以Context为key,以A为
value的ArrayMap。
对于ReceiverDispatcher(广播分发者),当不存在时则创建一
个。
2.3.1创建ReceiverDispatcher
ReceiverDispatcher(BroadcastReceiverreceiver,Contextcontext,Handler
activityThread,Instrumentationinstrumentation,booleanregistered){//创建
InnerReceiver【2.3.2】mIIntentReceiver=newInnerReceiver(this,!
registered);
mReceiver=receiver;
mContext=context;
mActivityThread=activityThread;
mInstrumentation=instrumentation;
mRegistered=registered;
mLocation=new
IntentReceiverLeaked(null);
mLocation.fillInStackTrace();
}2.3.2创建InnerReceiver
finalstaticclassInnerReceiverextendsIIntentReceiver.Stub{finalWeakReference
LoadedApk.ReceiverDispatchermDispatcher;
finalLoadedApk.ReceiverDispatcher
mStrongRef;
InnerReceiver(LoadedApk.ReceiverDispatcherrd,booleanstrong){
mDispatcher=newWeakReferenceLoadedApk.ReceiverDispatcher(rd);
mStrongRef=
strong?
rd:
null;
}...}ReceiverDispatcher(广播分发者)有一个内部类InnerReceiver,
该类继承于IIntentReceiver.Stub。
显然,这是一个Binder服务端,广播分发者通过
rd.getIIntentReceiver()可获取该Binder服务端对象InnerReceiver,用于BinderIPC通
2.4AMP.registerReceiver[-ActivityManagerNative.java]
publicIntentregisterReceiver(IApplicationThreadcaller,StringpackageName,
IIntentReceiverreceiver,IntentFilterfilter,Stringperm,intuserId)throws
RemoteException{Parceldata=Parcel.obtain();
Parcelreply=Parcel.obtain();
data.writeIn