Messenger可以翻译为信使,使用它我们可以进行跨进程通讯.Messengers是一种轻量的IPC,通过构造方法可以轻松的看出它的底层是现实AIDL.
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
Messenger的使用方法很简单
需要在服务端创建一个Service,来处理客户端的连接请求,同时创建一个Handler来处理接受到的消息,然后在通过Handler创建一个Messenger对象,最后在Service的onBind()
方法中返回Messenger的Binder对象即可.
package com.lixxy.service;
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.support.annotation.Nullable;
import android.util.Log;
public class MessengerService extends Service {
private static final String TAG = "MessengerService";
private final Messenger mMessenger = new Messenger(new MessengerHandler());
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "连接了");
return mMessenger.getBinder();
}
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 100:
//获取client发送的消息
Log.e(TAG, msg.getData().getString("client"));
//收到消息后给client发送消息
Messenger client = msg.replyTo;
Message message = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString("service", "Hello,Client");
message.setData(bundle);
message.what = 200;
try {
client.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
}
}
服务端的service配置
在AndroidManifest中加入
<!--permission可加可不加,如果加上的话,在cleint中也要加上-->
<service android:name=".MessengerService"
android:exported="true"
android:permission="com.lixxy.client.service">
</service>
首先要绑定服务端的service,然后在ServiceConnection中就可以通过IBinder发送消息.
@Override
//bind方法需要三个参数,intent,ServiceConnection,flags
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
return mBase.bindService(service, conn, flags);
}
//Intent
//由于服务端和客服端是两个APP,所以不能通过Intent intent = new //Intent(this,MessengerService.class);获取Intent
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.lixxy.service","com.lixxy.service.MessengerService"));
//private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Messenger messenger = new Messenger(service);
Bundle bundle = new Bundle();
bundle.putString("client", "Hello,Services");
Message message = Message.obtain();
message.what = 100;
message.setData(bundle);
//如果客户端同时要接受服务器发的消息,需要加这句
message.replyTo = mMessenger;
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e(TAG, "连接失败");
}
};
如果客户端同时要接受服务器发的消息,也要创建一个Handler处理消息,然后通过这个Handler来创建Messenger对象.
完整的客户端代码如下
package com.lixxy.client;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.nfc.Tag;
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;
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivity";
private final Messenger mMessenger = new Messenger(new MessengerHandler());
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 200:
//获取service发送的消息
Log.e(TAG, msg.getData().getString("service"));
break;
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.mBtnBind);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//由于服务端和客服端是两个APP,所以不能通过
// Intent intent = new //Intent(this,MessengerService.class)获取Intent
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.lixxy.service", "com.lixxy.service.MessengerService"));
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
});
}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Messenger messenger = new Messenger(service);
Bundle bundle = new Bundle();
bundle.putString("client", "Hello,Services");
Message message = Message.obtain();
message.what = 100;
message.setData(bundle);
//如果客户端同时要接受服务器发的消息,需要加这句
message.replyTo = mMessenger;
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e(TAG, "连接失败");
}
};
}
注意:如果服务端的service中加了android:permission:“xxx.xxx.xxx”,那么在客户端的AndroidManifest也要加入权限,不然会报错Not allowed to bind to service Intent
<permission android:name="com.lixxy.client.service" />
<uses-permission android:name="com.lixxy.client.service" />
https://github.com/Lillls/MessengerDemo