Android Messenger实现IPC通信

Android Messenger实现IPC通信

Messenger的使用方法很简单,它对AIDL做了封装,并且一次只处理一个请求。

客户端进程中,首先要绑定服务端的服务,绑定成功后使用Serviceconnection中绑定成功回调的IBinder对象创建一个Messenger,通过这个Messenger向服务端发消息。如果需要服务端能够回应客户端,则需要在客户端创建Handler,并使用这个Handler创建一个新的Messenger,将这个Messenger设置到消息Message的replyTo参数传递给服务端,服务端通过replyTo参数就可以给客户端发消息。

服务端进程中,在Service中创建Handler,并使用Handler创建Messenger,使用Messenger的getBinder()方法获得一个IBinder对象在onBind中返回

以下案例中,服务端代码和客户端代码运行在不同的进程中,使用android:process指定。


单向通信 Service端的代码 public class MessengerService extends Service { public static final int MSG_FROM_CLIENT = 0; //服务端的Handler class MessengeHandler extends Handler{ @Override public void handleMessage(Message msg) { switch(msg.what){ case MSG_FROM_CLIENT: String content = msg.getData().getString("content"); Log.d("ZXX", content); break; } super.handleMessage(msg); } } //使用Handler创建Messenger private Messenger messenger = new Messenger(new MessengeHandler()); @Nullable @Override public IBinder onBind(Intent intent) { //返回给客户端的IBinder对象,客户端可用于创建服务端的Messenger return messenger.getBinder(); }} 客户端代码 public class MainActivity extends AppCompatActivity { private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { //用服务端传递过来的IBinder创建Messenger Messenger serviceMessenger = new Messenger(iBinder); Message msg = new Message(); msg.what = 0; Bundle bundle = new Bundle(); bundle.putString("content","这是activity发来的消息"); msg.setData(bundle); try { //用创建的服务端的Messenger发送消息给服务端 serviceMessenger.send(msg); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName componentName) { Log.d("ZXX","onServiceDisconnected"); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(this, MessengerService.class); bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); }}

打出的Log:
08-07 23:02:01.186 3858-3858/com.xin.messenger D/ZXX: 这是activity发来的消息
以上就是客户端发出消息,服务端处理消息的基本实现。主要原理就是服务端在onBind中返回Binder,客户端连接成功后利用Binder得到一个服务端的Messenger,使用这个Messenger给服务端发送消息。

双向通信

双向通信主要就是让服务端能够发消息回应客户端,原理和单向通信相同。服务端需要得到客户端的Messenger,并使用它发送消息。主要实现就是客户端中定义Handler,使用Handler创建客户端的Messenger,在给服务端发请求时,利用消息Message对象的replyTo参数将客户端的Messenger传送给服务端。而后服务端在处理完客户端的消息时得到该Messenger,使用它发送消息给客户端。

客户端代码 public class MainActivity extends AppCompatActivity { //客户端的Handler private class MessengerHandler extends Handler{ @Override public void handleMessage(Message msg) { switch (msg.what){ case 0: String content = msg.getData().getString("servicereturn"); Log.e("ZXX",content); } super.handleMessage(msg); } } private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { //客户端的Messenger Messenger clientMessenger = new Messenger(new MessengerHandler()); //服务端的Messenger Messenger serviceMessenger = new Messenger(iBinder); Message msg = new Message(); msg.what = 0; //将客户端的Messenger设置到消息中,随消息发送给服务端 msg.replyTo = clientMessenger; Bundle bundle = new Bundle(); bundle.putString("content","这是activity发来的消息"); msg.setData(bundle); try { serviceMessenger.send(msg); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName componentName) { Log.d("ZXX","onServiceDisconnected"); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(this, MessengerService.class); bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); }} 服务端代码 public class MessengerService extends Service { public static final int MSG_FROM_CLIENT = 0; class MessengeHandler extends Handler{ @Override public void handleMessage(Message msg) { switch(msg.what){ case MSG_FROM_CLIENT: String content = msg.getData().getString("content"); Log.d("ZXX", content); Message newmsg = new Message(); Bundle bundle = new Bundle(); bundle.putString("servicereturn","这是服务端发出的消息"); newmsg.setData(bundle); newmsg.what = 0; try { //使用replyTo得到的客户端Messenger发送消息给客户端 msg.replyTo.send(newmsg); } catch (RemoteException e) { e.printStackTrace(); } break; } super.handleMessage(msg); } } private Messenger messenger = new Messenger(new MessengeHandler()); @Nullable @Override public IBinder onBind(Intent intent) { return messenger.getBinder(); }}

Log如下:
08-07 23:27:40.963 5277-5277/com.xin.messenger D/ZXX: 这是activity发来的消息
08-07 23:27:41.127 5261-5261/com.example.xin.messengerdemo E/ZXX: 这是服务端发出的消息
这两条log是在不同进程中打出的,一个是com.xin.messenger,一个是com.example.xin.messengerdemo