Messenger在跨进程通信中的使用
事先说明:
本人也是个初学者,所以本文是从初学者的角度入手,如果有不妥的地方请留言教导我,谢谢。
本篇文章主要针对讲解Messenger的使用和Messenger在应用层上的原理解析和Messenger在服务端的回复。
什么是Messenger?
Messenger可以翻译为信使,Messenger是一种轻量级的IPC方案,通过它可以在不同进程中传递Message对象,在Message中放入我们需要传递的数据,就可以实现数据的进程间传递了。
步骤一:Messenger的使用
服务端的编写:
public class MessagerService extends Service {
//标识
public static final int GET_RESULT = 1;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
private final Messenger mMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case GET_RESULT:
Log.i("服务端的消息:" , msg.getData().getString("data"));
break;
default:
super.handleMessage(msg);
break;
}
}
});
}
在manifests中配置service:
<service
android:name=".Messager.MessagerService"
android:exported="true" />
客户端的编写(在另一个应用中):
public class MessengerActivity extends AppCompatActivity {
//标识
public static final int GET_RESULT = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
//绑定服务
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.handsome.boke", "com.handsome.boke.Messager.MessagerService"));
bindService(intent, conn, BIND_AUTO_CREATE);
}
/**
* 服务回调方法
*/
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//获得消息者
Messenger messenger = new Messenger(service);
//创建空消息
Message message = Message.obtain(null, GET_RESULT);
Bundle bundle = new Bundle();
bundle.putString("data", "这是客户端发过去的消息");
//往消息中存数据
message.setData(bundle);
//消息者发送消息
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onDestroy() {
super.onDestroy();
//解绑服务,回收资源
unbindService(conn);
}
}
启动服务端的Activity,并开启服务:
public class LoginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
startService(new Intent(this, MessagerService.class));
}
}
接着启动客户端,查看测试结果:
08-21 06:18:25.521 4154-4154/com.handsome.boke I/服务端的消息:: 这是客户端发过去的消息
步骤二:Messenger在应用层上的原理解析
我们追随到Messenger的创建方法中,查看源码可以知道,底层是使用AIDL:
/**
* Create a Messenger from a raw IBinder, which had previously been
* retrieved with {@link #getBinder}.
*
* @param target The IBinder this Messenger should communicate with.
*/
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
关于AIDL的使用和原理分析,这里参照我的CSDN博客,里面有详细的分析,Android基础——初学者必知的AIDL在应用层上的Binder机制,http://blog.csdn.net/qq_30379689/article/details/52253413
步骤三:Messenger可以接受到客户端的消息后进行回复,这里就类似于邮箱自动回复的功能
改一下服务端的代码:
public class MessagerService extends Service {
//标识
public static final int GET_RESULT = 1;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
private final Messenger mMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case GET_RESULT:
Log.i("服务端的消息:" , msg.getData().getString("data"));
//------------------------修改的代码----------------------
//接受到消息后,进行回复
//通过replyTo拿到Messenger对象
Messenger messenger = msg.replyTo;
Message message = Message.obtain(null,GET_RESULT);
Bundle bundle = new Bundle();
bundle.putString("reply","好的,我收到你的信息了");
message.setData(bundle);
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
super.handleMessage(msg);
break;
}
}
});
}
改一下客户端的代码:
public class MessengerActivity extends AppCompatActivity {
//标识
public static final int GET_RESULT = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
//绑定服务
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.handsome.boke", "com.handsome.boke.Messager.MessagerService"));
bindService(intent, conn, BIND_AUTO_CREATE);
}
/**
* 服务回调方法
*/
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//获得消息者
Messenger messenger = new Messenger(service);
//创建空消息
Message message = Message.obtain(null, GET_RESULT);
Bundle bundle = new Bundle();
bundle.putString("data", "这是客户端发过去的消息");
//---------------------------修改的代码--------------------------
message.replyTo = replyMessenger;
//往消息中存数据
message.setData(bundle);
//消息者发送消息
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onDestroy() {
super.onDestroy();
//解绑服务,回收资源
unbindService(conn);
}
//---------------------------修改的代码--------------------------
private Messenger replyMessenger = new Messenger(new MessengerHandler());
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case GET_RESULT:
Log.i("客户端的消息:", msg.getData().getString("reply"));
break;
default:
super.handleMessage(msg);
break;
}
}
}
}
查看我们的测试结果:
08-21 07:34:51.032 12808-12808/com.handsome.boke I/服务端的消息:: 这是客户端发过去的消息
08-21 07:34:51.224 12784-12784/com.handsome.app2 I/客户端的消息:: 好的,我收到你的信息了