实例在最后,先简析原理。
1、服务端重要代码解析
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
getBinder里面是这样的
public IBinder getBinder() {
return mTarget.asBinder();
}
mTarget是什么?怎么来的?
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
Messenger的构造方法里面传进去的
getIMessenger里面是这样的
final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger != null) {
return mMessenger;
}
mMessenger = new MessengerImpl();
return mMessenger;
}
}
private final class MessengerImpl extends IMessenger.Stub {
public void send(Message msg) {
msg.sendingUid = Binder.getCallingUid();
Handler.this.sendMessage(msg);
}
}
从上面我们可以看到,mTarget是一个MessengerImpl对象,那么asBinder实际上是返回this(framework层源码里面有),也就是MessengerImpl对象。我们代码中用到的send方法,实际上就在MessengerImpl里面,本质上调用的还是handler的sendMessage方法!另外,我们可以看到的是,MessengerImpl本质上也是继承了IMessenger.Stub,实际山就是aidl的写法!
2、客户端源码解析
客户端 主要是三个重点,与服务端连接ServiceConnection、回传消息给服务端send(Message msg)、接收服务端穿过来的消息Messenger下的handleMessage(Message msg)。
注意一点是,回传拿到的Messenger是通过服务端传过来的IBinder对象拿到的,主要代码是
private ServiceConnection mConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = new Messenger(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
};
new Messenger(service)里面是这样的
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
在这里,我们给mTarget赋值,保证服务端发送消息跟客户端回传用的Messenger对象始终是同一个,服务端发送消息给客户端,用的是客户端的Messenger对象;客户端发送消息给服务端用的是服务端的Messenger对象!简而言之就是,Messenger对象会随着消息一起发送过去,在另一边执行操作!具体代码是public Messenger replyTo;给这个replyTo赋值后一起传过去!从而实现进程之间的通信!
参考:http://blog.csdn.net/lmj623565791/article/details/47017485