zoukankan      html  css  js  c++  java
  • Android跨进程通信Messenger*

    一.概述

    我们可以在客户端发送一个Message给服务端,在服务端的handler中会接收到客户端的消息,然后进行对应的处理,处理完成后,再将结果等数据封装成Message,发送给客户端,客户端的handler中会接收到处理的结果。

    有这么几个特点:

    • 基于Message,相信大家都很熟悉

    • 支持回调的方式,也就是服务端处理完成长任务可以和客户端交互

    • 不需要编写aidl文件

    此外,还支持,记录客户端对象的Messenger,然后可以实现一对多的通信;甚至作为一个转接处,任意两个进程都能通过服务端进行通信,这个后面再说。

    二.应用

    package com.imooc.messenger_server;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.Handler;
    import android.os.IBinder;
    import android.os.Message;
    import android.os.Messenger;
    import android.os.RemoteException;
    
    public class MessengerService extends Service {
    
        private static final int MSG_SUM = 0x110;
    
        //最好换成HandlerThread的形式
        private Messenger mMessenger = new Messenger(new Handler() {
            @Override
            public void handleMessage(Message msgfromClient) {
                Message msgToClient = Message.obtain(msgfromClient);//返回给客户端的消息
                switch (msgfromClient.what) {
                    //msg 客户端传来的消息
                    case MSG_SUM:
                        msgToClient.what = MSG_SUM;
                        try {
                            //模拟耗时
                            Thread.sleep(2000);
                            msgToClient.arg2 = msgfromClient.arg1 + msgfromClient.arg2;
                            msgfromClient.replyTo.send(msgToClient);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                        break;
                }
                super.handleMessage(msgfromClient);
            }
        });
    
        @Override
        public IBinder onBind(Intent intent)  {
            return mMessenger.getBinder();
        }
    }

    服务端就一个Service,可以看到代码相当的简单,只需要去声明一个Messenger对象,然后onBind方法返回mMessenger.getBinder();

    然后坐等客户端将消息发送到handleMessage想法,根据message.what去判断进行什么操作,然后做对应的操作,最终将结果通过 msgfromClient.replyTo.send(msgToClient);返回。

    可以看到我们这里主要是取出客户端传来的两个数字,然后求和返回,这里我有意添加了sleep(2000)模拟耗时,注意在实际使用过程中,可以换成在独立开辟的线程中完成耗时操作,比如和HandlerThread结合使用。

    注册文件

    <service
                android:name=".MessengerService"
                android:enabled="true"
                android:exported="true">
                <intent-filter>
                    <action android:name="com.zhy.aidl.calc"></action>
                    <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>
            </service>

    (二)客户端

    Activity

    package com.imooc.messenger_client;
    
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    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.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    
    public class MainActivity extends AppCompatActivity {
        private static final String TAG = "MainActivity";
        private static final int MSG_SUM = 0x110;
    
        private Button mBtnAdd;
        private LinearLayout mLyContainer;
        //显示连接状态
        private TextView mTvState;
    
        private Messenger mService;
        private boolean isConn;
    
    
        private Messenger mMessenger = new Messenger(new Handler() {
            @Override
            public void handleMessage(Message msgFromServer)  {
                switch (msgFromServer.what)  {
                    case MSG_SUM:
                        TextView tv = (TextView) mLyContainer.findViewById(msgFromServer.arg1);
                        tv.setText(tv.getText() + "=>" + msgFromServer.arg2);
                        break;
                }
                super.handleMessage(msgFromServer);
            }
        });
    
    
        private ServiceConnection mConn = new ServiceConnection()  {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                mService = new Messenger(service);
                isConn = true;
                mTvState.setText("connected!");
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name)  {
                mService = null;
                isConn = false;
                mTvState.setText("disconnected!");
            }
        };
    
        private int mA;
    
        @Override
        protected void onCreate(Bundle savedInstanceState)  {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //开始绑定服务
            bindServiceInvoked();
    
            mTvState = (TextView) findViewById(R.id.id_tv_callback);
            mBtnAdd = (Button) findViewById(R.id.id_btn_add);
            mLyContainer = (LinearLayout) findViewById(R.id.id_ll_container);
    
            mBtnAdd.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v)  {
                    try  {
                        int a = mA++;
                        int b = (int) (Math.random() * 100);
    
                        //创建一个tv,添加到LinearLayout中
                        TextView tv = new TextView(MainActivity.this);
                        tv.setText(a + " + " + b + " = caculating ...");
                        tv.setId(a);
                        mLyContainer.addView(tv);
    
                        Message msgFromClient = Message.obtain(null, MSG_SUM, a, b);
                        msgFromClient.replyTo = mMessenger;
                        if (isConn)  {
                            //往服务端发送消息
                            mService.send(msgFromClient);
                        }
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            });
    
        }
    
        private void bindServiceInvoked()  {
            Intent intent = new Intent();
            intent.setAction("com.zhy.aidl.calc");
            bindService(intent, mConn, Context.BIND_AUTO_CREATE);
            Log.e(TAG, "bindService invoked !");
        }
    
        @Override
        protected void onDestroy()  {
            super.onDestroy();
            unbindService(mConn);
        }
    }

    代码也不复杂,首先bindService,然后在onServiceConnected中拿到回调的service(IBinder)对象,通过service对象去构造一个mService =new Messenger(service);然后就可以使用mService.send(msg)给服务端了。

  • 相关阅读:
    494. Target Sum 添加标点符号求和
    636. Exclusive Time of Functions 进程的执行时间
    714. Best Time to Buy and Sell Stock with Transaction Fee有交易费的买卖股票
    377. Combination Sum IV 返回符合目标和的组数
    325. Maximum Size Subarray Sum Equals k 和等于k的最长子数组
    275. H-Index II 递增排序后的论文引用量
    274. H-Index论文引用量
    RabbitMQ学习之HelloWorld(1)
    java之struts2的数据处理
    java之struts2的action的创建方式
  • 原文地址:https://www.cnblogs.com/chenxibobo/p/9651861.html
Copyright © 2011-2022 走看看