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

【Android开发艺术探索】IPC机制(三)-使用Messenger进行跨进程通信

2016-10-02 22:54 501 查看

使用Messenger进行跨进程通信

翻译为中文就是信息的意思,通过它可以在不同进程中传递Message对象,是一种轻量级的IPC方案。底层是AIDL。通过源代码容易看出来。

构造方法A:
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
构造方法B:
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}


判断两个Messenger是不是相等:

/**
* Comparison operator on two Messenger objects, such that true
* is returned then they both point to the same Handler.
*/
public boolean equals(Object otherObj) {
if (otherObj == null) {
return false;
}
try {
return mTarget.asBinder().equals(((Messenger)otherObj)
.mTarget.asBinder());
} catch (ClassCastException e) {
}
return false;
}


一次只能处理一个请求。服务端不存在并发执行的情形。

Message对象的obj字段在2.2之前不能进行跨进程传输,在2.2之后,只能传输那些系统实现了Parcelable的对象,自定义的实现Parcelable的对象不能传输。所以我们使用它的setData方法。

Messenger工作原理



具体代码实现:

一个服务,作为服务端:

package com.example.ipc.messager;

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;

/**
* 充当服务器端,这个服务运行在一个新的进程中
* 客户端远程跨进程通信
*/
public class ServerService extends Service {
private static final int FROM_CLIENT = 0;
private Messenger messenger = new Messenger(new ServiceHandler());
public ServerService() {
}

class ServiceHandler extends Handler{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case FROM_CLIENT:
Log.d("666","服务器端收到客户端数据:"+msg.getData().getString("data"));
Messenger client = msg.replyTo;
Message obtain = Message.obtain(null, 1);
Bundle bundle = new Bundle();
bundle.putString("data","我是服务端");
obtain.setData(bundle);
obtain.replyTo = messenger;
try {
client.send(obtain);
} catch (RemoteException e) {
e.printStackTrace();
}
break;

}
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return messenger.getBinder();
}
}


一个Activity充当客户端:

package com.example.ipc.messager;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import com.example.administrator.testfortemplate.R;

public class ClientActivity extends AppCompatActivity {

private static final int FROM_SERVER = 1;
private final Messenger activityMessager = new Messenger(new ActivityHandler());
class ActivityHandler extends Handler{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case FROM_SERVER:
Log.d("666","客户端收到服务器端数据:"+msg.getData().getString("data"));
Messenger client = msg.replyTo;
Message obtain = Message.obtain(null,0);
Bundle bundle = new Bundle();
bundle.putString("data","Hi:我是客户端");
obtain.setData(bundle);
obtain.replyTo = activityMessager;
try {
client.send(obtain);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
bindService(new Intent(this,ServerService.class),new MyConnection(),BIND_AUTO_CREATE);
}

class MyConnection implements ServiceConnection{

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Messenger messenger = new Messenger(service);
Message obtain = Message.obtain(null, 0);
Bundle bundle = new Bundle();
bundle.putString("data","我是客户端");
obtain.setData(bundle);
obtain.replyTo = activityMessager;
try {
messenger.send(obtain);
} catch (RemoteException e) {
e.printStackTrace();
}
}

@Override
public void onServiceDisconnected(ComponentName name) {

}
}
}


清单文件:

<service
android:name="com.example.ipc.messager.ServerService"
android:enabled="true"
android:exported="true"
android:process=":remote"></service>


设置了process两者才是不在同一个进程中。否则这个例子就不是跨进程通信了。具体原因见【Android开发艺术探索】IPC机制(一)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  messenger ipc android