Android筑基——BroadcastReceiver 的动态注册、发送和接收过程(基于api21)
目录
- 1. 前言
- 2. 正文
- 2.1 广播接收者的动态注册
- 2.2 发送普通广播
- 2.3 接收普通广播
- 2.3.1 BroadcastQueue.scheduleBroadcastsLocked() 方法
- 2.3.2 BroadcastHandler.handleMessage() 方法
- 2.3.3 BroadcastQueue.processNextBroadcast() 方法
- 2.3.4 BroadcastQueue.deliverToRegisteredReceiverLocked() 方法
- 2.3.5 BroadcastQueue.performReceiveLocked() 方法
- 2.3.6 ApplicationThreadProxy.scheduleRegisteredReceiver() 方法
- 2.3.7 ApplicationThreadNative.onTransact() 方法
- 2.3.8 ApplicationThread.scheduleRegisteredReceiver() 方法
- 2.3.9 InnerReceiver.performReceive() 方法
- 2.3.10 ReceiverDispatcher.performReceive() 方法
- 2.3.11 Args.run() 方法
- 2.3.12 MyDynamicReceiver.onReceive() 方法
- 3.最后
- 4. 参考
1. 前言
BroadcastReceiver
的工作过程主要包括两个方面的内容:
- 广播接收者的注册过程(静态注册和动态注册);
- 广播的发送(包括发送普通广播、有序广播和粘性广播)和接收过程。
本文主要分析广播接收者的动态注册,普通广播的发送和接收过程。
2. 正文
首先,看一下我们要分析的代码:
-
定义广播接收者,继承
BroadcastReceiver
抽象类并重写它的onReceive()
方法:public class MyDynamicReceiver extends BroadcastReceiver { private static final String TAG = "MyDynamicReceiver"; public static final String ACTION_LAUNCH_DYNAMIC = "com.wzc.receiver.LAUNCH_DYNAMIC"; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.d(TAG, "onReceive: receive action = " + action); if (ACTION_LAUNCH_DYNAMIC.equals(action)) { Log.d(TAG, "onReceive: do launch work..."); } } }
-
点击按钮动态注册以及动态注销广播接收者
private MyDynamicReceiver receiver; // 动态注册广播接收者 public void registerReceiver(View view) { if (null == receiver) { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(ACTION_LAUNCH_DYNAMIC); receiver = new MyDynamicReceiver(); registerReceiver(receiver, intentFilter); } } // 动态注销广播接收者 public void unregisterReceiver(View view) { if (null != receiver) { unregisterReceiver(receiver); receiver = null; } }
-
点击按钮发送广播
public void sendBroadcast(View view) { Intent intent = new Intent(); intent.setAction(ACTION_LAUNCH_DYNAMIC); sendBroadcast(intent); }
先点击动态注册广播接收者按钮,再点击发送广播按钮,查看日志如下:
D/MyDynamicReceiver: onReceive: receive action = com.wzc.receiver.LAUNCH_DYNAMIC
D/MyDynamicReceiver: onReceive: do launch work...
如果不对广播接收者进行动态注册,直接点击发送广播按钮,是看不到 onReceive
方法里的日志的。
现在我们开始查看相关的源码吧。
2.1 广播接收者的动态注册
2.1.1 ContextWrapper.registerReceiver() 方法
- BroadcastReceiver receiver, MyDynamicReceiver 对象
- IntentFilter filter, 添加了 action 的 IntentFilter 对象
@Override
public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter) {
return mBase.registerReceiver(receiver, filter);
}
这里的 ContextWrapper
其实是装饰器设计模式的应用了,类结构图如下所示:
调用装饰类 ContextWrapper
的 registerReceiver
方法,内部真正调用的是核心实现类 ContextImpl
的 registerReceiver
方法。所以 mBase
实际上是一个 ContextImpl
类型的对象。
2.1.2 ContextImpl.registerReceiver() 方法
- BroadcastReceiver receiver, MyDynamicReceiver 对象
- IntentFilter filter, 添加了 action 的 IntentFilter 对象
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return registerReceiver(receiver, filter, null, null);
}
内部调用重载的 registerReceiver
方法
- BroadcastReceiver receiver, MyDynamicReceiver 对象
- IntentFilter filter, 添加了 action 的 IntentFilter 对象
- String broadcastPermission, null
- Handler scheduler, null
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
return registerReceiverInternal(receiver, getUserId(),
filter, broadcastPermission, scheduler, getOuterContext());
}
这里的 getOuterContext()
方法获取的是 mOuterContext
对象,是通过 setOuterContext
方法赋值的。
我们这里的 ContextImpl
对象是在创建 MainActivity
的时候被初始化的,具体来说是在 ActivityThread
的 performLaunchActivity
方法:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
Activity activity = null;
...
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
// 创建 Activity 对象
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
// 创建 ContextImpl 对象
Context appContext = createBaseContextForActivity(r, activity);
// 把 ContextImpl 对象和 Activity 对象相关联
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.voiceInteractor);
}
return activity;
}
在 createBaseContextForActivity
方法中,调用 setOuterContext
方法把 activity
对象赋值给 ContextImpl
对象。
private Context createBaseContextForActivity(ActivityClientRecord r,
final Activity activity) {
ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);
appContext.setOuterContext(activity);
Context baseContext = appContext;
...
return baseContext;
}
所以,getOuterContext()
方法获取的就是 MainActivity
对象。
2.1.3 ContextImpl.registerReceiverInternal() 方法
- BroadcastReceiver receiver, MyDynamicReceiver 对象
- int userId, 通过 UserHandle 对象的 getIdentifier() 方法获得
- IntentFilter filter, 添加了 action 的 IntentFilter 对象
- String broadcastPermission, null
- Handler scheduler, null
- Context context, MainActivity 对象
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context) {
IIntentReceiver rd = null;
if (receiver != null) { // 进入此分支
// mPackageInfo 是 LoadedApk 对象,是在创建 ContextImpl 的时候赋值的,不为 null
// context 是 MainActivity 对象,不为 null
if (mPackageInfo != null && context != null) { // 进入此分支
if (scheduler == null) { // 进入此分支,对 scheduler 进行赋值
// mMainThread 是 ActivityThread 对象,通过 getHandler() 方法获取的是它的 H mH 对象。
scheduler = mMainThread.getHandler();
}
// 获取 InnerReceiver 对象,见[2.1.3.1]
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else { // 不会进入这里
...
}
}
try {
// 调用到这里,通过 AMP 经过 binder 驱动,向 AMS 发起远程调用。
// ActivityManagerNative.getDefault() 见[2.1.3.3]
return ActivityManagerNative.getDefault().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName,
rd, filter, broadcastPermission, userId);
} catch (RemoteException e) {
return null;
}
}
在这里思考一下,为什么我们不直接把 BroadcastReceiver
对象传递给 AMS,而是把通过 getReceiverDispatcher()
方法获取的 InnerReceiver
对象传递给 AMS?
这是因为 BroadcastReceiver
仅仅是一个普通的 java 类而已:
public abstract class BroadcastReceiver {
public abstract void onReceive(Context context, Intent intent);
}
而广播接收者的注册过程是一个进程间通信的过程, BroadcastReceiver
作为一个普通的 java 类,不具备跨进程通信的能力,所以 Android 封装了具有跨进程传输能力的 InnerReciver
来完成 BroadcastReceiver
不能完成的工作。
当 InnerReciver
接收到广播时,会再调用到 BroadcastReceiver
的 onReceive()
方法,也就是说,InnerReciver
起到了一个中转作用。
2.1.3.1 LoadedApk.getReceiverDispatcher() 方法
- BroadcastReceiver r, MyDynamicReceiver 对象
- Context context, MainActivity 对象
- Handler handler, ActivityThread 里的 mH 对象
- Instrumentation instrumentation, Instrumentation 对象,是在 ActivityThread 的 handleBindApplication 方法中创建的
- boolean registered, true
public final class LoadedApk {
// mReceivers 是一个 ArrayMap 集合,以 Context 为键,以 ArrayMap<BroadcastReceiver, ReceiverDispatcher> 为值
// 其中值又是一个 ArrayMap 集合,以 BroadcastReceiver 为键,以 ReceiverDispatcher 为值
private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
= new ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();
public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
Context context, Handler handler,
Instrumentation instrumentation, boolean registered) {
synchronized (mReceivers) {
// 获取一个 ReceiverDispatcher 对象
LoadedApk.ReceiverDispatcher rd = null;
ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
if (registered) { // registered 为 true,进入此分支
// 根据 context 对象,从 mReceivers 里面取出 map 对象
map = mReceivers.get(context);
if (map != null) {
// 如果 map 不为 null,再根据 r 对象,取出 ReceiverDispatcher rd 对象
rd = map.get(r);
}
}
if (rd == null) {
// 创建 ReceiverDispatcher 对象,见[2.1.3.2]
rd = new ReceiverDispatcher(r, context, handler,
instrumentation, registered);
if (registered) { // 进入此分支
// 把 rd 存到 mReceivers 这个数据结构中
if (map == null) {
map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
mReceivers.put(context, map);
}
map.put(r, rd);
}
} else {
rd.validate(context, handler);
}
rd.mForgotten = false;
// 通过 ReceiverDispatcher 对象,获取 InnerReceiver 对象。
return rd.getIIntentReceiver();
}
}
}
2.1.3.2 new LoadedApk.ReceiverDispatcher() 方法
- BroadcastReceiver r, MyDynamicReceiver 对象
- Context context, MainActivity 对象
- Handler activityThread, ActivityThread 里的 mH 对象
- Instrumentation instrumentation, Instrumentation 对象,是在 ActivityThread 的 handleBindApplication 方法中创建的
- boolean registered, true
public final class LoadedApk {
static final class ReceiverDispatcher {
final static class InnerReceiver extends IIntentReceiver.Stub {
final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
final LoadedApk.ReceiverDispatcher mStrongRef;
InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
mStrongRef = strong ? rd : null;
}
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
LoadedApk.ReceiverDispatcher rd = mDispatcher.get();
if (rd != null) {
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
}
...
}
}
final IIntentReceiver.Stub mIIntentReceiver;
final BroadcastReceiver mReceiver;
final Context mContext;
final Handler mActivityThread;
final Instrumentation mInstrumentation;
final boolean mRegistered;
boolean mForgotten;
final class Args extends BroadcastReceiver.PendingResult implements Runnable {
private Intent mCurIntent;
private final boolean mOrdered;
public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
boolean ordered, boolean sticky, int sendingUser) {
super(resultCode, resultData, resultExtras,
mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED,
ordered, sticky, mIIntentReceiver.asBinder(), sendingUser);
mCurIntent = intent;
mOrdered = ordered;
}
public void run() {
final BroadcastReceiver receiver = mReceiver;
final boolean ordered = mOrdered;
final IActivityManager mgr = ActivityManagerNative.getDefault();
final Intent intent = mCurIntent;
mCurIntent = null;
if (receiver == null || mForgotten) {
if (mRegistered && ordered) {
sendFinished(mgr);
}
return;
}
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
receiver.onReceive(mContext, intent);
if (receiver.getPendingResult() != null) {
finish();
}
}
}
ReceiverDispatcher(BroadcastReceiver receiver, Context context,
Handler activityThread, Instrumentation instrumentation,
boolean registered) {
mIIntentReceiver = new InnerReceiver(this, !registered);
mReceiver = receiver;
mContext = context;
mActivityThread = activityThread;
mInstrumentation = instrumentation;
mRegistered = registered;
}
IIntentReceiver getIIntentReceiver() {
return mIIntentReceiver;
}
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Args args = new Args(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
if (!mActivityThread.post(args)) {
...
}
}
}
}
IIntentReceiver.aidl
文件如下:
oneway interface IIntentReceiver {
void performReceive(in Intent intent, int resultCode, String data,
in Bundle extras, boolean ordered, boolean sticky, int sendingUser);
}
类结构图如下:
从类结构图可以看到,
LoadedApk.ReceiverDispatcher
分别持有InnerReceiver
对象 和BroadcastReceiver
对象,这样LoadedApk.ReceiverDispatcher
可以获取到BroadcastReceiver
对象;InnerReceiver
通过弱引用持有LoadedApk.ReceiverDispatcher
对象,所以InnerReceiver
可以找到LoadedApk.ReceiverDispatcher
对象;InnerReceiver
可以获取LoadedApk.ReceiverDispatcher
对象,且LoadedApk.ReceiverDispatcher
可以获取到BroadcastReceiver
对象,因此InnerReceiver
可以通过LoadedApk.ReceiverDispatcher
获取BroadcastReceiver
对象(这样我们可以说LoadedApk.ReceiverDispatcher
起到了连接InnerReceiver
和BroadcastReceiver
的作用);InnerReceiver
是一个继承于IIntentReceiver.Stub
的类,所以它是一个 binder 通信的服务端类。
2.1.3.3 ActivityManagerNative.getDefault() 方法
// ActivityManagerNative 类:
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
IActivityManager am = asInterface(b);
return am;
}
};
// 因为这里客户端和服务端不处于同一个进程,所以这个方法返回的是 ActivityManagerProxy 对象。
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
public abstract class Singleton<T> {
private T mInstance;
protected abstract T create();
public final T get() {
synchronized (this) {
if (mInstance == null) {
mInstance = create();
}
return mInstance;
}
}
}
这里采用的是局部单例技术,保证获取到的 IActivityManager
对象总是一个对象,实际上是 ActivityManagerProxy
对象。
2.1.4 ActivityManagerProxy.registerReceiver() 方法
- IApplicationThread caller, ApplicationThread 对象,作为 binder 服务端,用于 AMS 进程向客户端进程发起通信
- String packageName, 包名,即 “com.wzc.chapter_9”
- IIntentReceiver receiver, InnerReceiver 对象
- IntentFilter filter, 添加了 action 的 IntentFilter 对象
- String perm, null
- int userId, 通过 UserHandle 对象的 getIdentifier() 方法获得
class ActivityManagerProxy implements IActivityManager
{
public Intent registerReceiver(IApplicationThread caller, String packageName,
IIntentReceiver receiver,
IntentFilter filter, String perm, int userId) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeString(packageName);
data.writeStrongBinder(receiver != null ? receiver.asBinder() : null);
filter.writeToParcel(data, 0);
data.writeString(perm);
data.writeInt(userId);
mRemote.transact(REGISTER_RECEIVER_TRANSACTION, data, reply, 0);
reply.readException();
Intent intent = null;
int haveIntent = reply.readInt();
if (haveIntent != 0) {
intent = Intent.CREATOR.createFromParcel(reply);
}
reply.recycle();
data.recycle();
return intent;
}
}
这个方法仍是在客户端进程调用的。
mRemote.transact()
是客户端进程发起 binder 通信的方法,经过 binder 驱动,最后会到 binder 服务端 ActivityManagerNative
的 onTransact()
方法。
2.1.5 ActivityManagerNative.onTransact() 方法
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
...
case REGISTER_RECEIVER_TRANSACTION:
{
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
// 这里获取的是 ApplicationThreadProxy 对象,是 binder 客户端对象。
IApplicationThread app =
b != null ? ApplicationThreadNative.asInterface(b) : null;
String packageName = data.readString();
b = data.readStrongBinder();
// 这里获取的是 IIntentReceiver.Stub.Proxy 对象,是 binder 客户端对象。
IIntentReceiver rec
= b != null ? IIntentReceiver.Stub.asInterface(b) : null;
IntentFilter filter = IntentFilter.CREATOR.createFromParcel(data);
String perm = data.readString();
int userId = data.readInt();
// 调用到这里,进入 AMS,见[2.1.6]
Intent intent = registerReceiver(app, packageName, rec, filter, perm, userId);
reply.writeNoException();
if (intent != null) {
reply.writeInt(1);
intent.writeToParcel(reply, 0);
} else {
reply.writeInt(0);
}
return true;
}
}
}
ActivityManagerNative
是抽象类,registerReceiver()
是它的一个抽象方法。
ActivityManagerService
继承了 ActivityManagerNative
,实现了 registerReceiver()
这个抽象方法。
2.1.6 ActivityManagerService.registerReceiver() 方法
- IApplicationThread caller, ApplicationThreadProxy对象,作为 binder 客户端
- String packageName, 包名,即 “com.wzc.chapter_9”
- IIntentReceiver receiver, InnerReceiver.Stub.Proxy对象
- IntentFilter filter, 添加了 action 的 IntentFilter 对象
- String perm, null
- int userId, 通过 UserHandle 对象的 getIdentifier() 方法获得
// mRegisteredReceivers 用于记录所有已经被注册给广播的 IIntentReceiver
// 键为 InnerReceiver.Stub.Proxy 对应的 BinderProxy 对象
// 值为 ReceiverList 对象
final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
new HashMap<IBinder, ReceiverList>();
final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
= new IntentResolver<BroadcastFilter, BroadcastFilter>() {}
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
int callingUid;
int callingPid;
synchronized(this) {
ProcessRecord callerApp = null;
if (caller != null) { // 进入此分支
// 获取发起方的进程记录对象
callerApp = getRecordForAppLocked(caller);
if (callerApp == null) { // 不为 null
throw new SecurityException();
}
// 本次分析 callerApp.pkgList.containsKey(callerPackage) 为 true,所以不会进入此分支。
if (callerApp.info.uid != Process.SYSTEM_UID &&
!callerApp.pkgList.containsKey(callerPackage) &&
!"android".equals(callerPackage)) {
throw new SecurityException();
}
callingUid = callerApp.info.uid;
callingPid = callerApp.pid;
} else { // 不会进入此分支
...
}
userId = this.handleIncomingUser(callingPid, callingUid, userId,
true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
List allSticky = null;
// Look for any matching sticky broadcasts...
Iterator actions = filter.actionsIterator();
if (actions != null) { // 进入此分支
while (actions.hasNext()) {
String action = (String)actions.next();
// 获取 sticky intent 的列表,本次分析没有 sticky intent,所以 allSticky 为 null。
allSticky = getStickiesLocked(action, filter, allSticky,
UserHandle.USER_ALL);
allSticky = getStickiesLocked(action, filter, allSticky,
UserHandle.getUserId(callingUid));
}
} else {
...
}
Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; // 返回 null
if (receiver == null) { // 不为 null
return sticky;
}
// 从 mRegisteredReceivers 获取对应 InnerReceiver.Stub.Proxy 对应的 BinderProxy 对象 的 ReceiverList 集合
// 因为我们是首次注册,所以这里获取到的 rl 是 null
ReceiverList rl
= (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) { // 进入此分支
// 创建一个 ReceiverList 对象。
rl = new ReceiverList(this, callerApp, callingPid, callingUid,
userId, receiver);
if (rl.app != null) { // r1.app 就是 callerApp,不为 null,进入此分支
rl.app.receivers.add(rl); // 把 rl 添加到 ProcessRecord 的 receivers 列表里面保存。
} else {
...
}
// 把新建的 rl 添加到 mRegisteredReceivers 集合里面保存。
mRegisteredReceivers.put(receiver.asBinder(), rl);
}
...
// 创建 BroadcastFilter 对象,BroadcastFilter 是 IntentFilter 的子类
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
permission, callingUid, userId);
// 保存在 rl 里面
rl.add(bf);
// BroadcastFilter 对象添加到 mReceiverResolver 里面。
mReceiverResolver.addFilter(bf);
if (allSticky != null) { // allSticky 为 null,不会进入此分支
...
}
return sticky;
}
}
该方法的作用:
- 创建
ReceiverList
对象,它封装了InnerReceiver.Stub.Proxy
对象,并保存在mRegisteredReceivers
集合里面; - 创建
BroadcastFilter
对象,封装了IntentFilter
对象,ReceiverList
对象,并保存在mReceiverResolver
和ReceiverList
集合对象里面。
类结构图如下:
这样,广播接收者的注册就完成了。
2.1.6.1 IntentResolver.addFilter()方法
- F f, BroadcastFilter 对象
public abstract class IntentResolver<F extends IntentFilter, R extends Object> {
// 以 BroadcastFilter 为元素的列表
private final HashSet<F> mFilters = new HashSet<F>();
// 以 action 为键,以 BroadcastFilter[] 为值的集合
private final ArrayMap<String, F[]> mActionToFilter = new ArrayMap<String, F[]>();
public void addFilter(F f) {
mFilters.add(f);
int numS = register_intent_filter(f, f.schemesIterator(),
mSchemeToFilter, " Scheme: "); // 没有设置 schema,所以返回 0
int numT = register_mime_types(f, " Type: "); // 没有设置 type,所以返回 0
if (numS == 0 && numT == 0) { // 进入此分支,把 F f 存放到 mActionToFilter 集合里面。
register_intent_filter(f, f.actionsIterator(),
mActionToFilter, " Action: ");
}
...
}
2.2 发送普通广播
2.2.1 ContextWrapper.sendBroadcast() 方法
- Intent intent, 添加了 action 的 Intent 对象
@Override
public void sendBroadcast(Intent intent) {
mBase.sendBroadcast(intent);
}
同 2.1.1, mBase
实际上是一个 ContextImpl
类型的对象。
2.2.2 ContextImpl.sendBroadcast() 方法
- Intent intent, 添加了 action 的 Intent 对象
@Override
public void sendBroadcast(Intent intent) {
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
intent.prepareToLeaveProcess();
// 调用到这里,见[2.2.3]
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, false,
getUserId());
} catch (RemoteException e) {
}
}
由 2.1.3.3,ActivityManagerNative.getDefault()
获取的是一个ActivityManagerProxy
对象。
2.2.3 ActivityManagerProxy.broadcastIntent() 方法
- IApplicationThread caller, ApplicationThread 对象,作为 binder 服务端,用于 AMS 进程向客户端进程发起通信
- Intent intent, 添加了 action 的 Intent 对象
- String resolvedType, 由 intent.resolveTypeIfNeeded 得到
- IIntentReceiver resultTo, null
- int resultCode, Activity.RESULT_OK,值为 -1
- String resultData, null
- Bundle map, null
- String requiredPermission, null
- int appOp, AppOpsManager.OP_NONE,值为 -1
- boolean serialized, false,表示不是有序广播
- boolean sticky, false,表示不是粘性广播
- int userId, mUser.getIdentifier() 得到
class ActivityManagerProxy implements IActivityManager
{
public int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle map,
String requiredPermission, int appOp, boolean serialized,
boolean sticky, int userId) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo != null ? resultTo.asBinder() : null);
data.writeInt(resultCode);
data.writeString(resultData);
data.writeBundle(map);
data.writeString(requiredPermission);
data.writeInt(appOp);
data.writeInt(serialized ? 1 : 0);
data.writeInt(sticky ? 1 : 0);
data.writeInt(userId);
// 调用到这里,见[2.2.4]
mRemote.transact(BROADCAST_INTENT_TRANSACTION, data, reply, 0);
reply.readException();
int res = reply.readInt();
reply.recycle();
data.recycle();
return res;
}
}
这个方法仍是在客户端进程调用的。
mRemote.transact()
是客户端进程发起 binder 通信的方法,经过 binder 驱动,最后会到 binder 服务端 ActivityManagerNative
的 onTransact()
方法。
2.2.4 ActivityManagerNative.onTransact() 方法
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
...
case BROADCAST_INTENT_TRANSACTION:
{
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
// 这里获取的是 ApplicationThreadProxy 对象,是 binder 客户端对象。
IApplicationThread app =
b != null ? ApplicationThreadNative.asInterface(b) : null;
Intent intent = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
b = data.readStrongBinder();
// 这里 resultTo 为 null,因为 b 为 null。
IIntentReceiver resultTo =
b != null ? IIntentReceiver.Stub.asInterface(b) : null;
int resultCode = data.readInt();
String resultData = data.readString();
Bundle resultExtras = data.readBundle();
String perm = data.readString();
int appOp = data.readInt();
boolean serialized = data.readInt() != 0;
boolean sticky = data.readInt() != 0;
int userId = data.readInt();
// 调用到这里,见[2.2.5]
int res = broadcastIntent(app, intent, resolvedType, resultTo,
resultCode, resultData, resultExtras, perm, appOp,
serialized, sticky, userId);
reply.writeNoException();
reply.writeInt(res);
return true;
}
}
}
这里已经在 system_server 进程了。
2.2.5 ActivityManagerService.broadcastIntent() 方法
- IApplicationThread caller, ApplicationThreadProxy 对象,作为 binder 客户端
- Intent intent, 添加了 action 的 Intent 对象
- String resolvedType, 由 intent.resolveTypeIfNeeded 得到
- IIntentReceiver resultTo, null
- int resultCode, Activity.RESULT_OK,值为 -1
- String resultData, null
- Bundle map, null
- String requiredPermission, null
- int appOp, AppOpsManager.OP_NONE,值为 -1
- boolean serialized, false,表示不是有序广播
- boolean sticky, false,表示不是粘性广播
- int userId, mUser.getIdentifier() 得到
public final int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle map,
String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
synchronized(this) {
intent = verifyBroadcastLocked(intent);
// 获取发起方的进程记录对象
final ProcessRecord callerApp = getRecordForAppLocked(caller);
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
int res = broadcastIntentLocked(callerApp,
callerApp != null ? callerApp.info.packageName : null,
intent, resolvedType, resultTo,
resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
callingPid, callingUid, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
2.2.6 ActivityManagerService.broadcastIntentLocked() 方法
- ProcessRecord callerApp, 发起方的进程记录对象
- String callerPackage, 发起方的包名
- Intent intent, 添加了 action 的 Intent 对象
- String resolvedType, 由 intent.resolveTypeIfNeeded 得到,为 null
- IIntentReceiver resultTo, null
- int resultCode, Activity.RESULT_OK,值为 -1
- String resultData, null
- Bundle map, null
- String requiredPermission, null
- int appOp, AppOpsManager.OP_NONE,值为 -1
- boolean ordered, false,表示不是有序广播
- boolean sticky, false,表示不是粘性广播
- int callingPid,
- int callingUid,
- int userId, mUser.getIdentifier() 得到,值为 0
// 记录处于开启状态的 user
final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
= new IntentResolver<BroadcastFilter, BroadcastFilter>() {...};
private final int broadcastIntentLocked(ProcessRecord callerApp,
String callerPackage, Intent intent, String resolvedType,
IIntentReceiver resultTo, int resultCode, String resultData,
Bundle map, String requiredPermission, int appOp,
boolean ordered, boolean sticky, int callingPid, int callingUid,
int userId) {
// ====> 1,设置广播 flag
intent = new Intent(intent);
// Intent.FLAG_EXCLUDE_STOPPED_PACKAGES 用来控制广播不对停止状态的应用起作用
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
userId = handleIncomingUser(callingPid, callingUid, userId,
true, ALLOW_NON_FULL, "broadcast", callerPackage);
// 确保正在接收广播的用户已经开启了;否则,跳过本次广播发送。
// 本次分析不会进入此分支。
if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
& Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
return ActivityManager.BROADCAST_SUCCESS;
}
}
// ====> 2,广播权限的验证
// 阻止非系统代码去发送受保护的广播。
int callingAppId = UserHandle.getAppId(callingUid);
if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
|| callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
|| callingAppId == Process.NFC_UID || callingUid == 0) {
// Always okay.
} else if (callerApp == null || !callerApp.persistent) { // callerApp.persistent 为 false,进入此分支
try {
if (AppGlobals.getPackageManager().isProtectedBroadcast(
intent.getAction())) { // 判断 action 是不是受保护的,本次不会进入此分支
throw new SecurityException(msg);
} else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { // 不会进入此分支
...
}
} catch (RemoteException e) {
return ActivityManager.BROADCAST_SUCCESS;
}
}
// ====> 3,处理系统相关广播
// 处理特殊广播,如包移除广播
final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
intent.getAction());
if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
|| Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
|| Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
|| Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
|| uidRemoved) { // 本次分析没有移除包,不会进入此分支
...
// 本次分析没有安装包,不会进入此分支
} else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
...
}
// 本次分析没有时区改变,不会进入此分支
if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
}
// 如果是时间改变广播,通知所有运行的进程,本次分析不会进入此分支。
if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
...
}
if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
}
if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
}
// ====> 4,是 sticky 广播,就添加 sticky 广播
if (sticky) { // sticky 为 false,不会进入此分支
...
}
int[] users;
if (userId == UserHandle.USER_ALL) {
users = mStartedUserArray;
} else { // 我们不考虑多用户,进入此分支
users = new int[] {userId};
}
// ====> 5,查询 receivers 和 registeredReceivers
List receivers = null;
List<BroadcastFilter> registeredReceivers = null;
// Intent.FLAG_RECEIVER_REGISTERED_ONLY 表示仅仅动态注册的广播接收者才会被调用
if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
== 0) { // 成立,进入此分支
// 收集静态注册的广播接收者,返回的是 List<ResolveInfo>,见[2.2.6.1]
receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
}
if (intent.getComponent() == null) { // 进入此分支
if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
...
} else { // 进入此分支
// 收集动态注册的广播接收者,见[2.2.6.2]
registeredReceivers = mReceiverResolver.queryIntent(intent,
resolvedType, false, userId);
}
}
final boolean replacePending = // 没有设置此 flag,所以返回 false。
(intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
// ====> 6. 处理并行广播
if (!ordered && NR > 0) { // 进入此分支
// 获取到的是 BroadcastQueue mBgBroadcastQueue,它是在 AMS 构造方法中初始化的。
final BroadcastQueue queue = broadcastQueueForIntent(intent);
// 创建 BroadcastRecord 对象,见[2.2.6.4]
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
appOp, registeredReceivers, resultTo, resultCode, resultData, map,
ordered, sticky, false, userId);
final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); // false
if (!replaced) { // 进入此分支
// 将 BroadcastRecord 对象添加到并行广播队列,见[2.2.6.5 ]
queue.enqueueParallelBroadcastLocked(r);
// 处理广播,见[2.3.1]
queue.scheduleBroadcastsLocked();
}
registeredReceivers = null;
NR = 0;
}
// Merge into one list.
int ir = 0;
if (receivers != null) { // receivers 为 null,不会进入此分支
...
}
while (ir < NR) { // ir = 0,NR = 0,不会进入此循环
...
}
if ((receivers != null && receivers.size() > 0)
|| resultTo != null) { // receivers 为 null,且 resultTo 为 null,不会进入此分支
...
}
return ActivityManager.BROADCAST_SUCCESS;
}
该方法的作用:
- 设置广播 flag;
- 广播权限的验证;
- 处理系统相关广播;
- 是 sticky 广播,就添加 sticky 广播;
- 查询 receivers 和 registeredReceivers;
在 2.1.6 中,通过mReceiverResolver.addFilter(bf);
添加了BroadcastFiilter
对象,这里通过mReceiverResolver.queryIntent
获取之前添加的BroadcastFiilter
对象列表,赋值给registeredReceivers
。 - 处理并行广播。
需要再次说明的是,我们本次分析的场景是发送普通广播,所以不用关心有序广播和粘性广播的情况。我们有意限定了分析的范围,这样才不会迷失在源码里面。
2.2.6.1 ActivityManagerService.collectReceiverComponents() 方法
- Intent intent, 添加了 action 的 Intent 对象
- String resolvedType, 由 intent.resolveTypeIfNeeded 得到,为 null
- int callingUid,
- int[] users, 只包含了当前的用户id的数组,这里的用户id的值是0
private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
int callingUid, int[] users) {
List<ResolveInfo> receivers = null;
try {
HashSet<ComponentName> singleUserReceivers = null;
boolean scannedFirstReceivers = false;
for (int user : users) { // users 里只有一个元素,所以只会循环一次。
...
// 解析清单文件中静态注册的 receiver,返回可能为 null。
List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
.queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
if (user != 0 && newReceivers != null) { // user 为 0,不会进入此分支
...
}
if (newReceivers != null && newReceivers.size() == 0) { // 不会进入此分支
newReceivers = null;
}
if (receivers == null) { // 进入此分支
receivers = newReceivers;
} else if (newReceivers != null) { // 走第一个 if 了,不会再进入 else if
...
}
}
} catch (RemoteException ex) {
}
return receivers;
}
该方法的作用:收集静态注册的广播接收者,返回的是 List<ResolveInfo>
。
本次分析没有静态注册广播接收者,所以这个方法会返回 null
。
2.2.6.2 IntentResolver.queryIntent() 方法
- Intent intent, 添加了 action 的 Intent 对象
- String resolvedType, null
- boolean defaultOnly, false
- int userId, 0
public abstract class IntentResolver<F extends IntentFilter, R extends Object> {
// 以 action 为键,以 BroadcastFilter[] 为值的集合
private final ArrayMap<String, F[]> mActionToFilter = new ArrayMap<String, F[]>();
public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly,
int userId) {
String scheme = intent.getScheme(); // 返回 null
ArrayList<R> finalList = new ArrayList<R>();
F[] firstTypeCut = null;
F[] secondTypeCut = null;
F[] thirdTypeCut = null;
F[] schemeCut = null;
if (resolvedType != null) { // resolvedType 为 null,不会进入此分支
...
}
if (scheme != null) { // scheme 为 null,不会进入此分支
...
}
if (resolvedType == null && scheme == null && intent.getAction() != null) {
firstTypeCut = mActionToFilter.get(intent.getAction());
}
FastImmutableArraySet<String> categories = getFastIntentCategories(intent); // 返回 null
if (firstTypeCut != null) {
// 见[2.2.6.3]
buildResolveList(intent, categories, debug, defaultOnly,
resolvedType, scheme, firstTypeCut, finalList, userId);
}
if (secondTypeCut != null) { // 进不去
...
}
if (thirdTypeCut != null) { // 进不去
...
}
if (schemeCut != null) { // 进不去
...
}
sortResults(finalList);
return finalList;
}
}
该方法的作用:从 mActionToFilter
获取 BroadcastFiilter
对象列表。
2.2.6.3 IntentResolver.buildResolveList() 方法
- Intent intent, 添加了 action 的 Intent 对象
- FastImmutableArraySet categories, null
- boolean debug, false
- boolean defaultOnly, false
- String resolvedType, null
- String scheme, null
- F[] src, BroadcastFilter[] 对象
- List dest, 容器参数 List 对象
- int userId, 0
public abstract class IntentResolver<F extends IntentFilter, R extends Object> {
// 以 action 为键,以 BroadcastFilter[] 为值的集合
private final ArrayMap<String, F[]> mActionToFilter = new ArrayMap<String, F[]>();
private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories,
boolean debug, boolean defaultOnly,
String resolvedType, String scheme, F[] src, List<R> dest, int userId) {
final String action = intent.getAction(); // "com.wzc.receiver.LAUNCH_DYNAMIC"
final Uri data = intent.getData(); // null
final String packageName = intent.getPackage(); // null
final boolean excludingStopped = intent.isExcludingStopped(); // true
final Printer logPrinter;
final PrintWriter logPrintWriter;
final int N = src != null ? src.length : 0;
boolean hasNonDefaults = false;
int i;
F filter;
for (i=0; i<N && (filter=src[i]) != null; i++) {
int match;
if (excludingStopped && isFilterStopped(filter, userId)) {
continue;
}
if (packageName != null && !isPackageForFilter(packageName, filter)) {
continue;
}
match = filter.match(action, resolvedType, scheme, data, categories, TAG);
if (match >= 0) {
if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) {
final R oneResult = newResult(filter, match, userId);
if (oneResult != null) {
dest.add(oneResult);
}
} else {
hasNonDefaults = true;
}
} else {
...
}
}
}
}
该方法的作用是:对 BroadcastFilter
对象数组进行一些过滤,通过容器参数返回符合条件的 BroadcastFilter
对象。
2.2.6.4 new BroadcastRecord() 方法
final class BroadcastRecord extends Binder {
final Intent intent; // 产生广播的原始 Intent
final ComponentName targetComp; // 设置在 Intent 上的原始的组件名对象
final ProcessRecord callerApp; // 发送广播的进程
final String callerPackage; // 发送方的包名
final int callingPid; // 发起方的pid
final int callingUid; // 发起方的uid
final boolean ordered; // 是否是有序广播
final boolean sticky; // 是否是粘性广播
final boolean initialSticky;
final int userId;
final String resolvedType; // mime type
final String requiredPermission; // 广播权限
final int appOp;
final List receivers; // 广播接收器,包括动态注册(BroadcastFilter)和静态注册(ResolveInfo)
IIntentReceiver resultTo; // null
long dispatchTime; // 广播分发时间点
long dispatchClockTime; // the clock time the dispatch started
long receiverTime; // 当前 receiver 开始处理时间点
long finishTime; // 广播处理完成时间点.
int resultCode; // current result code value.
String resultData; // current result data value.
Bundle resultExtras; // current result extra data values.
boolean resultAbort; // current result abortBroadcast value.
int nextReceiver; // next receiver to be executed.
IBinder receiver; // who is currently running, null if none.
int state;
int anrCount; // has this broadcast record hit any ANRs?
BroadcastQueue queue; // 处理广播的队列
static final int IDLE = 0;
static final int APP_RECEIVE = 1;
static final int CALL_IN_RECEIVE = 2;
static final int CALL_DONE_RECEIVE = 3;
static final int WAITING_SERVICES = 4;
BroadcastFilter curFilter;
ProcessRecord curApp; // hosting application of current receiver.
ComponentName curComponent; // the receiver class that is currently running.
ActivityInfo curReceiver; // info about the receiver that is currently running.
BroadcastRecord(BroadcastQueue _queue,
Intent _intent, ProcessRecord _callerApp, String _callerPackage,
int _callingPid, int _callingUid, String _resolvedType, String _requiredPermission,
int _appOp, List _receivers, IIntentReceiver _resultTo, int _resultCode,
String _resultData, Bundle _resultExtras, boolean _serialized,
boolean _sticky, boolean _initialSticky,
int _userId) {
queue = _queue;
intent = _intent;
targetComp = _intent.getComponent();
callerApp = _callerApp;
callerPackage = _callerPackage;
callingPid = _callingPid;
callingUid = _callingUid;
resolvedType = _resolvedType;
requiredPermission = _requiredPermission;
appOp = _appOp;
receivers = _receivers;
resultTo = _resultTo;
resultCode = _resultCode;
resultData = _resultData;
resultExtras = _resultExtras;
ordered = _serialized;
sticky = _sticky;
initialSticky = _initialSticky;
userId = _userId;
nextReceiver = 0;
state = IDLE;
}
}
可以看到,BroadcastRecord
是继承于 Binder
类的。
2.2.6.5 BroadcastQueue.enqueueParallelBroadcastLocked() 方法
public final class BroadcastQueue {
final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<BroadcastRecord>();
public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
mParallelBroadcasts.add(r);
}
}
该方法的作用:把 BroadcastRecord r
对象添加到 mParallelBroadcasts
列表而已。
2.3 接收普通广播
2.3.1 BroadcastQueue.scheduleBroadcastsLocked() 方法
public final class BroadcastQueue {
boolean mBroadcastsScheduled = false;
final BroadcastHandler mHandler;
BroadcastQueue(ActivityManagerService service, Handler handler,
String name, long timeoutPeriod, boolean allowDelayBehindServices) {
mService = service;
mHandler = new BroadcastHandler(handler.getLooper());
...
}
public void scheduleBroadcastsLocked() {
if (mBroadcastsScheduled) {
return;
}
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
}
该方法的作用是:通过 mHandler
发送一个 what
为 BROADCAST_INTENT_MSG
,object
为 BroadcastQueue
对象的消息。
mHandler
是在 BroadcastQueue
的构造方法中初始化的:mHandler = new BroadcastHandler(handler.getLooper())
,需要特别说明的是,这里的 hanlder.getLooper()
是一个名字 "ActivityManager"
为子线程的 Looper
对象,因为这个 Looper
对象来自于 ActivityManagerService
的 mHandlerThread.getLooper()
。
public final class ActivityManagerService extends ActivityManagerNative {
static final String TAG = "ActivityManager";
final ServiceThread mHandlerThread;
final MainHandler mHandler;
BroadcastQueue mFgBroadcastQueue;
BroadcastQueue mBgBroadcastQueue;
public ActivityManagerService(Context systemContext) {
mContext = systemContext;
mSystemThread = ActivityThread.currentActivityThread();
mHandlerThread = new ServiceThread(TAG,
android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
"foreground", BROADCAST_FG_TIMEOUT, false);
mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
"background", BROADCAST_BG_TIMEOUT, true);
}
}
所以,发送消息是在 system_server 进程的主线程,接收消息的地方是在 system_server 进程的子线程里面了。
2.3.2 BroadcastHandler.handleMessage() 方法
private final class BroadcastHandler extends Handler {
public BroadcastHandler(Looper looper) {
super(looper, null, true);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BROADCAST_INTENT_MSG: {
// 见[2.3.3]
processNextBroadcast(true);
} break;
case BROADCAST_TIMEOUT_MSG: {
synchronized (mService) {
broadcastTimeoutLocked(true);
}
} break;
}
}
};
2.3.3 BroadcastQueue.processNextBroadcast() 方法
- boolean fromMsg, true
final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<BroadcastRecord>();
final void processNextBroadcast(boolean fromMsg) {
synchronized(mService) {
BroadcastRecord r;
if (fromMsg) {
// 重置 mBroadcastsScheduled 标记。
mBroadcastsScheduled = false;
}
// 首先,马上处理普通广播
while (mParallelBroadcasts.size() > 0) { // 存在并行广播
r = mParallelBroadcasts.remove(0);
r.dispatchTime = SystemClock.uptimeMillis();
r.dispatchClockTime = System.currentTimeMillis();
final int N = r.receivers.size();
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
// 调用到这里,见[2.3.4]
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
}
addBroadcastToHistoryLocked(r);
}
// 当正在等待一个进程被拉起来处理下一个广播,mPendingBroadcast 就不为 null。
// 本次分析不涉及跨进程,所以 mPendingBroadcast 为 null。
if (mPendingBroadcast != null) { // 本次分析不进入此分支
...
}
boolean looped = false;
do {
if (mOrderedBroadcasts.size() == 0) { // 本次分析没有有序广播,所以进入此分支。
mService.scheduleAppGcsLocked();
if (looped) {
mService.updateOomAdjLocked();
}
return; // 结束本方法了。
}
...
} while (r == null);
// ... 省略与本次分析无关的代码。
}
}
该方法的作用:取出广播队列中的元素,传递给注册的广播接收者。
2.3.4 BroadcastQueue.deliverToRegisteredReceiverLocked() 方法
- BroadcastRecord r, BroadcastRecord 对象
- BroadcastFilter filter, BroadcastFilter 对象,存储了广播接收者的信息
- boolean ordered, false,表示不是有序广播
private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
BroadcastFilter filter, boolean ordered) {
boolean skip = false;
if (filter.requiredPermission != null) { // 不进入此分支
...
}
if (!skip && r.requiredPermission != null) { // 不进入此分支
...
}
if (r.appOp != AppOpsManager.OP_NONE) { // 不进入此分支
...
}
if (!skip) {
skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
r.callingPid, r.resolvedType, filter.receiverList.uid);
}
if (filter.receiverList.app == null || filter.receiverList.app.crashing) {
skip = true;
}
if (!skip) {
...
try {
// 调用到这里,见[2.3.5]
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);
} catch (RemoteException e) {
}
}
}
该方法的作用:进行必要的权限验证,然后执行广播接收过程。
这里为了弄清楚 performReceiveLocked
方法的参数,我们再次查看一下类结构图:
2.3.5 BroadcastQueue.performReceiveLocked() 方法
- ProcessRecord app, filter.receiverList.app = 发起方的进程记录对象
- IIntentReceiver receiver, filter.receiverList.receiver = InnerReceiver.Stub.Proxy对象
- Intent intent, new Intent(r.intent) = 添加了 action 的 Intent 对象
- int resultCode, r.resultCode = Activity.RESULT_OK,值为 -1
- String data, r.resultData = null
- Bundle extras, r.resultExtras = null
- boolean ordered, r.ordered = false
- boolean sticky, r.initialSticky = false
- int sendingUser, r.userId = 0
private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
if (app != null) {
// app.thread 是 IApplicationThread 对象,实际上是 ApplicationThreadProxy 对象,是 binder 客户端对象。
if (app.thread != null) {
// 开始向 IApplicationThread binder 服务端对象发起请求服务,见[2.3.6]
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.repProcState);
} else {
...
}
} else {
...
}
}
2.3.6 ApplicationThreadProxy.scheduleRegisteredReceiver() 方法
class ApplicationThreadProxy implements IApplicationThread {
public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
int resultCode, String dataStr, Bundle extras, boolean ordered,
boolean sticky, int sendingUser, int processState) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(receiver.asBinder());
intent.writeToParcel(data, 0);
data.writeInt(resultCode);
data.writeString(dataStr);
data.writeBundle(extras);
data.writeInt(ordered ? 1 : 0);
data.writeInt(sticky ? 1 : 0);
data.writeInt(sendingUser);
data.writeInt(processState);
mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
}
这个方法是运行在 system_server 进程的。
mRemote.transact()
是 system_server 进程发起 binder 通信的方法,经过 binder 驱动,最后会到 binder 服务端 ApplicationThreadNative
的 onTransact()
方法。
2.3.7 ApplicationThreadNative.onTransact() 方法
public abstract class ApplicationThreadNative extends Binder
implements IApplicationThread {
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
case SCHEDULE_REGISTERED_RECEIVER_TRANSACTION: {
data.enforceInterface(IApplicationThread.descriptor);
// 这里获取的是 IIntentReceiver.Stub.Proxy 对象,是 binder 客户端对象
IIntentReceiver receiver = IIntentReceiver.Stub.asInterface(
data.readStrongBinder());
Intent intent = Intent.CREATOR.createFromParcel(data);
int resultCode = data.readInt();
String dataStr = data.readString();
Bundle extras = data.readBundle();
boolean ordered = data.readInt() != 0;
boolean sticky = data.readInt() != 0;
int sendingUser = data.readInt();
int processState = data.readInt();
scheduleRegisteredReceiver(receiver, intent,
resultCode, dataStr, extras, ordered, sticky, sendingUser, processState);
return true;
}
}
}
ApplicationThreadNative
是一个抽象类,scheduleRegisteredReceiver
是它的一个抽象方法,所以要寻找 scheduleRegisteredReceiver
的实现,实现实在 ApplicationThread
类里面。
ApplicationThread
是 ActivityThread
类的私有内部类。
2.3.8 ApplicationThread.scheduleRegisteredReceiver() 方法
- IIntentReceiver receiver, IIntentReceiver.Stub.Proxy 对象,是 binder 客户端对象
- Intent intent, 添加了 action 的 Intent 对象
- int resultCode, Activity.RESULT_OK,值为 -1
- String dataStr, null
- Bundle extras, null
- boolean ordered, false
- boolean sticky, false
- int sendingUser, 0
- int processState
public final class ActivityThread {
private class ApplicationThread extends ApplicationThreadNative {
public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
int resultCode, String dataStr, Bundle extras, boolean ordered,
boolean sticky, int sendingUser, int processState) throws RemoteException {
receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
sticky, sendingUser);
}
}
}
这个方法是运行在客户端进程的 binder 线程池里面。
receiver
是 IIntentReceiver.Stub.Proxy
对象,是 binder 客户端对象。
调用 receiver.performReceive
方法,会经过 binder 驱动,调用到发起方进程的 IIntentReceiver.Stub
对象,即 InnerReceiver
对象的 performReceive
方法。可以查看注册过程的 2.1.3 部分,并且在 2.1.3.2 部分绘制了 InnerReceiver
,BroadcastReceiver
以及ReceiverDispatcher
的类结构图。
2.3.9 InnerReceiver.performReceive() 方法
- Intent intent, 添加了 action 的 Intent 对象
- int resultCode, Activity.RESULT_OK,值为 -1
- String data, null
- Bundle extras, null
- boolean ordered, false
- boolean sticky, false
- int sendingUser, 0
final static class InnerReceiver extends IIntentReceiver.Stub {
final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
final LoadedApk.ReceiverDispatcher mStrongRef;
InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
mStrongRef = strong ? rd : null;
}
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
LoadedApk.ReceiverDispatcher rd = mDispatcher.get();
if (rd != null) {
// 调用到这里,见[2.3.10]
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
} else {
...
}
}
}
2.3.10 ReceiverDispatcher.performReceive() 方法
- Intent intent, 添加了 action 的 Intent 对象
- int resultCode, Activity.RESULT_OK,值为 -1
- String data, null
- Bundle extras, null
- boolean ordered, false
- boolean sticky, false
- int sendingUser, 0
public final class LoadedApk {
static final class ReceiverDispatcher {
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
// 把一系列参数封装在 Args 对象里面,是一个 Runnable 对象。
Args args = new Args(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
// mActivityThread 就是 ActivityThread 类的 mH 对象。
if (!mActivityThread.post(args)) {
...
}
}
}
}
mActivityThread.post
方法把消息在主线程执行。
2.3.11 Args.run() 方法
Args
是 ReceiverDispatcher
的内部类,因此它可以获取到 ReceiverDispatcher
的成员。
static final class ReceiverDispatcher {
final BroadcastReceiver mReceiver;
ReceiverDispatcher(BroadcastReceiver receiver, Context context,
Handler activityThread, Instrumentation instrumentation,
boolean registered) {
mReceiver = receiver;
mContext = context;
mActivityThread = activityThread;
}
final class Args extends BroadcastReceiver.PendingResult implements Runnable {
private Intent mCurIntent;
private final boolean mOrdered;
public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
boolean ordered, boolean sticky, int sendingUser) {
super(resultCode, resultData, resultExtras,
mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED,
ordered, sticky, mIIntentReceiver.asBinder(), sendingUser);
mCurIntent = intent;
mOrdered = ordered;
}
public void run() {
// mReceiver 就是 MyDynamicReceiver 对象
final BroadcastReceiver receiver = mReceiver;
final boolean ordered = mOrdered;
final Intent intent = mCurIntent;
mCurIntent = null;
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
// 调用 MyDynamicReceiver 对象的 onReceive 方法
receiver.onReceive(mContext, intent);
} catch (Exception e) {
...
}
...
}
}
}
2.3.12 MyDynamicReceiver.onReceive() 方法
public class MyDynamicReceiver extends BroadcastReceiver {
private static final String TAG = "MyDynamicReceiver";
public static final String ACTION_LAUNCH_DYNAMIC = "com.wzc.receiver.LAUNCH_DYNAMIC";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "onRecei
ve: receive action = " + action);
if (ACTION_LAUNCH_DYNAMIC.equals(action)) {
Log.d(TAG, "onReceive: do launch work...");
}
}
}
到这里,就收到了广播了。
3.最后
本文到这里就结束了,希望可以帮助到大家。
4. 参考
-
Android 里的广播和广播接收者对应于被观察者和观察者角色,是观察者模式的典型应用。
-
Android:多用户的UserHandle的东东记录
这篇文章解决了对 UerHandle 类中的 uid,userid,appid 不清楚的问题。