热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

BroadcastReceiver启动过程

1.注册过程@OverridepublicIntentregisterReceiver(BroadcastReceiverreceiver,IntentFilterfilter){

1.注册过程

@Override
public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter) {
return mBase.registerReceiver(receiver, filter);
}

看到啥了?mBase.registerReceiver是一个abstract方法,
具体实现在ContextImpl(Context的具体实现,位置E:\adt\sdk\sources\Android-23\android\app)的registerReceiver中

@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) {
return registerReceiverInternal(receiver, getUserId(),
filter, broadcastPermission, scheduler, getOuterContext());
}
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) {
scheduler = mMainThread.getHandler();
}
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 {
//*********************************************************
return ActivityManagerNative.getDefault().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName,
rd, filter, broadcastPermission, userId);
} catch (RemoteException e) {
return null;
}
}
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
enforceNotIsolatedCaller("registerReceiver");
synchronized (this) {
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
rl = new ReceiverList(this, callerApp, callingPid, callingUid,
userId, receiver);
if (rl.app != null) {
rl.app.receivers.add(rl);
} else {
try {
receiver.asBinder().linkToDeath(rl, 0);
} catch (RemoteException e) {
return sticky;
}
rl.linkedToDeath = true;
}
mRegisteredReceivers.put(receiver.asBinder(), rl);
} else if (rl.uid != callingUid) {
throw new IllegalArgumentException(
"Receiver requested to register for uid " + callingUid
+ " was previously registered for uid " + rl.uid);
} else if (rl.pid != callingPid) {
throw new IllegalArgumentException(
"Receiver requested to register for pid " + callingPid
+ " was previously registered for pid " + rl.pid);
} else if (rl.userId != userId) {
throw new IllegalArgumentException(
"Receiver requested to register for user " + userId
+ " was previously registered for user " + rl.userId);
}
//***************************上下两部分
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
permission, callingUid, userId);
rl.add(bf);
if (!bf.debugCheck()) {
Slog.w(TAG, "==> For Dynamic broadcast");
}
mReceiverResolver.addFilter(bf);
。。。。。。。。。
return sticky;
}
}

可以看到registerReceiver其实就做了两件事,一件是用mRegisteredReceivers把IIntentReceiver保存起来,另一件是生成一个BroadcastFilter,然后用mReceiverResolver保存起来
mRegisteredReceivers是一个HashMap

2.发送过程

ContextImpl的sendBroadcast方法

@Override
public void sendBroadcast(Intent intent) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
intent.prepareToLeaveProcess();
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
getUserId());
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
}
public final int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras,
String[] requiredPermissions, int appOp, Bundle options,
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();
int res = broadcastIntentLocked(callerApp,
callerApp != null ? callerApp.info.packageName : null,
intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
requiredPermissions, appOp, null, serialized, sticky,
callingPid, callingUid, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}

broadcastIntentLocked前面是一系列的过滤条件,最后有下面这段代码

if ((receivers != null && receivers.size() > 0)
|| resultTo != null) {
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, resolvedType,
requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
resultData, resultExtras, ordered, sticky, false, userId);
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
+ ": prev had " + queue.mOrderedBroadcasts.size());
if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
"Enqueueing broadcast " + r.intent.getAction());
boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
if (!replaced) {
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
}

生成BroadcastRecord然后调用queue(BroadcastQueue)的enqueueOrderedBroadcastLocked和scheduleBroadcastsLocked
E:\adt\sdk\sources\android-23\com\android\server\am\BroadcastQueue.java

public void enqueueOrderedBroadcastLocked(BroadcastRecord r) {
//******************注意,这里添加进链表
mOrderedBroadcasts.add(r);
r.enqueueClockTime = System.currentTimeMillis();
}
public void scheduleBroadcastsLocked() {
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
+ mQueueName + "]: current="
+ mBroadcastsScheduled);
if (mBroadcastsScheduled) {
return;
}
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}

BROADCAST_INTENT_MSG这个标记调用processNextBroadcast

final void processNextBroadcast(boolean fromMsg) {
synchronized(mService) {
BroadcastRecord r;
// First, deliver any non-serialized broadcasts right away.
while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0);
r.dispatchTime = SystemClock.uptimeMillis();
r.dispatchClockTime = System.currentTimeMillis();
final int N = r.receivers.size();
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
+ mQueueName + "] " + r);
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Delivering non-ordered on [" + mQueueName + "] to registered "
+ target + ": " + r);
//***************************************************发送无序广播
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
}
addBroadcastToHistoryLocked(r);
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
+ mQueueName + "] " + r);
}
// Now take care of the next serialized one...
// If we are waiting for a process to come up to handle the next
// broadcast, then do nothing at this point. Just in case, we
// check that the process we're waiting for still exists.
...............................
}
}

从processNextBroadcast可以看出,无序广播存储在mParallelBroadcasts中,deliverToRegisteredReceiverLocked发送广播,然后addBroadcastToHistoryLocked添加到历史队列里去
先看addBroadcastToHistoryLocked

private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
if (r.callingUid <0) {
// This was from a registerReceiver() call; ignore it.
return;
}
r.finishTime = SystemClock.uptimeMillis();
//添加到历史队列里去
mBroadcastHistory[mHistoryNext] = r;
mHistoryNext = ringAdvance(mHistoryNext, 1, MAX_BROADCAST_HISTORY);
mBroadcastSummaryHistory[mSummaryHistoryNext] = r.intent;
mSummaryHistoryEnqueueTime[mSummaryHistoryNext] = r.enqueueClockTime;
mSummaryHistoryDispatchTime[mSummaryHistoryNext] = r.dispatchClockTime;
mSummaryHistoryFinishTime[mSummaryHistoryNext] = System.currentTimeMillis();
mSummaryHistoryNext = ringAdvance(mSummaryHistoryNext, 1, MAX_BROADCAST_SUMMARY_HISTORY);
}

重点看deliverToRegisteredReceiverLocked发送广播

private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
BroadcastFilter filter, boolean ordered) {
//检查对应关系是否正确(比如接受者uid是否正确)***************************
if (!mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
r.callingPid, r.resolvedType, filter.receiverList.uid)) {
return;
}
if (!skip) {
// If this is not being sent as an ordered broadcast, then we
// don't want to touch the fields that keep track of the current
// state of ordered broadcasts.
if (ordered) {
r.receiver = filter.receiverList.receiver.asBinder();
r.curFilter = filter;
filter.receiverList.curBroadcast = r;
r.state = BroadcastRecord.CALL_IN_RECEIVE;
if (filter.receiverList.app != null) {
// Bump hosting application to no longer be in background
// scheduling class. Note that we can't do that if there
// isn't an app... but we can only be in that case for
// things that directly call the IActivityManager API, which
// are already core system stuff so don't matter for this.
r.curApp = filter.receiverList.app;
filter.receiverList.app.curReceiver = r;
mService.updateOomAdjLocked(r.curApp);
}
}
try {
if (DEBUG_BROADCAST_LIGHT) Slog.i(TAG_BROADCAST,
"Delivering to " + filter + " : " + r);
//********************************完成具体的发送过程
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);
if (ordered) {
r.state = BroadcastRecord.CALL_DONE_RECEIVE;
}
} catch (RemoteException e) {
。。。。。。
}
}
}

3.接收过程

private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
// Send the intent to the receiver asynchronously using one-way binder calls.
if (app != null) {
if (app.thread != null) {
// If we have an app thread, do the call through that so it is
// correctly ordered with other one-way calls.
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.repProcState);
} else {
// Application has died. Receiver doesn't exist.
throw new RemoteException("app.thread must not be null");
}
} else {
receiver.performReceive(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
}
}

由于接收广播会调用应用程序,所以app.thread != null条件成立

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);
}

IIntentReceiver具体实现在LoadApk.java(里面有两个performReceive函数,此时应该是final static class InnerReceiver extends IIntentReceiver.Stub的performReceive)

public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
LoadedApk.ReceiverDispatcher rd = mDispatcher.get();
if (ActivityThread.DEBUG_BROADCAST) {
int seq = intent.getIntExtra("seq", -1);
Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction() + " seq=" + seq
+ " to " + (rd != null ? rd.mReceiver : null));
}
if (rd != null) {
//***************************此时调用LoadedApk.ReceiverDispatcher的performReceive
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
} else {
// The activity manager dispatched a broadcast to a registered
// receiver in this process, but before it could be delivered the
// receiver was unregistered. Acknowledge the broadcast on its
// behalf so that the system's broadcast sequence can continue.
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing broadcast to unregistered receiver");
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
if (extras != null) {
extras.setAllowFds(false);
}
mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
} catch (RemoteException e) {
Slog.w(ActivityThread.TAG, "Couldn't finish broadcast to unregistered receiver");
}
}
}
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
if (ActivityThread.DEBUG_BROADCAST) {
int seq = intent.getIntExtra("seq", -1);
Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction() + " seq=" + seq
+ " to " + mReceiver);
}
Args args = new Args(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
if (!mActivityThread.post(args)) {
if (mRegistered && ordered) {
IActivityManager mgr = ActivityManagerNative.getDefault();
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing sync broadcast to " + mReceiver);
args.sendFinished(mgr);
}
}
}

在此方法中生成一个Args对象,然后调用mActivityThread.post(args)(是否记得mActivityThread是一个Handler),args是一个runnable

public void run() {
。。。。。。。。。。
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
//最终在这里接收
receiver.onReceive(mContext, intent);
} catch (Exception e) {
if (mRegistered && ordered) {
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing failed broadcast to " + mReceiver);
sendFinished(mgr);
}
if (mInstrumentation == null ||
!mInstrumentation.onException(mReceiver, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Error receiving broadcast " + intent
+ " in " + mReceiver, e);
}
}
if (receiver.getPendingResult() != null) {
finish();
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}

推荐阅读
  • 最强python编辑器,play首发!
    听说c4droid的作者与pydroid ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 在实际开发中,现在安卓端和后台之间的数据交互,一般都是用JSON来传递数据信息。JSON大家一般都比较熟悉。我这边就以实际项目中的后台传过来的情况和大家分析下及如何处理。比如后台返 ... [详细]
  • 自定义RecyclerView添加EmptyView
    你知道RecyclerView里没有Em ... [详细]
  • spotify engineering culture part 1
    原文,因为原视频说的太快太长,又没有字幕,于是借助youtube,把原文听&打出来了。中文版日后有时间再翻译。oneofthebigsucceessfactorshereatSpo ... [详细]
  • Android 自定义控件基础 canvas paint
    1、首先说一下canvas类:ClassOverviewTheCanvasclassholdsthedrawcalls.Todrawsomething,youne ... [详细]
  • 尝试在数据库中查询数据并在datatables中异步显示时总是报错。有人帮我看下吗,好像是这个json的格式出问题,我看了firebug,应该是servlet返回的json数据格式问题,但因为新 ... [详细]
  • Spark 贝叶斯分类算法
    一、贝叶斯定理数学基础我们都知道条件概率的数学公式形式为即B发生的条件下A发生的概率等于A和B同时发生的概率除以B发生的概率。根据此公式变换,得到贝叶斯公式:即贝叶斯定律是关于随机 ... [详细]
  • Android JNI学习之Concepts
    2019独角兽企业重金招聘Python工程师标准ConceptsBeforeBeginningThisguideassumesthatyouare:Alreadyfamili ... [详细]
  • 本文整理了Java中com.jogamp.opengl.GLDrawable.setRealized()方法的一些代码示例,展示了GLDrawable.se ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 本文介绍了Android中的assets目录和raw目录的共同点和区别,包括获取资源的方法、目录结构的限制以及列出资源的能力。同时,还解释了raw目录中资源文件生成的ID,并说明了这些目录的使用方法。 ... [详细]
  • 今天就跟大家聊聊有关怎么在Android应用中实现一个换肤功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根 ... [详细]
author-avatar
编舞木煜率_841
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有