1.广播的基本使用
类继承 BroadcastReceiver,onReceive回调中处理业务逻辑
intent.getAction来匹配之前写的action等。
静态:manifest里面注册,通过intent匹配
动态: a. new BroadcastReceiver,
b. new IntentFilter,
c. intentfilter.addAction("匹配规则")
d. registerReceiver
e. unregisterReceiver
2.广播的工作流程
2.1 广播的注册过程
2.1.1 静态注册:pms(PackageManagerService)来完成解析和注册,四大组件均是pms来完成解析和注册
public class PackageManagerService extends IPackageManager.Stub implements PackageSender {
mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final Message msg = mHandler .obtainMessage(CHECK_PENDING_VERIFICATION);
msg.arg1 = verificationId;
mHandler.sendMessageDelayed(msg, getVerificationTimeout());
}
}, null, 0, null, null);
mArgs = null;
}
实际上底层还是通过binder和handler
2.1.2 动态注册:
//入口是在ContextWrap的registerReceiver中。
@Override
public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter) {
return mBase.registerReceiver(receiver, filter);
}
具体实现则是在ContextImpl(路径:Android/sdk/sources/android-26/android/app)
//实际上是进程间通信的过程,broadCastReceiver无法直接跨进程传递,需要通过binder进行传递。而IIntentReceiver则是作为一个中转层
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context, int flags) {
IIntentReceiver rd = null;//这里是binder的接口。
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = mPackageInfo.getReceiverDispatcher(
//通过广播和context和handler和Instrumentation的转换,获取到iIntentReceiver,取出rd的方法
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = new LoadedApk.ReceiverDispatcher(
//主要的存放的方法,intentReceiver的具体实现如下图
receiver, context, scheduler, null, true).getIIntentReceiver();
}
}
try {
final Intent intent =
//核心注册代码,activityManager得到服务
//实际上是在ActivityManagerService中调用registerReceiver
ActivityManager.getService().registerReceiver(
mMainThread.getApplicationThread(),
mBasePackageName, rd, filter,
broadcastPermission, userId, flags);
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
intent.prepareToEnterProcess();
}
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
Context context, Handler handler,
Instrumentation instrumentation, boolean registered) {
synchronized (mReceivers) {
LoadedApk.ReceiverDispatcher rd = null;
ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;//通过键值对的形式去存context和BroadCastReceiver。
if (registered) {
map = mReceivers.get(context);
if (map != null) {
rd = map.get(r);
}
}
if (rd == null) {
rd = new ReceiverDispatcher(r, context, handler,
instrumentation, registered);
if (registered) {
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;
return rd.getIIntentReceiver();
}
}
真正的注册代码核心(AMS中的registerReceiver中)
最终将远程的innerReceiver对象以及IntentFilter对象存储起来
mRegisteredReceivers.put(receiver.asBinder(), rl);
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
permission, callingUid, userId, instantApp, visibleToInstantApps);
rl.add(bf);
mReceiverResolver.addFilter(bf);
也就是说,动态注册的过程如下:
Activity的registerReceiver==>
ContextWrap的registerReceiver==>
ContextImpl的registerReceiverInternal()==>
LoadedApk的getReceiverDispatcher()获取IIntentReceiver==>
ActivityManager的registerReceiver。
2.2 广播发送和接收的过程
2.2.1 发送
依然是从ContextWrapper的sendBroadcast开始,实现为ContextImp的sendBroadcast。
@Override
public void sendBroadcast(Intent intent) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
intent.prepareToLeaveProcess(this);
//异步向ams发送广播
ActivityManager.getService().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
AMS发送广播代码
public final int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras,
String[] requiredPermissions, int appOp, Bundle bOptions,
boolean serialized, boolean sticky, int userId) {
enforceNotIsolatedCaller("broadcastIntent");
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();
//核心代码
//广播默认不发送给已经停止的应用
//intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
int res = broadcastIntentLocked(callerApp,
callerApp != null ? callerApp.info.packageName : null,
intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
requiredPermissions, appOp, bOptions, serialized, sticky,
callingPid, callingUid, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
final int broadcastIntentLocked() {
final BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord();
final boolean replaced = replacePending
&& (queue.replaceParallelBroadcastLocked(r) != null);
if (!replaced) {
//排序
queue.enqueueParallelBroadcastLocked(r);
//发送过程
queue.scheduleBroadcastsLocked();
}
registeredReceivers = null;
NR = 0;
}
BroadCastQueue的scheduleBroadcastsLocked方法
public void scheduleBroadcastsLocked() {
//Set when we current have a BROADCAST_INTENT_MSG in flight
if (mBroadcastsScheduled) {
return;
}
//通过handler发送一个Broadcast_intent_msg
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BROADCAST_INTENT_MSG: {
if (DEBUG_BROADCAST) Slog.v(
TAG_BROADCAST, "Received BROADCAST_INTENT_MSG");
processNextBroadcast(true);
} break;
final void processNextBroadcast(boolean fromMsg) {
while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0);
r.dispatchTime = SystemClock.uptimeMillis();
r.dispatchClockTime = System.currentTimeMillis();
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
System.identityHashCode(r));
Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
System.identityHashCode(r));
}
final int N = r.receivers.size();
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
}
addBroadcastToHistoryLocked(r);
}
}
deliverToRegisteredReceiverLocked()内部调performReceiveLocked()方法完成具体的发送。
也就是说 整个流程为:
ContextWrapper的sendBroadcast()==>
ContextImp的sendBroadcast()==>
AMS的broadcastIntent()==>
AMS的broadcastIntentLocked==>
BroadCastQueue的scheduleBroadcastsLocked()==>
processNextBroadcast()==>
deliverToRegisteredReceiverLocked()==>
performReceiveLocked()==>
scheduleRegisteredReceiver==>
ApplicationThread(ActivityThread的内部类)==>
//ActivityThread的scheduleRegisteredReceiver,则是
public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
int resultCode, String dataStr, Bundle extras, boolean ordered,
boolean sticky, int sendingUser, int processState) throws RemoteException {
updateProcessState(processState, false);
receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
sticky, sendingUser);
//内部则是LoadApk的ReceiverDispatcher类的performReceive方法
}
而performReceive内部则是调用
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
intent.prepareToEnterProcess();
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
receiver.onReceive(mContext, intent);
完成整个广播的注册