Android多进程系列

  • Android 多进程通信之几个基本问题
  • Android多进程之Binder的使用
  • Android多进程之手动编写Binder类
  • Android多进程之Binder解绑监听的问题
  • Android多进程之Binder的意外死亡及权限校验
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,当然要设置在不同的进程
  • 然后客户端是通过绑定服务端返回的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();    }}
Android 多进程之Messenger的使用_第1张图片 服务端接收到客户端的消息
通过上面的额实践,我们可以看出利用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");    }};
Android 多进程之Messenger的使用_第2张图片 客户端收到服务端的消息回复
总结
  • 使用Messager来传递Message,Message中能使用的字段只有what、arg1、arg2、Bundle和replyTo,自定义的Parcelable对象无法通过object字段来传输
  • Message中的Bundle支持多种数据类型,replyTo字段用于传输Messager对象,以便进程间相互通信
  • Messager以串行的方式处理客户端发来的消息,不适合有大量并发的请求
  • Messager方法只能传递消息,不能跨进程调用方法

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


AntDream

更多相关文章

  1. Android应用程序进程启动过程(后篇)
  2. 你对进程线程到底理解有多少
  3. 在iis上运行的服务器端程序,运行一段时间后,访问都只出现一行乱码,
  4. 命名管道跨进程通讯
  5. ASP.NET全栈开发之在MVC中使用服务端验证(二)
  6. C语言如何获取进程ID?(代码实例)
  7. 运行golang程序提示进程无法启动
  8. golang如何获取客户端ip?
  9. golang如何退出进程?

随机推荐

  1. 详解MySQL 5.7 MGR单主确定主节点方法
  2. macOS 下的 MySQL 8.0.17 安装与简易配置
  3. Windows环境下MySQL 8.0 的安装、配置与
  4. mysql最新版8.0.17解压版安装教程
  5. mysql 8.0.17 解压版安装配置方法图文教
  6. MySql逗号拼接字符串查询的两种方法
  7. Django2.* + Mysql5.7开发环境整合教程图
  8. Mysql数据库清理binlog日志命令详解
  9. mysql共享锁与排他锁用法实例分析
  10. 解决重置Mysql root用户账号密码问题