AMS 是怎么和注册发送广播的?
动态注册:
LoadedApk.ReceiverDispatcher.InnerReceiver extends IIntentReceiver.Stub
BroadcastReceiver作为一个成员变量放在ReceiverDispatcher中
最终注册到AMS中的是IIntentReceiver,如上LoadedApk.ReceiverDispatcher.InnerReceiver继承IIntentReceiver.Stub.
动态广播发送:
AMS.broadcastIntentLocked
=》BroadcastQueue.performReceiveLocked
=》IApplicationThread.scheduleRegisteredReceiver
=》ActivityThread.AppliactionThread.scheduleRegisteredReceiver
=》IIntentReceiver.performReceive
=》ReceiverDispatcher.InnerReceiver.performReceive
=》构建Args对象(Args extends BroadcastReceiver.PendingResult)
=》(Handler)mActivityThread.post(Args.getRunnable)
到了这里我们就知道为什么Receiver是运行在主线程上了:因为使用了主线程上的Handler进行post的
=》Args.getRunnable{ run(mReceiver.onReceive) }
到了这里就调用到了我们自定义的BroadcastReceiver了。
静态广播发送:
=》AMS.broadcastIntentLocked
=》BroadcastQueue.scheduleBroadcastsLocked: send message to BroadcastHandler
=》BroadcastHandler case BROADCAST_INTENT_MSG: processNextBroadcast()
=》BroadcastQueue.processCurBroadcastLocked
=》ActivityThread.ApplicationThread.scheduleReceiver
此时已经通过Binder到达App端
=》sendMessage to mH case RECEIVER:
到了这里我们就知道为什么Receiver是运行在主线程上了:因为使用了主线程上的Handler进行发送和处理的
=》handleReceiver
String component = (ReceiverData extends BroadcastReceiver.PendingResult)data.intent.getComponent().getClassName();
component就是注册广播的自定义BroadcastReceiver
=》通过如下方式直接将此Receiver new出一个实例来, 猜测这种方式是针对静态广播的,不然不应该new出一个新的实例来,通过调试果然是
java.lang.ClassLoader cl = context.getClassLoader();
data.intent.setExtrasClassLoader(cl);
data.intent.prepareToEnterProcess();
data.setExtrasClassLoader(cl);
receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
receiver.onReceive(.....)
综上, AMS 在broadcastIntentLocked中区分静态和动态广播去分别处理的
网友评论