面试题Android技术知识Android开发

Android源码学习笔记1-Messenger源码的学习

2016-07-30  本文已影响69人  NKming

首先先分析服务端:

服务端必有:

public IBinder onBind(Intent intent) { return messenger.getBinder();}
则得到getBinder()这个方法:
public IBinder getBinder() { return mTarget.asBinder();}
由此得到mTarget 这个变量,分析这个target类:
private final IMessenger mTarget;
得到IMessenger这个类:
IMessenger这是一个基于AIDL写法的接口类,继承自IInterface,其结构和系统自动生成aidl的方法大体相同,一个stub类和一个端口proxy类,可以说是对系统aidl生成做了一定的封装,所以不用我们自己写aidl文件。
既然这是一个接口,那就需要实现,看一下mTarget从哪里来:
public Messenger(Handler target) {mTarget = target.getIMessenger();}
发现这个是从handler过来的:
final IMessenger getIMessenger() { synchronized (mQueue) { if (mMessenger != null) { return mMessenger; } mMessenger = new MessengerImpl(); return mMessenger; }
发现这是一个handler内部变量IMessenger mMessenger,则基本上我们不会自己去实现这个IMessenger类,所以会执行到MessengerImpl:
private final class MessengerImpl extends IMessenger.Stub { public void send(Message msg) { msg.sendingUid = Binder.getCallingUid(); Handler.this.sendMessage(msg); }}
会发现,则个内部类实现了send方法,就是将message通过自身handler机制,发送到记得消息队列中,让自己来处理,所以我们肯定可以在handler内部的handlemessage方法中处理远程服务发过来的消息,所以当我们为我们的messagereplyto赋值messenger时,我们就能够将消息内容发送到定义的handler消息队列处理,然后这个replyto 这个messenger对象可以通过binder机制,因为已经实现了IMessenger接口,则如果是本地的话,可以返回stub对象,如果是远程服务,则可返回proxy对象实现跨进程通信。

客户端:

客户端连接的话,必定实现

public Messenger(IBinder target) { mTarget = IMessenger.Stub.asInterface(target);}

由此可见,这就是基于aidl的通信,知道aidl的,aidl会自定生成一个类,其asInterface里会判断是本地服务还是远程服务,然后选择本地发送还是通过Proxy发送,调用send方法 ,我们可以看到,数据的序列化和反序列化都在message中做好了,所以整个过程是不需要我们来写得。

上一篇下一篇

猜你喜欢

热点阅读