您的位置:首页 > 移动开发 > Android开发

Android IPC之Messager用法示例

2016-04-24 20:18 465 查看
Messager可以翻译为信使,顾名思义,通过它可以在不同进程中传递Message对象,在Message中放入我们需要传递的数据,就可以轻松地实现数据的进程间穿传递了。Messager是一种轻量级的IPC方式,它的底层实现是AIDL。这个大家可以下去看一下Messager的构造方法就知道了。

Messager的使用方法很简单,它对AIDL做了封装,使得我们可以更简便的进行进程间通信。同时,由于它一次处理一个请求,因此在服务器中不存在并发的情形。实现一个Messager有如下几个步骤,分为服务端和客户端。

1,服务端进程

首先,我们需要在服务端创建一个Service来处理客户端的连接请求,同时创建一个Handler并通过它来创建一个Messager对象,然后在Service的onBinder中返回这个Messager对象底层的Binder即可。

代码如下:


package com.example.lenovo.textmyaidl;

import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

/**
* MessaerHandler用来处理客户端发来的消息,并从消息中取出客户端发来的文本消息。而
* messenger是一个Messager对象,它和MessaerHandler相关联,并在onBind方法中返回它里面的Binder
* 对象,可以看出这里的messager的作用就是将客户端发送的消息传递给MessaerHandler处理。
* Created by lenovo on 2016/4/24.
*/
public class MessengerService extends Service {

private  static  final String TAG = "MessengerService";

private static class  MessaerHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case MyContants.MSG_FROM_CLIENT:
Log.e(TAG,"receive msg from client:"+msg.getData().getString("msg"));
Messenger client = msg.replyTo;
Message replyMessage = Message.obtain(null,MyContants.MSG_FROM_SERVICE);
Bundle bundle = new Bundle();
bundle.putString("reply","嗯,你的消息我收到了,稍后回复你!");
replyMessage.setData(bundle);
try {
client.send(replyMessage);
} catch (RemoteException e) {
e.printStackTrace();
}
break;

}
}
}
private final Messenger messenger = new Messenger(new MessaerHandler());
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
}


然后,注册service,让其运行在单独的进程中:

<service android:name=".MessengerService"
android:process=":remote"></service>


2,客户端进程

代码如下:
package com.example.lenovo.textmyaidl;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

public class MainActivity extends Activity {

private static final String TAG = "MainActivity";

private  Messenger mGetMessage = new Messenger(new MessengerHandler());
private Messenger mService;

private  static class  MessengerHandler extends Handler{
@Override
public void handleMessage(Message msg) {

switch (msg.what){
case MyContants.MSG_FROM_SERVICE:
Log.e(TAG,"recive msg from Service:"+msg.getData().getString("reply"));
}
}
}

private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = new Messenger(service);
Message msg = Message.obtain(null,MyContants.MSG_FROM_CLIENT);
Bundle data = new Bundle();
data.putString("msg","hello,this is client");
msg.replyTo = mGetMessage;
msg.setData(data);
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}

@Override
public void onServiceDisconnected(ComponentName name) {

}
};

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Intent intent = new Intent(this,MessengerService.class);
bindService(intent,connection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onDestroy() {
unbindService(connection);
super.onDestroy();
}
}


运行结果:

04-24 11:31:38.632 12385-12385/com.example.lenovo.textmyaidl:remote E/MessengerService:
receive msg from client:
hello,this is client
04-24 11:31:39.060 12363-12363/com.example.lenovo.textmyaidl E/MainActivity: recive msg from Service:
嗯,你的消息我收到了,稍后回复你!


通过上面的例子可以看出来。在Messenger中进行数据传递必须将数据封装到Messenge中。Messenger和Messenge都实现了Parcelable接口,因此可以跨进程传输。简单的来说就是Messenge中所支持的数据类型就是Messenger所支持的传输类型。Messenge的另一个字段object在同一个进程中是很实用的,但是在跨进程中却是由有很大的限制的,只支持系统提供的实现了Parcelable接口的对象的传输,非系统的(自定义的)对象是无法跨进程用object字段来传输的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: