Messager实现IPC通信,底层也是使用了AIDL方式。和AIDL方式不同的是,Messager方式是利用Handler形式处理,因此,它是线程安全的,这也表示它不支持并发处理;而AIDL方式是非线程安全的,支持并发处理,因此,我们使用AIDL方式时需要保证代码的线程安全。大部分情况下,我们应用中不需要并发处理。因此,我们通常只需要使用Messager方式。
在我们的例子中:ClientActivity和Service分数不同的进程,我们在Client绑定Service的时候可以获得Service端的Messenger,在Client端通过Messenger发送消息到Service端,将消息交给handler 去处理,同样Service端也可以通过Client端的Messenger进行同样的操作。
为了让Service运行在其他的进程,我们需要在Manifest.xml中做一些设置:
<service
android:name="com.flyingduck.servicedemo2.MessengerService"
android:process=":remote" >
</service>
android:name=“:remote”写法是任意的,可以写成其他的字符串,但是必须要加上‘:’的前缀。客户端进程:
package com.flyingduck.servicedemo2;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
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.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class ClientActivity extends Activity {
private TextView showTxt;
private Button sendMsg;
private Button boundBtn;
private Button unboundBtn;
private ServiceConnection conn;
private final Messenger mMessenger = new Messenger(new IncomingHandler());
/** 服务端的Messenger **/
private Messenger serviceMessenger;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
showTxt = (TextView) findViewById(R.id.show_message);
sendMsg = (Button) findViewById(R.id.send_set_value_message);
boundBtn = (Button) findViewById(R.id.bound_service);
unboundBtn = (Button) findViewById(R.id.unbound_service);
boundBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
doInBindService();
}
});
unboundBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
doInUnBindService();
}
});
sendMsg.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
showTxt.setText("send set_value_message");
if (serviceMessenger != null) {
try {
// 发送一个100 值到service
Message msg = Message.obtain(null,
MessengerService.MSG_SET_VALUE, 100, 0);
msg.replyTo = mMessenger;
serviceMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
});
conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
showTxt.setText("disconnectes");
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
serviceMessenger = new Messenger(service);
showTxt.setText("connectes");
try {
Message msg = Message.obtain(null,
MessengerService.MSG_REGISTER_CLIENT);
msg.replyTo = mMessenger;
serviceMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
};
}
private void doInBindService() {
showTxt.setText("bind");
bindService(new Intent(this, MessengerService.class), conn,
Service.BIND_AUTO_CREATE);
}
private void doInUnBindService() {
showTxt.setText("unbind");
unbindService(conn);
if (serviceMessenger != null) {
try {
Message msg = Message.obtain(null,
MessengerService.MSG_UNREGISTER_CLIENT);
msg.replyTo = mMessenger;
serviceMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
/** 用于处理服务发过来的消息 **/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MessengerService.MSG_SET_VALUE:
showTxt.setText("received from service:" + msg.arg1);
break;
default:
super.handleMessage(msg);
}
}
}
}
Service端:
package com.flyingduck.servicedemo2;
import java.util.ArrayList;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.widget.Toast;
public class MessengerService extends Service {
private NotificationManager notifyM;
/** 用于记录所有绑定service的客户端 这里只有一个client绑定这个service**/
ArrayList<Messenger> clients = new ArrayList<Messenger>();
private final Messenger mMessenger = new Messenger(new IncomingHandler());
/** 定义几种Handler的消息类型 **/
static final int MSG_REGISTER_CLIENT = 1;
static final int MSG_UNREGISTER_CLIENT = 2;
static final int MSG_SET_VALUE = 3;
/** 用于发送消息时使用 **/
private int value = 100;
/** 用于处理客户端发过来的消息 **/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_REGISTER_CLIENT:
clients.add(msg.replyTo);
break;
case MSG_UNREGISTER_CLIENT:
clients.remove(msg.replyTo);
break;
case MSG_SET_VALUE:
for (int index = clients.size() - 1; index >= 0; index--) {
try {
//接收到ClientActivity发送过来的值“100”,再加上value ,发送给ActivityClient
clients.get(index).send(
Message.obtain(null, MSG_SET_VALUE, value+msg.arg1, 0));
} catch (RemoteException e) {
clients.remove(index);
}
}
break;
default:
super.handleMessage(msg);
break;
}
}
}
@Override
public void onCreate() {
notifyM = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
showNotification();
}
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
private void onDestor() {
notifyM.cancel(100);
Toast.makeText(this, "service distory", Toast.LENGTH_SHORT).show();
}
private void showNotification() {
Notification notification = new Notification(R.drawable.ic_launcher,
"Service start...", System.currentTimeMillis());
notification.setLatestEventInfo(this, "content-title",
"service started", null);
notifyM.notify(100, notification);
}
}
client 发送了一个100整数给service端,service将 其加上100发送给client端显示。
运行截图: