前面文章《android--监听SMS》中简单实现了接受短信信息的功能,下面棘突分析一下源码是怎么实现的。
广播接收者的注册分为静态注册和动态注册,在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,用来描述正在注册的广播接收者。广播注册到这就分析完了。