1 用法
(1)定义广播接收者
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//TODO
}
}
(2)注册广播
1 静态注册
<receiver android:name=”.MyBroadcastReceiver” >
<intent-filter>
<action android:name=”android.net.conn.CONNECTIVITY_CHANGE” />
</intent-filter>
<intent-filter>
<action android:name=”android.intent.action.BOOT_COMPLETED” />
</intent-filter>
</receiver>
2 动态注册
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BROADCAST_ACTION);
registerReceiver(mBroadcastReceiver, intentFilter);
(3)发送广播
Intent intent = new Intent();
intent.setAction(BROADCAST_ACTION);
intent.putExtra(“name”, “qqyumidi”);
sendBroadcast(intent);
2 源码分析
1 ContextWrapper
@Override
public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter) {
return mBase.registerReceiver(receiver, filter);
}
mBase是contextImpl,说过无数次了。
2 ContextImpl
@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;
}
}
因为注册广播是一个进程间通信的过程,所以不能直接只用BroadcastReceiver。mPackageInfo.getReceiverDispatcher将broadcast转化为一个binder,这个过程和service的
mPackageInfo.getServiceDispatcher类型。mPackageInfo是LoadedApk实例,下面看看getReceiverDispatcher
3 LoadedApk
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;
if (registered) {
map = mReceivers.get(context);
if (map != null) {
rd = map.get(r);
}
}
......
rd = new ReceiverDispatcher(r, context, handler,
instrumentation, registered);
......
return rd.getIIntentReceiver();
}
}
这里涉及到LoadedApk,ReceiverDispatcher,
private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
= new ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();
rd是一个ReceiverDispatcher实例,他调用了自己的getIIntentReceiver方法
IIntentReceiver getIIntentReceiver() {
return mIIntentReceiver;
}
mIIntentReceiver是一个binder,下面就来看看怎么把broadcastReceiver转化为binder的
4 ReceiverDispatcher
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();
}
ReceiverDispatcher实例化时创建了InnerReceiver,InnerReceiver就是一个binder,这里就将broadcastReceiver“转化“为binder了,其实这个过程和service转化为binder一模一样,可以结合service来比较。
5 InnerReceiver
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;
}
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
......
}
}
6 ActivityManagerProxy(ActivityManager内部类)
回到第2步,接着执行了ActivityManagerNative.getDefault().registerReceiver,什么不用说了,大家都懂,直接上代码。