我们知道在Android开发中通讯传值是经常能够遇到的,像进程内部 进程与进程之间,如果是在进程内部 我们可以通过接口回调 或者EventBus来实现,尤其是第二个 在各个界面间传值非常方便,然而 如果是跨进程 的话他就隔屁了
什么时候应用会有多进程呢
比如在一个应用中要使用定位的功能,定位服务就可以交给一个进程去处理,第三方的服务都可以这样去提供,这样定位问题就很快了
在多进程中有多种实现方式比如自定义监听(不太现实),广播(用于进程唤醒)还有本文要讲述的Messenger(信使)
客户端发信息给服务端 ,服务端处理完之后再把反馈信息传递给客户端,然后客户端据此作出反馈
Messenger这个类的注释:
This allows for the implementation of message-based communication across processes允许实现基于消息的进程间通信的方式
我们可以在客户端发送一个Message给服务端,在服务端的handler中会接收到客户端的消息,然后进行对应的处理,处理完成后,再将结果等数据封装成Message,发送给客户端,客户端的handler中会接收到处理的结果。
这样的进程间通信是不是很爽呢?
1.基于Message,相信大家都很熟悉
2.支持回调的方式,也就是服务端处理完成长任务可以和客户端交互
3.不需要编写aidl文件
此外,还支持,记录客户端对象的Messenger,然后可以实现一对多的通信;甚至作为一个转接处,任意两个进程都能通过服务端进行通信
客户端代码:
/**
* 如果需要服务跟远程进程通信,那么就可以使用Messenger对象来给服务提供接口。
* 这种技术允许你在不使用AIDL的情况下执行进程间通信(IPC)。
*以下是信使(Messenger)对象的使用概要:
*1.服务端实现的一个处理器(Handler接口),这个处理器针对每次来自客户端的调用接收一次回调;
*2.这个处理器被用于创建一个信使对象(Messager)(这个信使对象要引用这个处理器);
*3.信使对象创建一个创建一个服务端从onBind()方法中返回给客户端的IBinder对象;
*4.客户端使用这个IBinder对象来实例化这个信使对象(信使引用了服务端的处理器),
* 客户端使用这个信使给服务端发送Message对象;
*5.服务端在它的处理器(Handler)的handleMessage()方法中依次接收每个Message对象
*在这种方法中,没有给客户端提供服务端的方法调用,相反,客户端会给发送服务端消息(Message)对象,
* 服务端会在它的处理器中接受这些消息对象。
*/
public class Second extends AppCompatActivity{
private TextView mTvState;
private boolean isConn;
private MyConn conn;
// 客户端的信使
private Messenger clientMessenger;
// 客户单的"地址":
private Messenger clientAddress = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 2:
int serverMsg = msg.arg1;
Log.i("TAG", "服务端回复的消息=" + serverMsg);
break;
}
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
mTvState = (TextView) findViewById(R.id.mTvState);
}
// 按钮点击事件种,进行信息的传递:"青鸟发消息给吴刚"
public void communication(View v) {
try {
// 客户端的消息
Message clientMsg = Message.obtain();
clientMsg.what = 1;
clientMsg.arg1 = 100;
// 客户端要告诉服务端:我自己的地址是....
clientMsg.replyTo = clientAddress;
// 客户端的信使给服务端的信使发消息
if(isConn){
clientMessenger.send(clientMsg);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onResume() {
super.onResume();
Intent service = new Intent("messenger");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
service.setPackage("com.longlian.messenger");
}
conn = new MyConn();
bindService(service, conn, BIND_AUTO_CREATE);
}
@Override
protected void onPause() {
super.onPause();
if (conn != null) {
unbindService(conn);
}
}
// 客户端和服务端建立连接
class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 得到客户端的信使---->青鸟
clientMessenger = new Messenger(service);
isConn = true;
mTvState.setText("connected!");
}
@Override
public void onServiceDisconnected(ComponentName name) {
clientMessenger = null;
isConn = false;
mTvState.setText("disconnected!");
}
}
}
//服务端代码
public class MessengerServer extends Service {
// 信使--->青鸟殷勤为探看
// 服务端的信使:----->"吴刚"
private Messenger serverMessenger = new Messenger(new ServerHandler());
// 服务端进行消息的处理和发送
class ServerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
// 取出客户端发送过来的消息
int clientMsg = msg.arg1;
Log.i("TAG", "客户端的消息=" + clientMsg);
// 服务端给客户端回复信息
// 取出客户端的"地址"
Messenger clientAddress = msg.replyTo;
try {
// 服务端的信息
Message serverMsg = Message.obtain();
serverMsg.what = 2;
serverMsg.arg1 = 200;
// 给客户端回复信息
clientAddress.send(serverMsg);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
}
@Override
public IBinder onBind(Intent intent) {
return serverMessenger.getBinder();//获取IBinder对象.
}
}
在清单文件注明服务端是在单独的进程中
<service android:name=".MessengerServer"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="messenger" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
周一快乐