展会信息港展会大全

android开发之广播接收者BroadcastReceiver的注册过程
来源:互联网   发布日期:2016-01-13 21:56:05   浏览:1900次  

导读:广播接收者的注册分为静态注册和动态注册,在AndroidManifest xml中配置的属于静态注册,而动态注册需要调用context中的 registerReceiver方法进行注册。这次我们对动态注册进行分析1、代码如下:IntentFilter ...

广播接收者的注册分为静态注册和动态注册,在AndroidManifest.xml中配置的属于静态注册,而动态注册需要调用context中的 registerReceiver方法进行注册。

这次我们对动态注册进行分析

1、代码如下:

IntentFilter counterActionFilter = new IntentFilter(CounterService.BROADCAST_COUNTER_ACTION);

registerReceiver(counterActionReceiver, counterActionFilter);

注释:

(1)、IntentFilter 顾名思义,IntentFilter对象负责过滤掉组件无法响应和处理的 Intent,只将自己关心的Intent接收进来进行处理。 IntentFilter实行 白名单 管理,即只列出组件乐意接受的Intent,但IntentFilter只会过滤隐式Intent,显式的 Intent会直接传送到目标组件。 Android组件可以有一个或多个IntentFilter,每个IntentFilter之间相互独立,只需要其中一个验证通过则可。

创建IntentFilter对象的源码:

public class IntentFilter implements Parcelable {

private int mPriority;

private final ArrayList<String> mActions;

public IntentFilter(String action) {

mPriority = 0;

mActions = new ArrayList<String>();

addAction(action);

}

。。。

}

把CounterService.BROADCAST_COUNTER_ACTION字符串放到了mActions 中。

2、registerReceiver的源码:

public class ContextWrapper extends Context {

Context mBase;

public ContextWrapper(Context base) {

mBase = base;

}

@Override

public Intent registerReceiver(

BroadcastReceiver receiver, IntentFilter filter) {

return mBase.registerReceiver(receiver, filter);

}

。。。

}

mBase是ContextImpl对象。

3、mBase.registerReceiver(receiver, filter)的源码:

class ContextImpl extends Context {

。。。。

@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, filter, broadcastPermission,

scheduler, getOuterContext());

}

private Intent registerReceiverInternal(BroadcastReceiver receiver,

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

rd, filter, broadcastPermission);

} catch (RemoteException e) {

return null;

}

}

。。。

}

注释:

(1)通过getReceiverDispatcher()将广播接收者封装成实现IintentReceiver接口的binder本地对象rd。

3.1 mPackageInfo.getReceiverDispatcher()的源码:

public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,

Context context, Handler handler,

Instrumentation instrumentation, boolean registered) {

synchronized (mReceivers) {

LoadedApk.ReceiverDispatcher rd = null;

HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;

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 HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();

mReceivers.put(context, map);

}

map.put(r, rd);

}

} else {

rd.validate(context, handler);

}

return rd.getIIntentReceiver();

}

}

3.2 new 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;

}

}

final IIntentReceiver.Stub mIIntentReceiver;

final BroadcastReceiver mReceiver;

final Context mContext;

final Handler mActivityThread;

final Instrumentation mInstrumentation;

final boolean mRegistered;

ReceiverDispatcher(BroadcastReceiver receiver, Context context,

Handler activityThread, Instrumentation instrumentation,

boolean registered) {

if (activityThread == null) {

throw new NullPointerException("Handler must not be null");

}

mIIntentReceiver = new InnerReceiver(this, !registered);

mReceiver = receiver;

mContext = context;

mActivityThread = activityThread;

mInstrumentation = instrumentation;

mRegistered = registered;

mLocation = new IntentReceiverLeaked(null);

mLocation.fillInStackTrace();

}

IIntentReceiver getIIntentReceiver() {

return mIIntentReceiver;

}

mReceiver表示广播接受者

mContext表示activity组件,也就是这个广播接受者在哪一个activity中注册的。

mActivityThread表示与activity相关的handle

mIIntentReceiver指向了创建的ReceiverDispatcher对象。

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

总结:activity组件在注册一个广播接收者时,并不是真的将广播接收者注册到ActivityManagerService 中,而是将与它相关联的IntentReceiver对象注册到ActivityManagerService中,当ActivityManagerService 接受到一个广播的时候,他就会根据广播的类型在内部找到对应的IntentReceiver对象,然后再通过他找到广播接收者。

4、ActivityManagerProxy中怎么实现的registerReceiver方法 ,源码:

public Intent registerReceiver(IApplicationThread caller,

IIntentReceiver receiver,

IntentFilter filter, String perm) throws RemoteException

{

Parcel data = Parcel.obtain();

Parcel reply = Parcel.obtain();

data.writeInterfaceToken(IActivityManager.descriptor);

data.writeStrongBinder(caller != null ? caller.asBinder() : null);

data.writeStrongBinder(receiver != null ? receiver.asBinder() : null);

filter.writeToParcel(data, 0);

data.writeString(perm);

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;

}

注释:binder代理对象mRemote向ActivityManagerService发送一个类型为 REGISTER_RECEIVER_TRANSACTION的进程间通信请求。

5、ActivityManagerService中的源码:

public final class ActivityManagerService extends ActivityManagerNative

implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

public Intent registerReceiver(IApplicationThread caller,

IIntentReceiver receiver, IntentFilter filter, String permission) {

synchronized(this) {

ProcessRecord callerApp = null;

if (caller != null) {

callerApp = getRecordForAppLocked(caller);

if (callerApp == null) {

throw new SecurityException(

"Unable to find app for caller " + caller

+ " (pid=" + Binder.getCallingPid()

+ ") when registering receiver " + receiver);

}

}

List allSticky = null;

// Look for any matching sticky broadcasts...

Iterator actions = filter.actionsIterator();

if (actions != null) {

while (actions.hasNext()) {

String action = (String)actions.next();

allSticky = getStickiesLocked(action, filter, allSticky);

}

} else {

allSticky = getStickiesLocked(null, filter, allSticky);

}

// The first sticky in the list is returned directly back to

// the client.

Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;

if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter

+ ": " + sticky);

if (receiver == null) {

return sticky;

}

ReceiverList rl

= (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());

if (rl == null) {

rl = new ReceiverList(this, callerApp,

Binder.getCallingPid(),

Binder.getCallingUid(), 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);

}

BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);

rl.add(bf);

if (!bf.debugCheck()) {

Slog.w(TAG, "==> For Dynamic broadast");

}

mReceiverResolver.addFilter(bf);

// Enqueue broadcasts for all existing stickies that match

// this filter.

if (allSticky != null) {

ArrayList receivers = new ArrayList();

receivers.add(bf);

int N = allSticky.size();

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

Intent intent = (Intent)allSticky.get(i);

BroadcastRecord r = new BroadcastRecord(intent, null,

null, -1, -1, null, receivers, null, 0, null, null,

false, true, true);

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

scheduleBroadcastsLocked();

}

mParallelBroadcasts.add(r);

}

}

return sticky;

}

}

。。。

}

注释:

创建一个BroadcastFilter,用来描述正在注册的广播接收者。广播注册到这就分析完了。

赞助本站

人工智能实验室
AiLab云推荐
展开

热门栏目HotCates

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