Messenger信使,基于AIDL实现的进程间通讯的一种简化方式,但是我用的时候感觉没有AIDL简单,因为发送与接收都要写很多的代码去实现传递过程,AIDL却简洁的多,规定传递哪些值,直接去实现就可以了。
既然Messenger是基于AIDL实现的,那么它与AIDL有什么区别呢?
1:Messenger是通过Bundle传递数据,多以只能传递基本数据类型,而AIDL可以传递实体类
2:Messenger适合传递数据少,数据量小的情况,AIDL适合数据多,数据量大的情况
3:Messenger返回值是异步的,AIDL是同步的
有什么相似呢?
AIDL是分客户端跟服务端的,只能是客户端主动调服务端,而服务端无法主动调用客户端,只能通过return的方式返数据给客户端。
Messenger貌似好像可以互相通讯,但是别忘了它是基于AIDL实现的,他其实也有这个特性,只不过因为是异步的所以没那么明显,但是其实它也是必须先客户端访问服务端,服务端才能返回数据给客户端,这一点十分的重要!
我实现的功能是需要服务端去定位然后把定位信息传递给客户端,下面是代码:
客户端:
public class LocationReceiver extends BroadcastReceiver {
private Context context;
@Override
public void onReceive(Context context, Intent intent) {
this.context = context;
doWork();
}
//实现serviceConnection对象
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Messenger serviceMessenger = new Messenger(service);
Message message = Message.obtain(null, OpenLocationService.MSG_FROM_CLIENT);
//把messenger对象赋值给message.replyTo,保证服务端返回的消息,我们可以在messenger中收到
message.replyTo = messenger;
try {
//就算是空消息也要发,因为只有先客户端发消息,服务端才能回复
serviceMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
private Messenger messenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
//接收服务端传回来的数据
super.handleMessage(msg);
Bundle bundle = msg.getData();
String lat = bundle.getString("lat");
String lon = bundle.getString("lon");
Log.i("TAG","lat:"+lat);
Log.i("TAG","lon :"+lon);
context.getApplicationContext().unbindService(serviceConnection);
}
});
private void doWork() {
//绑定服务
Intent intent = new Intent(context, OpenLocationService.class);
//因为我是同一个项目下不同进程,所以可以直接绑定
context.getApplicationContext().bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
}
服务端:
public class OpenLocationService extends Service {
private Messenger replyTo;
public static final int MSG_FROM_CLIENT = 123;
public static final int MSG_FROM_SERVICE = 321;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
@Override
public void onCreate() {
super.onCreate();
if (replyTo != null) {
Message message = Message.obtain(null, MSG_FROM_SERVICE);
Bundle bundle = new Bundle();
bundle.putString("lat", "40.087379");
bundle.putString("lon", "116.610951");
message.setData(bundle);
try {
replyTo.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
private Messenger messenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//这里就可以看到客户端设置的replyTo 的关键之处了
replyTo = msg.replyTo;
}
});
}