Messenger是实现进程通讯的一个工具,只不过它是单线程实现的那么他是怎么实现单线程的呢?
这里有一个例子:Android 基于Message的进程间通信 Messenger完全解析 通信实例
看一下服务端service中的代码:
public class MessengerService extends Service {
private static final int MSG_SUM = 0x110;
private Messenger mMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
Message message = Message.obtain(msg);
switch (msg.what) {
case MSG_SUM:
msg.what = MSG_SUM;
try {
Thread.sleep(2000);
message.arg2 = msg.arg1 + msg.arg2;
msg.replyTo.send(message);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
super.handleMessage(msg);
}
});
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
}
比较简单,只是实现了一个Messenger,并在onBind()中返回mMessenger中的binder。
那么我们来看一下Messenger的构造方法。
private final IMessenger mTarget;
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
这个构造方法就是将Handler中的IMessenger对象取出来赋值给自己的mTarget。
那么我们再看一下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);
}
}
这里就有一个类IMessenger,他就是ALDL生成的一个类,前面Binder应用层架构–AIDL从自动生成到手动编写 已经讲过。方法send是IMessenger里定义的抽象方法(比较重要,下面会讲)。这里实现的是Handler将Message插入队列MessageQueue。这就是Messenger的一个构造方法。
mMessenger.getBinder()呢?
public IBinder getBinder() {
return mTarget.asBinder();
}
这里返回的是IMessenger的asBinder方法,然后在IMessenger中找到源码:
public android.os.IBinder asBinder() {
return this;
}
这里返回的是IMessenger.Stub,它继承了Binder类和IMessenger接口。
然后我们看一下客户端的代码:
public class MainActivity extends AppCompatActivity {
private static final int MSG_SUM = 0x110;
private Button add;
private Messenger mService;
private boolean isConn = false;
Messenger mMessemger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SUM:
break;
}
super.handleMessage(msg);
}
});
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = new Messenger(service);
isConn = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
isConn = false;
}
};
private int value;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
add = (Button) findViewById(R.id.add);
bind();
add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int a = value++;
int b = (int) (Math.random() * 100);
Message message = Message.obtain(null, MSG_SUM, a, b);
message.replyTo = mMessemger;
if(isConn){
try {
mService.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
});
}
private void bind() {
Intent intent = new Intent();
intent.setAction("com.demo.ln.service");
bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(connection);
}
}
这里我们就按照操作顺序来捋一下。
当向服务端发送消息时,会初始化一个消息,这个消息会携带Messenger即message.replyTo = mMessemger;那么mMessemger是怎么来的,我们来看一下源码:
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
也是通过Handler获得的,也就是说Handler中会新建一个Messenger,并将它赋值给msg。
然后Messenger向服务端发送消息mService.send(message);mService也是一个Messenger类,它是怎么来的呢? 代码中是这样写的mService = new Messenger(service);我们看一下源码:
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
再来看一下,IMessenger.Stub.asInterface的源码:
public static android.os.IMessenger asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof android.os.IMessenger))) {
return ((android.os.IMessenger) iin);
}
return new android.os.IMessenger.Stub.Proxy(obj);
}
Proxy:
private static class Proxy implements android.os.IMessenger {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
public void send(android.os.Message msg)throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((msg != null)) {
_data.writeInt(1);
msg.writeToParcel(_data, 0);// 将msg所有字段(what,obj)写到_data中去
} else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_send, _data, null,
// // 接收的code和发送的code都是TRANSACTION_send
android.os.IBinder.FLAG_ONEWAY);
} finally {
_data.recycle();
}
}
}
现在找到根了,mService 其实就是Proxy的一个实例,mService.send(message)执行的就是Proxy类的send方法,msg.writeToParcel(_data, 0)将msg所有字段(what,obj)写到_data中去,这就是ALDL的向服务端传msg。writeToParcel()方法的源码:
public void writeToParcel(Parcel dest, int flags) {
if (callback != null) {
throw new RuntimeException(
"Can't marshal callbacks across processes.");
}
dest.writeInt(what);
dest.writeInt(arg1);
dest.writeInt(arg2);
if (obj != null) {
try {
Parcelable p = (Parcelable)obj;
dest.writeInt(1);
dest.writeParcelable(p, flags);
} catch (ClassCastException e) {
throw new RuntimeException(
"Can't marshal non-Parcelable objects across processes.");
}
} else {
dest.writeInt(0);
}
dest.writeLong(when);
dest.writeBundle(data);
Messenger.writeMessengerOrNullToParcel(replyTo, dest);
dest.writeInt(sendingUid);
}
可以看出这个方法就是将msg拆开,一个一个的向服务端传过去。这就是ALDL向服务端传数据。
然后ALDL中IMessenger.Stub类的onTransact方法接收数据,来看一下IMessenger.Stub类中的onTransact方法:
@Override
public boolean onTransact(int code, android.os.Parcel data,android.os.Parcel reply, int flags)throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_send: {
// 接收的code和发送的code都是TRANSACTION_send
data.enforceInterface(DESCRIPTOR);
android.os.Message _arg0;
if ((0 != data.readInt())) {
// data.readInt为1(当msg不为空时)
_arg0 = android.os.Message.CREATOR.createFromParcel(data);
} else {
_arg0 = null;
}
this.send(_arg0);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
android.os.Message.CREATOR.createFromParcel(data)方法就是接收数据。接受完之后处理数据this.send(_arg0);这个this是哪一个呢?
在这里目前有三个IMessenger的对象,也就有三个send方法,一个是IMessenger.stub.Proxy对象 ,一个是客户端Handler里边的MessengerImpl对象,一个是服务端Handler里边的MessengerImpl对象,这个this指代的是IMessenger.stub对象,Proxy没有继承 IMessenger.stub,所以排除了。以为这时候已经把数据传到服务端进程,所以这个this指的是服务端Handler里边的MessengerImpl对象。MessengerImpl类的send源码:
public void send(Message msg) {
msg.sendingUid = Binder.getCallingUid();
Handler.this.sendMessage(msg);
}
看到这是不是很熟悉,不熟悉的看一下Handler通信机制 ,剩下的就是通过Handler进行数据的传递,放入MessageQueue队列之中,一个个的处理,最后在服务端service.Messenger的handleMessage中处理问题。
public void handleMessage(Message msg) {
Message message = Message.obtain(msg);
switch (msg.what) {
case MSG_SUM:
msg.what = MSG_SUM;
try {
Thread.sleep(2000);
message.arg2 = msg.arg1 + msg.arg2;
msg.replyTo.send(message);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
super.handleMessage(msg);
}
在这个方法中,msg.replyTo.send(message)向客户端返回信息。msg.replyTo就是message自带的Messenger,就是从客户端传过来的mService。
在这个过程中,一共用了三个Messenger,分别是mService,客户端的mMessenger,服务端的mMessenger。
这三个对象中只有mService是传递消息的,剩下的两个分别在自己所在的进程进行消息的接收和处理。这个地方描述的或许不准确,若有问题请告知。
参考资料: