Android进程间通信 Messenger 允许实现基于消息的进程间通信的方式
可以看到,我们可以在客户端发送一个Message给服务端,在服务端的handler中会接收到客户端的消息,然后进行对应的处理,处理完成后,再将结果等数据封装成Message,发送给客户端,客户端的handler中会接收到处理的结果。此外,还支持,记录客户端对象的Messenger,然后可以实现一对多的通信
Messenger使用步骤
以下是如何使用Messenger的步骤:
1. Service需要实现一个Hanlder,用以处理从客户端收到的消息
2. 用该Handler创建一个Messenger对象,Messenger对象内部会引用该Handler对象
3. 用创建好的Messenger对象获得一个IBinder实例,并且将该IBinder通过Service的onBind方法返回给各个客户端
4. 客户端通过收到的IBinder对象实例化一个Messenger对象,该Messenger内部指向指向Service中的Handler。客户端通过该Messenger对象就可以向Service中的Hanlder发送消息。
5. Service中的Hanlder收到消息后,在Handler中的handleMessage方法中处理消息。
6. 通过上面的第4步与第5步,就完成了客户端向Service发送消息并且Service接收到消息的单向通信过程,即客户端 -> Service。如果要实现Service向客户端回消息的通信过程,即Service -> 客户端,那么前提是在客户端中也需要像Service一样内部维护有一个指向Handler的Messenger。当在第四步中客户端向Service发送信息时,将Message的replyTo属性设置为客户端自己的Messenger。这样在第5步Service在Handler的handleMessage中处理收到的消息时,可以通过Message的Messenger再向客户端发送Message,这样客户端内维护的Handler对象就会收到来自于Service的Message,从而完成Service向客户端发送消息且客户端接收到消息的通信过程。
综上六步就能完成客户端与Service的跨进程双向通信过程:
客户端 -> Service -> 客户端
Messenger Server端
package com.fate.messengerserver;
import android.app.Service;
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.util.Log;
public class MessengerService extends Service {
private static final int MSG_SUM = 0x110;
//clientMessenger表示的是客户端的Messenger,可以通过来自于客户端的Message的replyTo属性获得,
//其内部指向了客户端的ClientHandler实例,可以用clientMessenger向客户端发送消息
private Messenger clientMessenger = null;
//serviceMessenger是Service自身的Messenger,其内部指向了ServiceHandler的实例
//客户端可以通过IBinder构建Service端的Messenger,从而向Service发送消息,
//并由ServiceHandler接收并处理来自于客户端的消息
private Messenger serviceMessenger = new Messenger(new ServiceHandler());
//MyService用ServiceHandler接收并处理来自于客户端的消息
private class ServiceHandler extends Handler {
@Override
public void handleMessage(Message msgfromClient) {
Message msgToClient = Message.obtain(msgfromClient);//返回给客户端的消息
switch (msgfromClient.what)
{
//msg 客户端传来的消息
case MSG_SUM:
msgToClient.what = MSG_SUM;
try
{
//模拟耗时
Thread.sleep(1000);
msgToClient.arg2 = msgfromClient.arg1 + msgfromClient.arg2;
//通过Message的replyTo获取到客户端自身的Messenger,
//Service可以通过它向客户端发送消息
clientMessenger = msgfromClient.replyTo;
clientMessenger.send(msgToClient);
Log.i("fate","Messenger Server -> result "+msgToClient.arg2);
} catch (InterruptedException e)
{
e.printStackTrace();
} catch (RemoteException e)
{
e.printStackTrace();
}
break;
}
super.handleMessage(msgfromClient);
}
}
@Override
public void onCreate() {
Log.i("fate", "Messenger Server -> onCreate");
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
Log.i("fate", "Messenger Server -> onBind");
//获取Service自身Messenger所对应的IBinder,并将其发送共享给所有客户端
return serviceMessenger.getBinder();
}
@Override
public void onDestroy() {
Log.i("fate", "Messenger Server -> onDestroy");
clientMessenger = null;
super.onDestroy();
}
}
服务端就一个Service,可以看到代码相当的简单,只需要去声明一个Messenger对象,然后onBind方法返回mMessenger.getBinder();
然后坐等客户端将消息发送到handleMessage想法,根据message.what去判断进行什么操作,然后做对应的操作,最终将结果通过 msgfromClient.replyTo.send(msgToClient);返回。
Service注册
<service
android:name=".MessengerService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.fate.messenger.client"></action>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
Messenger Client端
package com.fate.messengerclient;
import android.content.ComponentName;
import android.content.Context;
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 android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private static final String TAG = "fate";
private static final int MSG_SUM = 0x110;
private Button mBtnAdd, mBindBtn, mUnBindBtn;
private LinearLayout mLyContainer;
//显示连接状态
private TextView mTvState;
private Messenger mService;
private boolean isConn;
private Messenger mMessenger = new Messenger(new Handler(){
@Override
public void handleMessage(Message msgFromServer) {
switch (msgFromServer.what) {
case MSG_SUM:
TextView tv = (TextView) mLyContainer.findViewById(msgFromServer.arg1);
tv.setText(tv.getText() + "=>" + msgFromServer.arg2);
break;
}
super.handleMessage(msgFromServer);
}
});
private ServiceConnection mConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("fate","Messenger Client -> onServiceConnected");
mService = new Messenger(service);
isConn = true;
mTvState.setText("connected!");
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i("fate","Messenger Client -> onServiceDisconnected");
mService = null;
isConn = false;
mTvState.setText("disconnected!");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTvState = (TextView) findViewById(R.id.id_tv_callback);
mBtnAdd = (Button) findViewById(R.id.id_btn_add);
mLyContainer = (LinearLayout) findViewById(R.id.id_ll_container);
mBtnAdd.setOnClickListener(this);
//开始绑定服务
bindServiceInvoked();
}
private void bindServiceInvoked() {
Intent intent = new Intent();
intent.setAction("com.fate.messenger.client");
intent.setPackage("com.fate.messengerserver");
bindService(intent, mConn, Context.BIND_AUTO_CREATE);
Log.i("fate", "Messenger Client -> bindService invoked !");
}
@Override
protected void onDestroy() {
Log.i("fate", "Messenger Client -> onDestroy ");
super.onDestroy();
unbindService(mConn);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.id_btn_add:
try {
int a = (int) (Math.random() * 100);
int b = (int) (Math.random() * 100);
//创建一个tv,添加到LinearLayout中
TextView tv = new TextView(MainActivity.this);
tv.setText(a + " + " + b + " = caculating ...");
tv.setId(a);
mLyContainer.addView(tv);
Message msgFromClient = Message.obtain(null, MSG_SUM, a, b);
msgFromClient.replyTo = mMessenger;
if (isConn) {
//往服务端发送消息
mService.send(msgFromClient);
}
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
}
首先bindService,然后在onServiceConnected中拿到回调的service(IBinder)对象,通过service对象去构造一个mService =new Messenger(service);然后就可以使用mService.send(msg)给服务端了。
那么服务端会收到消息,处理完成会将结果返回,传到Client端的mMessenger中的Handler的handleMessage方法中。
fate : Messenger Client -> bindService invoked !
fate : Messenger Server -> onCreate
fate : Messenger Server -> onBind
fate : Messenger Client -> onServiceConnected
fate : Messenger Server -> result 65
fate : Messenger Client -> onDestroy
fate : Messenger Server -> onDestroy
相关文章
http://blog.csdn.net/lmj623565791/article/details/47017485
http://blog.csdn.net/iispring/article/details/48329925
http://blog.csdn.net/qq379454816/article/details/52573476