IPC for Android 系列:
1、Android IPC
2、Serializable、Parcelable、Binder的使用、理解
3、本文Android IPC bindService传递Messenger
4、结合PMS源码讲解AIDLPackageManagerService服务框架
Messenger:信使,可在不同进程间传递Message;轻量级IPC方案,底层实现AIDL;
服务端
第一步:创建一个Service做服务端
public class MessengerService extends Service {
private final Messenger mMessenger = new Messenger(new MessengerHandler());
public static class MessengerHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case Utils.MSG_FROM_CLIENT:
Log.d("yink","client msg = " + msg.getData().getString("msg"));
Messenger client = msg.replyTo;
Message replayMessage = Message.obtain(null,Utils.MSG_FROM_SERVICE);
Bundle data = new Bundle();
data.putString("replay","Msg is arrived!");
replayMessage.setData(data);
try {
if(client != null) {
client.send(replayMessage);
} else {
Log.d("yink","don't replay");
}
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
}
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return mMessenger.getBinder();
}
}
1、定义了一个Messenger,一个Handler;
2、在onBind中返回mMessenger的Ibinder;
3、当客户端发送Messenger发送一个Message消息过来的时候,MessengerHandler就会接收这个消息;
客户端
第二步:绑定服务端bindService
public class MessengerAcitvity extends Activity {
private static Messenger mMesenger;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMesenger = new Messenger(service);
Message msg = Message.obtain(null,Utils.MSG_FROM_CLIENT);
Bundle data = new Bundle();
data.putString("msg","hello this is client");
msg.setData(data);
msg.replyTo = mGetReplayMessenger;
try {
mMesenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
private static Messenger mGetReplayMessenger = new Messenger(new MessengerHandler());
private static class MessengerHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case Utils.MSG_FROM_SERVICE:
Log.d("yink","service msg = " + msg.getData().getString("replay"));
secondMsgTest();
break;
default:
super.handleMessage(msg);
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger_acitvity);
Intent intent = new Intent(this,MessengerService.class);
bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
}
public static void secondMsgTest() {
Message msg = Message.obtain(null,Utils.MSG_FROM_CLIENT);
Bundle data = new Bundle();
data.putString("msg","client second msg");
msg.setData(data);
try {
if(mMesenger != null) {
mMesenger.send(msg);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
unbindService(mConnection);
super.onDestroy();
}
}
1、先看onCreate的bindService,绑定操作;
2、mConnection中onServiceConnected,先得到一个Messenger,看Messenger的构造函数就明白了,标准的binder(不明白的读者可以阅读系列文章的第二篇)
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
然后是封装一条Message消息
Message msg = Message.obtain(null,Utils.MSG_FROM_CLIENT);
Bundle data = new Bundle();
data.putString("msg","hello this is client");
msg.setData(data);
msg.replyTo = mGetReplayMessenger; //注意此句是把mGetReplayMessenger传递给服务端,当服务端发送消息时,通过mGetReplayMessenger创建的handler接收消息
最后mMesenger.send(msg);向服务端发送消息;
接下来我们看客户端和服务端怎么来回交互:
客户端发送完消息后,我们回到服务端代码handleMessage:
1、log打印出接收到的消息
05-11 10:20:07.880 31158 31158 D yink : client msg = hello this is client
2、得到客户端传过来的Messenger
Messenger client = msg.replyTo;
3、封装好一条Message后,再发送回客户端
client.send(replayMessage);
回到客户端代码:
1、mGetReplayMessenger的handleMessage中log打印接收到的消息:
05-11 10:20:07.881 31115 31115 D yink : service msg = Msg is arrived!
2、调用secondMsgTest,发送第二条消息给服务端
这里附加说明一下,在onCreate绑定service后,客户端就单独执行了,若直接发送secondMsgTest,是不会发送的,这个时候mMesenger还是为空;
public static void secondMsgTest() {
Message msg = Message.obtain(null,Utils.MSG_FROM_CLIENT);
Bundle data = new Bundle();
data.putString("msg","client second msg");
msg.setData(data);
try {
if(mMesenger != null) {
mMesenger.send(msg);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
贴出所有log如下:
05-11 10:20:07.880 31158 31158 D yink : client msg = hello this is client
05-11 10:20:07.881 31115 31115 D yink : service msg = Msg is arrived!
05-11 10:20:07.882 31158 31158 D yink : client msg = client second msg
05-11 10:20:07.882 31158 31158 D yink : don't replay