本文参考Android开发艺术探索整理所得
主要三个方面的内容:如何使用BroadcastReceiver,BroadcastReceiver注册过程,发送消息和接收消息的过程
1.如何使用
public abstract class BroadcastReceiver
public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
// 该函数不能做耗时操作,10s内要执行完毕
String action = intent.getAction();
}
}
然后需要注册MyReceiver,两种注册方式:静态注册
<receiver
android:name=".MyReceiver">
<intent-filter>
<action android:name=".............."/>
</intent-filter>
</receiver>
动态注册:(合适时机需要解注册)
IntentFilter filter = new IntentFilter();
filter.addAction("..............");
registerReceiver(new MyReceiver(), filter);
发送消息:
getActivity().finish();
Intent intent = new Intent();
intent.setAction("............");
sendBroadcast(intent);
2.BroadcastReceiver注册过程
静态注册的广播接收器是在应用安装的时候由系统自动完成注册,由PMS(PackageManagerService)来完成整个注册过程,其他三大组件也是在应用安装的时候由PMS解析并注册的,因此之分析动态注册过程:
由此开始:
ContextWrapper.java
@Override
public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
return mBase.registerReceiver(receiver, filter, broadcastPermission,
scheduler);
}
ContextImpl.java
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 {
final Intent intent = ActivityManagerNative.getDefault().registerReceiver( // 注意这里
mMainThread.getApplicationThread(), mBasePackageName,
rd, filter, broadcastPermission, userId);
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
intent.prepareToEnterProcess();
}
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
getReceiverDispatcher的作用同Service绑定过程一样,因为注册过程是一个进程间通信过程,而BroadcastReceiver不能跨进程传递,需要IIntentReceiver来中转一下
LoadedApk.java
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); // 注意这里,获取当前应用的所有BroadcastReceiver和ReceiverDispatcher映射关系
if (map != null) {
rd = map.get(r);
}
}
if (rd == null) {
rd = new ReceiverDispatcher(r, context, handler, // 创建一个ReceiverDispatcher
instrumentation, registered);
if (registered) {
if (map == null) {
map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
mReceivers.put(context, map);
}
map.put(r, rd); // 保存ReceiverDispatcher,key是BroadcastReceiver,value是ReceiverDispatcher
}
} else {
rd.validate(context, handler);
}
rd.mForgotten = false;
return rd.getIIntentReceiver();
}
}
private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
= new ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.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();
}
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;
}
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final LoadedApk.ReceiverDispatcher rd;
if (intent == null) {
Log.wtf(TAG, "Null intent received");
rd = null;
} else {
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, 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) {
throw e.rethrowFromSystemServer();
}
}
}
}
创建一个ReceiverDispatcher,ReceiverDispatcher保存了BroadcastReceiver和创建InnerReceiver,InnerReceiver是ReceiverDispatcher的内部类,继承了IIntentReceiver.Stub是一个Binder,为了进程间通信,getReceiverDispatcher返回InnerReceiver对象
然后调用ActivityManagerNative.getDefault.registerReceiver,InnerReceiver作为它的参数传递给AMS,AMS.registerReceiver主要把远程BroadcastReceiver和IntentFilter保存起来
AMS.java
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
..........
ReceiverList rl
= (ReceiverList)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); // 把远程的IIntentReceiver存储起来
} 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 broadast");
}
mReceiverResolver.addFilter(bf); // 存储IntentFilter,继承了Parcelable可以跨进程传输
.........
}
final HashMap<IBinder, ReceiverList> mRegisteredReceivers = // 存储远程BroadcastReceiver
new HashMap<IBinder, ReceiverList>();
3.发送消息和接收消息过程
以