Messenger——Messenger使用和原理
1、概述
Messenger是一种轻量级的IPC通信方案,对AIDL进行了封装,可以在不同进程中传递Message对象。
2、使用Messenger通信
Server端代码
public class MessengerService extends Service {public static final String TAG = "MyMessenger";public static final int MSG_FROMCLIENT = 1000;public static final int MSG_FROMSERVER = 1001;@Overridepublic void onCreate() {super.onCreate();}private Handler mHandler = new Handler(Looper.myLooper()) {@Overridepublic void handleMessage(@NonNull Message msg) {switch (msg.what) {case MSG_FROMCLIENT:Log.d(TAG, "receive message from client:" + msg.getData().getString("msg"));Messenger messenger = msg.replyTo;Message message = Message.obtain(null, MSG_FROMSERVER);Bundle bundle = new Bundle();bundle.putString("rep", "message form server");message.setData(bundle);try {messenger.send(message);} catch (RemoteException e) {e.printStackTrace();}break;}}};@Nullable@Overridepublic IBinder onBind(Intent intent) {return new Messenger(mHandler).getBinder();}
}
Service端接收Client端发送的消息,并返回一个消息。Server端要点是创建Handler对象,并在其handleMessage方法中处理Client端发送的消息。如果要返回消息给Client端,则需要Client发送消息时传递Client端的Messenger对象到Server端。同样的Client端要发送消息到Server端,也是通过Server端传递过去的Messenger对象。
Client端代码
public class MainActivity extends AppCompatActivity {private Handler mHandler = new Handler(Looper.myLooper()) {@Overridepublic void handleMessage(@NonNull Message msg) {switch (msg.what) {case MessengerService.MSG_FROMSERVER:Log.d(MessengerService.TAG, "received message from server: " + msg.getData().getString("rep"));break;}}};private ServiceConnection mServiceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {Messenger messenger = new Messenger(service);Message message = Message.obtain(null, MessengerService.MSG_FROMCLIENT);Bundle bundle = new Bundle();bundle.putString("msg", "message form client");message.setData(bundle);message.replyTo = new Messenger(mHandler);try {messenger.send(message);} catch (RemoteException e) {e.printStackTrace();}}@Overridepublic void onServiceDisconnected(ComponentName name) {}};@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Intent intent = new Intent(this, MessengerService.class);bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);}@Overrideprotected void onDestroy() {super.onDestroy();unbindService(mServiceConnection);}
}
bindService时回调onServiceConnected,获取service返回的IBinder对象,由此重构Messenger对象,并用此Messenger对象发送消息给Server端。同时,如果需要处理Server端返回的消息,则需要创建一个Messenger对象并包含Handler对象,将其设置到Message对象的replyTo属性中,并将其传递到Server端,Server端通过这个replyTo获取的Messenger对象发送消息回Client端。
3、Messenger原理探究
从Messenger的使用中可以看出,Messenger通信依赖Binder、Handler和Message。Handler机制是Android线程间通信的机制,BInder是Android进程间通信的机制。
- 构造函数
public Messenger(Handler target) {mTarget = target.getIMessenger();
}
public Messenger(IBinder target) {mTarget = IMessenger.Stub.asInterface(target);
}
messenger有两个构造函数,分别是传入一个Handler对象和一个IBinder类型的对象作为参数,都会去设置mTarget属性。
先来看一下Handler作为参数的情况,调用的是Handler中的getIMessenger方法。
final IMessenger getIMessenger() {synchronized (mQueue) {if (mMessenger != null) {return mMessenger;}mMessenger = new MessengerImpl();return mMessenger;}
}
返回的是IMessenger对象,如果Handler中已经设置了该对象则直接返回,如果没有设置,则返回一个MessengerImpl对象。MessengerImpl是Handler中的内部类,继承自IMessenger.Stub,并重写了send方法。
private final class MessengerImpl extends IMessenger.Stub {public void send(Message msg) {msg.sendingUid = Binder.getCallingUid();Handler.this.sendMessage(msg);}
}
可以看出IMessenger是一个aidl接口,里面有一个send方法。
另外一个构造函数就更直接了,直接调用asInterface方法返回一个IMessenger的实例。
- 发送消息
public void send(Message message) throws RemoteException {mTarget.send(message);
}
调用的是mTarget的send方法,因为mTarget是IMessenger的实例,调用的是Handler中MessengerIml内部类的send方法。从上面的方法中可以看到实际调用的就是Handler中的sendMessage方法。
- 总结
Messenger实际是通过Binder来实现跨进程通信,通过Handler机制来处理消息循环。Messenger封装Handler来进行消息的发送和处理,消息发送后通过Binder完成进程间通信。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
