基于Android 6.0的源码剖析, 分析android广播的发送与接收流程。
一、概述
广播(Broadcast)机制用于进程/线程间通信,广播分为广播发送和广播接收两个过程,其中广播接收者BroadcastReceiver便是Android四大组件之一。
BroadcastReceiver分为两类:
- 静态广播接收者:通过AndroidManifest.xml的标签来申明的BroadcastReceiver。
- 动态广播接收者:通过AMS.registerReceiver()方式注册的BroadcastReceiver,动态注册更为灵活,可在不需要时通过unregisterReceiver()取消注册。
从广播发送方式可分为三类:
- 普通广播:通过Context.sendBroadcast()发送,可并行处理
- 有序广播:通过Context.sendOrderedBroadcast()发送,串行处理
- Sticky广播:通过Context.sendStickyBroadcast()发送
二、注册广播
2.1 registerReceiver
广播注册,对于应用开发来说,往往是在Activity/Service中调用registerReceiver()
方法,而Activity/Service都间接继承于Context抽象类,真正干活是交给ContextImpl类。另外调用getOuterContext()可获取最外层的调用者Activity/Service。
[ContextImpl.java]
1 2 3 4 5 6 7 8 9 10 11 12 |
@Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { return registerReceiver(receiver, filter, null, null); } @Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) { //【见小节2.2】 return registerReceiverInternal(receiver, getUserId(), filter, broadcastPermission, scheduler, getOuterContext()); } |
当执行两参数的registerReceiver
方法,增加两个broadcastPermission=null和scheduler=null调用四参数的注册方法。其中broadcastPermission拥有广播的权限控制,scheduler用于指定接收到广播时onRecive执行线程,当scheduler=null则默认代表在主线程中执行,这也是最常见的用法。 再然后调用6参数的registerReceiverInternal
。
2.2 registerReceiverInternal
[ContextImpl.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId, IntentFilter filter, String broadcastPermission, Handler scheduler, Context context) { IIntentReceiver rd = null; if (receiver != null) { if (mPackageInfo != null && context != null) { if (scheduler == null) { //将主线程Handler赋予scheuler scheduler = mMainThread.getHandler(); } //获取IIntentReceiver对象【2.3】 rd = mPackageInfo.getReceiverDispatcher( receiver, context, scheduler, mMainThread.getInstrumentation(), true); } else { if (scheduler == null) { scheduler = mMainThread.getHandler(); } rd = new LoadedApk.ReceiverDispatcher( receiver, context, scheduler, null, true).getIIntentReceiver(); } } try { //调用AMP.registerReceiver 【2.4】 return ActivityManagerNative.getDefault().registerReceiver( mMainThread.getApplicationThread(), mBasePackageName, rd, filter, broadcastPermission, userId); } catch (RemoteException e) { return null; } } |
ActivityManagerNative.getDefault()返回的是ActivityManagerProxy对象,简称AMP,该方法中参数有mMainThread.getApplicationThread()返回的是ApplicationThread,这是Binder的Bn端,用于system_server进程与该进程的通信。
2.3 LoadedApk.getReceiverDispatcher
[-> LoadedApk.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 num" data-line="crayon-5812848bcbc62765587306-23">23 24 25 26 27 |