美文网首页
AMS 是怎么和注册发送广播的?

AMS 是怎么和注册发送广播的?

作者: 平头说人生 | 来源:发表于2018-06-29 16:42 被阅读95次

    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中区分静态和动态广播去分别处理的

    相关文章

      网友评论

          本文标题:AMS 是怎么和注册发送广播的?

          本文链接:https://www.haomeiwen.com/subject/utiayftx.html