展会信息港展会大全

android开发之广播BroadcastReceiver的发送过程
来源:互联网   发布日期:2016-01-13 21:55:56   浏览:2810次  

导读:当在某个service中想要发送广播,我们就会调用这么的代码:Intent intent = new Intent(BROADCAST_COUNTER_ACTION);intent putExtra(COUNTER_VALUE, counter);sendBroadcast(intent);下面我们就对这几行代码 ...

当在某个service中想要发送广播,我们就会调用这么的代码:

Intent intent = new Intent(BROADCAST_COUNTER_ACTION);

intent.putExtra(COUNTER_VALUE, counter);

sendBroadcast(intent);

下面我们就对这几行代码进行分析

1、一个广播使用intent来描述的,BROADCAST_COUNTER_ACTION名称就是用来和广播接收者的类型进行匹配的。

public class Intent implements Parcelable, Cloneable {

// ---------------------------------------------------------------------

private String mAction;

private Uri mData;

private String mType;

private String mPackage;

private ComponentName mComponent;

private int mFlags;

private HashSet<String> mCategories;

private Bundle mExtras;

private Rect mSourceBounds;

}

变量mAction和mExtras不为空,其余为空

2、 sendBroadcast(intent)的源码:

public class ContextWrapper extends Context {

Context mBase;

public ContextWrapper(Context base) {

mBase = base;

}

@Override

public void sendBroadcast(Intent intent) {

mBase.sendBroadcast(intent);

}

。。。

}

注释:mBase是一个ContextImpl对象,所以调用的是ContextImpl中的sendBroadcast方法。

3、mBase.sendBroadcast(intent)的源码:

@Override

public void sendBroadcast(Intent intent) {

String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());

try {

ActivityManagerNative.getDefault().broadcastIntent(

mMainThread.getApplicationThread(), intent, resolvedType, null,

Activity.RESULT_OK, null, null, null, false, false);

} catch (RemoteException e) {

}

}

注释:(1)

ActivityManagerNative. getDefault()获得是ActivityManagerProxy对象。

(2) resolvedType为空null

4、ActivityManagerProxy 中的broadcastIntent()方法的源码:

public int broadcastIntent(IApplicationThread caller,

Intent intent, String resolvedType,IIntentReceiver resultTo,

int resultCode, String resultData, Bundle map,

String requiredPermission, boolean serialized,

boolean sticky) 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(serialized ? 1 : 0);

data.writeInt(sticky ? 1 : 0);

mRemote.transact(BROADCAST_INTENT_TRANSACTION, data, reply, 0);

reply.readException();

int res = reply.readInt();

reply.recycle();

data.recycle();

return res;

}

注释:(1)将参数封装成Parcel对象data中。

(2)binder代理对象mRemote向ActivityManagerService发送一个类型为BROADCAST_INTENT_TRANSACTION的进程间通信请求。

5、ActivityManagerService 中的源码:

public final int broadcastIntent(IApplicationThread caller,

Intent intent, String resolvedType, IIntentReceiver resultTo,

int resultCode, String resultData, Bundle map,

String requiredPermission, boolean serialized, boolean sticky) {

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, serialized,

sticky, callingPid, callingUid);

Binder.restoreCallingIdentity(origId);

return res;

}

}

6、broadcastIntentLocked()方法源码:

private final int broadcastIntentLocked(ProcessRecord callerApp,

String callerPackage, Intent intent, String resolvedType,

IIntentReceiver resultTo, int resultCode, String resultData,

Bundle map, String requiredPermission,

boolean ordered, boolean sticky, int callingPid, int callingUid) {

intent = new Intent(intent);

if (DEBUG_BROADCAST_LIGHT) Slog.v(

TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent

+ " ordered=" + ordered);

if ((resultTo != null) && !ordered) {

Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");

}

// Handle special intents: if this broadcast is from the package

// manager about a package being removed, we need to remove all of

// its activities from the history stack.

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())

|| uidRemoved) {

if (checkComponentPermission(

android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,

callingPid, callingUid, -1)

== PackageManager.PERMISSION_GRANTED) {

if (uidRemoved) {

final Bundle intentExtras = intent.getExtras();

final int uid = intentExtras != null

? intentExtras.getInt(Intent.EXTRA_UID) : -1;

if (uid >= 0) {

BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();

synchronized (bs) {

bs.removeUidStatsLocked(uid);

}

}

} else {

// If resources are unvailble just force stop all

// those packages and flush the attribute cache as well.

if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {

String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);

if (list != null && (list.length > 0)) {

for (String pkg : list) {

forceStopPackageLocked(pkg, -1, false, true, true);

}

sendPackageBroadcastLocked(

IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);

}

} else {

Uri data = intent.getData();

String ssp;

if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {

if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {

forceStopPackageLocked(ssp,

intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);

}

if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {

sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,

new String[] {ssp});

}

}

}

}

} else {

String msg = "Permission Denial: " + intent.getAction()

+ " broadcast from " + callerPackage + " (pid=" + callingPid

+ ", uid=" + callingUid + ")"

+ " requires "

+ android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;

Slog.w(TAG, msg);

throw new SecurityException(msg);

}

}

/*

* If this is the time zone changed action, queue up a message that will reset the timezone

* of all currently running processes. This message will get queued up before the broadcast

* happens.

*/

if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {

mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);

}

/*

* Prevent non-system code (defined here to be non-persistent

* processes) from sending protected broadcasts.

*/

if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID

|| callingUid == Process.SHELL_UID || callingUid == 0) {

// Always okay.

} else if (callerApp == null || !callerApp.persistent) {

try {

if (AppGlobals.getPackageManager().isProtectedBroadcast(

intent.getAction())) {

String msg = "Permission Denial: not allowed to send broadcast "

+ intent.getAction() + " from pid="

+ callingPid + ", uid=" + callingUid;

Slog.w(TAG, msg);

throw new SecurityException(msg);

}

} catch (RemoteException e) {

Slog.w(TAG, "Remote exception", e);

return BROADCAST_SUCCESS;

}

}

// Add to the sticky list if requested.

if (sticky) { //(1)从上面的传值,这里sticky=false

if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,

callingPid, callingUid)

!= PackageManager.PERMISSION_GRANTED) {

String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="

+ callingPid + ", uid=" + callingUid

+ " requires " + android.Manifest.permission.BROADCAST_STICKY;

Slog.w(TAG, msg);

throw new SecurityException(msg);

}

if (requiredPermission != null) {

Slog.w(TAG, "Can't broadcast sticky intent " + intent

+ " and enforce permission " + requiredPermission);

return BROADCAST_STICKY_CANT_HAVE_PERMISSION;

}

if (intent.getComponent() != null) {

throw new SecurityException(

"Sticky broadcasts can't target a specific component");

}

ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());

if (list == null) {

list = new ArrayList<Intent>();

mStickyBroadcasts.put(intent.getAction(), list);

}

int N = list.size();

int i;

for (i=0; i<N; i++) {

if (intent.filterEquals(list.get(i))) {

// This sticky already exists, replace it.

list.set(i, new Intent(intent));

break;

}

}

if (i >= N) {

list.add(new Intent(intent));

}

}

// Figure out who all will receive this broadcast.

List receivers = null;

List<BroadcastFilter> registeredReceivers = null;

try {

if (intent.getComponent() != null) {

///(2 )intent.getComponent()获得是广播接收者的名称,发送给特定的广播接收者。从上面的传值来看mComponent为null

// Broadcast is going to one specific receiver class...

ActivityInfo ai = AppGlobals.getPackageManager().

getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);

if (ai != null) {

receivers = new ArrayList();

ResolveInfo ri = new ResolveInfo();

ri.activityInfo = ai;

receivers.add(ri);

}

} else {

// Need to resolve the intent to interested receivers...

if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)

== 0) {

///(3)获得静态注册的广播接收者

receivers =

AppGlobals.getPackageManager().queryIntentReceivers(

intent, resolvedType, STOCK_PM_FLAGS);

}

registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);

///(4)获得动态注册的广播接收者

}

} catch (RemoteException ex) {

// pm is in same process, this will never happen.

}

final boolean replacePending =

(intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;

if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()

+ " replacePending=" + replacePending);

int NR = registeredReceivers != null ? registeredReceivers.size() : 0;

if (!ordered && NR > 0) { ///(5)这里为true

// If we are not serializing this broadcast, then send the

// registered receivers separately so they don't wait for the

// components to be launched.

BroadcastRecord r = new BroadcastRecord(intent, callerApp,

callerPackage, callingPid, callingUid, requiredPermission,

registeredReceivers, resultTo, resultCode, resultData, map,

ordered, sticky, false);

if (DEBUG_BROADCAST) Slog.v(

TAG, "Enqueueing parallel broadcast " + r

+ ": prev had " + mParallelBroadcasts.size());

boolean replaced = false;

if (replacePending) {///(6)这里检查是否存在一个这样的无序广播,如果存在替换,如果不存在择添加。

for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {

if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {

if (DEBUG_BROADCAST) Slog.v(TAG,

"***** DROPPING PARALLEL: " + intent);

mParallelBroadcasts.set(i, r);

replaced = true;

break;

}

}

}

if (!replaced) {

mParallelBroadcasts.add(r);

scheduleBroadcastsLocked(); //然后执行这个方法

}

registeredReceivers = null;

NR = 0;

}

// Merge into one list.

int ir = 0;

if (receivers != null) {

// A special case for PACKAGE_ADDED: do not allow the package

// being added to see this broadcast.This prevents them from

// using this as a back door to get run as soon as they are

// installed.Maybe in the future we want to have a special install

// broadcast or such for apps, but we'd like to deliberately make

// this decision.

String skipPackages[] = null;

if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())

|| intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())

|| intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {

Uri data = intent.getData();

if (data != null) {

String pkgName = data.getSchemeSpecificPart();

if (pkgName != null) {

skipPackages = new String[] { pkgName };

}

}

} else if (intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {

skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);

}

if (skipPackages != null && (skipPackages.length > 0)) {

for (String skipPackage : skipPackages) {

if (skipPackage != null) {

int NT = receivers.size();

for (int it=0; it<NT; it++) {

ResolveInfo curt = (ResolveInfo)receivers.get(it);

if (curt.activityInfo.packageName.equals(skipPackage)) {

receivers.remove(it);

it--;

NT--;

}

}

}

}

}

int NT = receivers != null ? receivers.size() : 0;

int it = 0;

ResolveInfo curt = null;

BroadcastFilter curr = null;

while (it < NT && ir < NR) {

if (curt == null) {

curt = (ResolveInfo)receivers.get(it);

}

if (curr == null) {

curr = registeredReceivers.get(ir);

}

if (curr.getPriority() >= curt.priority) {

// Insert this broadcast record into the final list.

receivers.add(it, curr);

ir++;

curr = null;

it++;

NT++;

} else {

// Skip to the next ResolveInfo in the final list.

it++;

curt = null;

}

}

}

while (ir < NR) {

if (receivers == null) {

receivers = new ArrayList();

}

receivers.add(registeredReceivers.get(ir));

ir++;

}

if ((receivers != null && receivers.size() > 0)

|| resultTo != null) {

BroadcastRecord r = new BroadcastRecord(intent, callerApp,

callerPackage, callingPid, callingUid, requiredPermission,

receivers, resultTo, resultCode, resultData, map, ordered,

sticky, false);

if (DEBUG_BROADCAST) Slog.v(

TAG, "Enqueueing ordered broadcast " + r

+ ": prev had " + mOrderedBroadcasts.size());

if (DEBUG_BROADCAST) {

int seq = r.intent.getIntExtra("seq", -1);

Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);

}

boolean replaced = false;

if (replacePending) {

for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {

if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {

if (DEBUG_BROADCAST) Slog.v(TAG,

"***** DROPPING ORDERED: " + intent);

mOrderedBroadcasts.set(i, r);

replaced = true;

break;

}

}

}

if (!replaced) {

mOrderedBroadcasts.add(r);

scheduleBroadcastsLocked();

}

}

return BROADCAST_SUCCESS;

}

注释:如上面的(1),(2)....

7、scheduleBroadcastsLocked()的源码:

private final void scheduleBroadcastsLocked() {

if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="

+ mBroadcastsScheduled);

if (mBroadcastsScheduled) {

return;

}

mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);

mBroadcastsScheduled = true;

}

注释:mBroadcastsScheduled表示是否已经向所有运行的线程发送了一个类型为BROADCAST_INTENT_MSG的消息。

到这里,广播就发送完了,可以看出广播发送和接受者是异步的

8、mHandler.sendEmptyMessage( BROADCAST_INTENT_MSG)的源码:

final Handler mHandler = new Handler() {

//public Handler() {

//if (localLOGV) Slog.v(TAG, "Handler started!");

//}

public void handleMessage(Message msg) {

switch (msg.what) {

case BROADCAST_INTENT_MSG: {

if (DEBUG_BROADCAST) Slog.v(

TAG, "Received BROADCAST_INTENT_MSG");

processNextBroadcast(true);

} break;

。。。。

}}

解释:mHandler是定义在ActivityManagerService中的变量,用于发送消息。

9、processNextBroadcast(true)的源码:

private final void processNextBroadcast(boolean fromMsg) {

synchronized(this) {

BroadcastRecord r;

if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "

+ mParallelBroadcasts.size() + " broadcasts, "

+ mOrderedBroadcasts.size() + " ordered broadcasts");

updateCpuStats();

if (fromMsg) { //(1)这里为true

mBroadcastsScheduled = false;

}

// First, deliver any non-serialized broadcasts right away.

while (mParallelBroadcasts.size() > 0) { //(2) 这里为true

,因为上面向mParallelBroadcasts添加了数据

r = mParallelBroadcasts.remove(0);

r.dispatchTime = SystemClock.uptimeMillis();

final int N = r.receivers.size();///(3)这里的r.receivers.就是上面创建BroadcastRecord对象时候传入的registeredReceivers

if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "

+ r);

for (int i=0; i<N; i++) {

Object target = r.receivers.get(i);

if (DEBUG_BROADCAST)Slog.v(TAG,

"Delivering non-ordered to registered "

+ target + ": " + r);

deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);

//执行这行代码

}

addBroadcastToHistoryLocked(r);

if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "

+ 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.

if (mPendingBroadcast != null) {

if (DEBUG_BROADCAST_LIGHT) {

Slog.v(TAG, "processNextBroadcast: waiting for "

+ mPendingBroadcast.curApp);

}

boolean isDead;

synchronized (mPidsSelfLocked) {

isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);

}

if (!isDead) {

// It's still alive, so keep waiting

return;

} else {

Slog.w(TAG, "pending app " + mPendingBroadcast.curApp

+ " died before responding to broadcast");

mPendingBroadcast.state = BroadcastRecord.IDLE;

mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;

mPendingBroadcast = null;

}

}

boolean looped = false;

do {// mOrderedBroadcasts这里是处理有序队列的,因为上面没有传值,就不分析了

if (mOrderedBroadcasts.size() == 0) {

// No more broadcasts pending, so all done!

scheduleAppGcsLocked();

if (looped) {

// If we had finished the last ordered broadcast, then

// make sure all processes have correct oom and sched

// adjustments.

updateOomAdjLocked();

}

return;

}

。。。。。

}

}

10、deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false)的源码:

private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,

BroadcastFilter filter, boolean ordered) {

boolean skip = false;

if (filter.requiredPermission != null) {

///(1)检查发送者权限

int perm = checkComponentPermission(filter.requiredPermission,

r.callingPid, r.callingUid, -1);

if (perm != PackageManager.PERMISSION_GRANTED) {

Slog.w(TAG, "Permission Denial: broadcasting "

+ r.intent.toString()

+ " from " + r.callerPackage + " (pid="

+ r.callingPid + ", uid=" + r.callingUid + ")"

+ " requires " + filter.requiredPermission

+ " due to registered receiver " + filter);

skip = true;

}

}

if (r.requiredPermission != null) {

///(2)检查接受者权限

int perm = checkComponentPermission(r.requiredPermission,

filter.receiverList.pid, filter.receiverList.uid, -1);

if (perm != PackageManager.PERMISSION_GRANTED) {

Slog.w(TAG, "Permission Denial: receiving "

+ r.intent.toString()

+ " to " + filter.receiverList.app

+ " (pid=" + filter.receiverList.pid

+ ", uid=" + filter.receiverList.uid + ")"

+ " requires " + r.requiredPermission

+ " due to sender " + r.callerPackage

+ " (uid " + r.callingUid + ")");

skip = true;

}

}

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) { //这里为false

。。。。

}

try {

if (DEBUG_BROADCAST_LIGHT) {

int seq = r.intent.getIntExtra("seq", -1);

Slog.i(TAG, "Delivering to " + filter

+ " (seq=" + seq + "): " + r);

}

performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,

new Intent(r.intent), r.resultCode,

r.resultData, r.resultExtras, r.ordered, r.initialSticky);

if (ordered) {

r.state = BroadcastRecord.CALL_DONE_RECEIVE;

}

} catch (RemoteException e) {

Slog.w(TAG, "Failure sending broadcast " + r.intent, e);

if (ordered) {

r.receiver = null;

r.curFilter = null;

filter.receiverList.curBroadcast = null;

if (filter.receiverList.app != null) {

filter.receiverList.app.curReceiver = null;

}

}

}

}

}

11、performReceiveLocked()源码:

static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,

Intent intent, int resultCode, String data, Bundle extras,

boolean ordered, boolean sticky) throws RemoteException {

// Send the intent to the receiver asynchronously using one-way binder calls.

if (app != null && 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);

} else {

receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);

}

}

App为activity组件,app.thread即为应用运行进程的一个ApplicationThread的代理对象。

12、scheduleRegisteredReceiver源码:

public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,

int resultCode, String dataStr, Bundle extras, boolean ordered, boolean sticky)

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

mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION, data, null,

IBinder.FLAG_ONEWAY);

data.recycle();

}

13、接下来是ActivityThread中的 的方法

public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,

int resultCode, String dataStr, Bundle extras, boolean ordered,

boolean sticky) throws RemoteException {

receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky);

}

注释:参数receiver封装了一个广播接收者

14 、 receiver.performReceive源码:

public void performReceive(Intent intent, int resultCode,

String data, Bundle extras, boolean ordered, boolean sticky) {

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) {

rd.performReceive(intent, resultCode, data, extras,

ordered, sticky);

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

} catch (RemoteException e) {

Slog.w(ActivityThread.TAG, "Couldn't finish broadcast to unregistered receiver");

}

}

}

15、rd.performReceive的源码:

public void performReceive(Intent intent, int resultCode,

String data, Bundle extras, boolean ordered, boolean sticky) {

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

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

}

}

}

注释:将intent所描述的广播封装成一个args对象,然后把它封装成一个消息,添加到主程序的消息队列中。

16、args的run()源码:

public void run() {

final BroadcastReceiver receiver = mReceiver;

final boolean ordered = mOrdered;

if (ActivityThread.DEBUG_BROADCAST) {

int seq = mCurIntent.getIntExtra("seq", -1);

Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()

+ " seq=" + seq + " to " + mReceiver);

Slog.i(ActivityThread.TAG, "mRegistered=" + mRegistered

+ " mOrderedHint=" + ordered);

}

final IActivityManager mgr = ActivityManagerNative.getDefault();

final Intent intent = mCurIntent;

mCurIntent = null;

if (receiver == null || mForgotten) {

if (mRegistered && ordered) {

if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,

"Finishing null broadcast to " + mReceiver);

sendFinished(mgr);

}

return;

}

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)) {

throw new RuntimeException(

"Error receiving broadcast " + intent

+ " in " + mReceiver, e);

}

}

if (receiver.getPendingResult() != null) {

finish();

}

}

注释:请看这行代码receiver.onReceive(mContext, intent);,这就是调用了广播接收器中的onReceive方法。我们在自定义中的广播接收器中,经常重写这个方法

赞助本站

人工智能实验室

相关热词: 广播 BroadcastReceiver android

AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港