您现在的位置是:首页 > 文章详情

Android 多进程之Messenger的使用

日期:2018-09-26点击:258

Android多进程系列

Messenger也可以作为Android多进程的一种通信方式,通过构建Message来在客户端和服务端之间传递数据

简单使用Messenger

客户端通过Messenger向服务端进程发送消息
  • 构建一个运行在独立进程中的服务端Service:
public class MessengerService extends Service { private static final String TAG = "MessagerService"; /** * 处理来自客户端的消息,并用于构建Messenger */ private static class MessengerHandler extends Handler { @Override public void handleMessage(Message message) { switch (message.what) { case MESSAGE_FROM_CLIENT: Log.e(TAG, "receive message from client:" + message.getData().getString("msg")); break; default: super.handleMessage(message); break; } } } /** * 构建Messenger对象 */ private final Messenger mMessenger = new Messenger(new MessengerHandler()); @Nullable @Override public IBinder onBind(Intent intent) { //将Messenger对象的Binder返回给客户端 return mMessenger.getBinder(); } }
  • 注册service,当然要设置在不同的进程
<service android:name="com.xxq2dream.service.MessengerService" android:process=":remote" />
  • 然后客户端是通过绑定服务端返回的binder来创建Messenger对象,并通过这个Messenger对象来向服务端发送消息
public class MessengerActivity extends AppCompatActivity { private static final String TAG = "MessengerActivity"; private Messenger mService; private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { Log.e(TAG, "ServiceConnection-->" + System.currentTimeMillis()); //通过服务端返回的Binder创建Messenger mService = new Messenger(iBinder); //创建消息,通过Bundle传递数据 Message message = Message.obtain(null, MESSAGE_FROM_CLIENT); Bundle bundle = new Bundle(); bundle.putString("msg", "hello service,this is client"); message.setData(bundle); try { //向服务端发送消息 mService.send(message); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName componentName) { Log.e(TAG, "onServiceDisconnected-->binder died"); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_messenger); //绑定服务 Intent intent = new Intent(this, MessengerService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onDestroy() { //解绑服务 unbindService(mConnection); super.onDestroy(); } }

服务端接收到客户端的消息

通过上面的额实践,我们可以看出利用Messenger进行跨进程通信,需要通过Message来传递消息,而Message可以通过setData方法利用Bundle来传递复杂的数据。
服务端如果要回复消息给客户端,那就要用到Message的replyTo参数了
  • 服务端改造
private static class MessengerHandler extends Handler { @Override public void handleMessage(Message message) { switch (message.what) { case Constant.MESSAGE_FROM_CLIENT: Log.e(TAG, "receive message from client:" + message.getData().getString("msg")); //获取客户端传递过来的Messenger,通过这个Messenger回传消息给客户端 Messenger client = message.replyTo; //当然,回传消息还是要通过message Message msg = Message.obtain(null, Constant.MESSAGE_FROM_SERVICE); Bundle bundle = new Bundle(); bundle.putString("msg", "hello client, I have received your message!"); msg.setData(bundle); try { client.send(msg); } catch (RemoteException e) { e.printStackTrace(); } break; default: super.handleMessage(message); break; } } }
  • 客户端改造,主要是通过Handle构建一个Messenger对象,并在向服务端发送消息的时候,通过Message的replyTo参数将Messenger对象传递给服务端
/** * 用于构建客户端的Messenger对象,并处理服务端的消息 */ private static class MessengerHandler extends Handler { @Override public void handleMessage(Message message) { switch (message.what) { case Constant.MESSAGE_FROM_SERVICE: Log.e(TAG, "receive message from service:" + message.getData().getString("msg")); break; default: super.handleMessage(message); break; } } } /** * 客户端Messenger对象 */ private Messenger mClientMessenger = new Messenger(new MessengerHandler()); private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { Log.e(TAG, "ServiceConnection-->" + System.currentTimeMillis()); mService = new Messenger(iBinder); Message message = Message.obtain(null, MESSAGE_FROM_CLIENT); Bundle bundle = new Bundle(); bundle.putString("msg", "hello service,this is client"); message.setData(bundle); //将客户端的Messenger对象传递给服务端 message.replyTo = mClientMessenger; try { mService.send(message); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName componentName) { Log.e(TAG, "onServiceDisconnected-->binder died"); } };

客户端收到服务端的消息回复

总结
  • 使用Messager来传递Message,Message中能使用的字段只有what、arg1、arg2、Bundle和replyTo,自定义的Parcelable对象无法通过object字段来传输
  • Message中的Bundle支持多种数据类型,replyTo字段用于传输Messager对象,以便进程间相互通信
  • Messager以串行的方式处理客户端发来的消息,不适合有大量并发的请求
  • Messager方法只能传递消息,不能跨进程调用方法

欢迎关注我的微信公众号,期待与你一起学习,一起交流,一起成长!
AntDream

原文链接:https://yq.aliyun.com/articles/645896
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章