braodcast通过静态注册和动态注册两种方式进行使用,这里就不再详细描述
先上个图
ContextImpl通过binder的方式进行通信
开始RTFSC
第一步
自己写的注册类
1 | public class MainActivity extends AppCompatActivity { |
1 | public interface Constant { |
第二步contextWrapper#registerReceiver
contextWrapper#registerReceiver
运用了装饰者设计模式,mBase是ContextImpl的对象
参照:ContextImpl和ContextWrapper(装饰模式)
ContextImpl和ContextWrapper绑定过程
1 | Context mBase; |
其实有个好一点的办法区分,就是找到contextWrapper类,打个断点,看看mBase的类型就好了
第三步ContextImpl#registerReceiver
从第二步,我们已经知道是contextImpl,所以第三步是
ContextImpl#registerReceiver
1 | //... |
一大堆的重载方法(是重写context的抽象方法,相互回调了,就看做为重载方法应该也没毛病)。
最终调用了registerReceiverInternal
第三小步 1.1 ContextImpl#registerReceiverInternal
1 | private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId, |
这个类没多少内容,全部都copy了下来
获取ActivityThread的mH这个 handler 对象
IIntentReceiver的binder对象 IIntentReceiver相当于是一个AIDL的接口。2.x的内容和绑定的关系不是很大,就是可能好理解一些,所以我记录了一下2.x的一些内容,实际上回头发送broadcast的时候还是要知道,AMS发送消息回来的时候需要看这些源码
1 | ReceiverDispatcher(BroadcastReceiver receiver, Context context, |
2.1 这个里把 ReceiverDispatcher 用 this 传了进行,以便于然后 ,后面AMS那边把IIntentReceiver 这个binder对象传回来的时候进行 调取
ReceiverDispatcher自己的performReceive方法,其实这个里我原来也不太理解,为什么不直接传ReceiverDispatcher对象过去。现在我理解成,因为binder对象是可以通过打包在 Parcel中,通过 Parcel的 writeStrongBinder进行传递的,然后AIDL的方式传递到AMS中,然后进行保存
1 | final static class InnerReceiver extends IIntentReceiver.Stub { |
2.2 InnerReceiver是ReceiverDispatcher的静态内部类,并且实现了IIntentReceiver的方法。根据AIDL,继承了IIntentReceiver.Stub相当于一个binder对象并且实现了IIntentReceiver的方法,根据多态,然后可以通过IIntentReceiver的方式进行传递
2.3 在往下一步的下一步,我们就能看到接收了,我们重写的 onReceive()
ReceiverDispatcher#performReceive
1 | public void performReceive(Intent intent, int resultCode, String data, |
2.4 再看args.getRunnable()
1 | public final Runnable getRunnable() { |
- ActivityManager.getService() 想当于调用AMS里面对应的方法
1 | public static IActivityManager getService() { |
上面代码可以看出,就是个AIDL, asInterface就是返回了一个AIDL中的proxy的对象,这个用来跨进程调用AMS的方法
第四步ActivityManagerService#registerReceiver
1 | public Intent registerReceiver(IApplicationThread caller, String callerPackage, |
到此,使用的broadcast在AMS中注册就已经注册完成了
参考
《android源码情景分析》