Android 进阶解密阅读笔记6
四大组件之 BroadcastReceiver 使用流程
从 ContextImpl 说起,动态注册会调用 registerBroadcastReceiver 传入自定义的广播接收器。接着会调动 AMS,在 mRegisteredReceivers 里查找当前应用进程相关的 ReceiverList,没有就新建,并添加 BroadcastFilter 对象,以及缓存到 mReceiverResolver 里。
自定义广播接收器里,需要我们重写 onReceive 方法,来处理业务逻辑。
接着发送广播,还是从 ContextImpl 说起,sendBroadcast 方法里紧接着就调用了 AMS,起初 AMS 会校验一下 Intent 类型的入参合法性,接着调用 broadcastIntentLocked 方法做进一步处理。方法内前面部分主要根据 intent 的 action 进行广播动作区分,最后排除系统行为后,才会认为是用户的广播,借助 BroadcastQueue 对封装成 BroadcastRecord 的 intent 信息进行处理。
在 BroadcastQueue 里,会通过消息机制进行广播消息处理(这点类似于 MessageQueue),最后又会转到调用者进程的 ApplicationThread 里去处理。这里有个入参类型要了解 IIntentReceiver 是通过 AIDL 实现的,本质就是 Binder 通信,真正的实现类是 LoadedApk 内部的 ReceiverDispatcher.InnerReceiver,接下去就会用到它。
ApplicationThread 的方法内部就是调用了 ReceiverDispatcher.InnerReceiver 的方法 performReceive。其又会转向调用 ReceiverDispatcher 的方法。最后 LoadedApk 对象所在的线程里会 post 一个消息处理 Args 类型的对象。在这里最终就会调用 onReceive 方法了。
关键点是,在注册广播接收器时缓存了 BroadcastFilter,发送广播时,从缓存里取出相应的 BroadcastFilter 用于处理。
四大组件之Content Provider 使用流程
我们可以将 getContentResolver 作为使用 Content Provider 入口点进行分析。作为 ContextImpl 的成员变量 mContentResolver 是在构造方法里创建的,而 ContextImpl 对象会在创建 Activity 或者 Application 等的时候创建,在哪创建应该都一样,就以创建 Activity 为例,ApplicationContentResolver 对象主要关联了应用进程的 ActivityThread 对象。
接着是一些功能操作,例如增,删,改,查。以 insert 为例,方法由其父类 ContentResolver 提供,大意是获取 IContentProvider 对象,并继续调用其 insert 方法。这里有两点需要了解,1.如何获取 IContentProvider 对象,2.IContentProvider 对象的 insert 方法内部逻辑如何。
对于第一点通过 ActivityThread 提供的 acquireProvider 方法获取。方法主要思路依然是 先从缓存中获取,没有的话新建,而新建的过程依然是 AMS 负责(可见 AMS 多么的能干)。再通过 ApplicationThread 和 AMS 相互来回调用完成 ContentProvider 的创建及安装。创建安装的逻辑其实可以启动根 Activity 很类似。
IContentProvider 是 ContentProvider 的代理类,真正的实现要在 ContentProvider 里查看,位置在源码的 framework/base/core/java/android/content/ContentProvider
以上文字描述比较抽象,如果能在梳理的过程中结合画图会更好的理解。总的来说四大组件的启动离不开 ActivityThread,ApplicationThread,AMS,LoadedApk 等几个关键类,并且通信形式上会涉及 Socket,Binder,消息机制 通信。