• Android 跨进程通信并传输复杂数据


    前言
    AIDL (Android Interface Definition Language) 支持以下数据类型:
    基本数据类型:int、long、float、double、boolean、char、byte。
    字符串类型:String。
    集合类型:List、Map、Set。
    Parcelable 类型:实现了 Parcelable 接口的自定义类。
    IBinder 类型:用于跨进程通信的 Binder 类型。
    数组类型:int[]、String[]、Parcelable[] 等。
    其他类型:CharSequence、SparseArray、Bundle、CharSequence[]、ArrayList 等。
    所以,传输复杂类型的时候,只能使用Parcelable ,不支持Serializable

    服务端
    • 1、创建接收数据AIDL 文件
    // IServerInterface.aidl
    package com.rayvison.socketserviceapp;
    import com.rayvison.socketserviceapp.ComplexData;
    // Declare any non-default types here with import statements
    
    interface IServerInterface {
    
    void simpleData(String msg);
    void complexData(in ComplexData complexData);
    void destroyService();
    void unregisterListener(com.rayvison.socketserviceapp.ICallBackInterface listener);
    void registerListener(com.rayvison.socketserviceapp.ICallBackInterface listener);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 2、创建接收接口AIDL 文件
    // ICallBackInterface.aidl
    package com.rayvison.socketserviceapp;
    import com.rayvison.socketserviceapp.ComplexData;
    // Declare any non-default types here with import statements
    
    interface ICallBackInterface {
       void onSimpleData(String msg);
    
        void onComplexData(in ComplexData complexData);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 3、创建实体类以及实体类AIDL 文件

    实体类:

    package com.rayvison.socketserviceapp;
    
    import android.os.Parcel;
    import android.os.Parcelable;
    
    
    
    public class ComplexData implements Parcelable {
    
        private float[][]handValue;
       public ComplexData(){}
        protected ComplexData(Parcel in) {
            handValue = new float[in.readInt()][in.readInt()];
            for (int i = 0; i < handValue.length; i++) {
                in.readFloatArray(handValue[i]);
            }
        }
    
    
        public void setData(float[][] leftHandValue) {
            this.handValue = leftHandValue;
        }
    
        public float[][] getData() {
            return handValue;
        }
    
        public static final Creator<ComplexData> CREATOR = new Creator<ComplexData>() {
            @Override
            public ComplexData createFromParcel(Parcel in) {
                return new ComplexData(in);
            }
    
            @Override
            public ComplexData[] newArray(int size) {
                return new ComplexData[size];
            }
        };
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(handValue.length);
            dest.writeInt(handValue[0].length);
            for (int i = 0; i < handValue.length; i++) {
                dest.writeFloatArray(handValue[i]);
            }
    
    
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    // ComplexData.aidl
    package com.rayvison.socketserviceapp;
    
    // Declare any non-default types here with import statements
    
    parcelable   ComplexData;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 4、创建binder
    package com.rayvison.socketserviceapp.server;
    
    import android.os.RemoteCallbackList;
    import android.os.RemoteException;
    
    import com.rayvison.socketserviceapp.ComplexData;
    import com.rayvison.socketserviceapp.ICallBackInterface;
    import com.rayvison.socketserviceapp.IServerInterface;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class LocalBinder  extends IServerInterface.Stub {
    
    
        private  ConnectServer server;
    
        public  LocalBinder(ConnectServer connectService){
            this.server=connectService;
        }
        private RemoteCallbackList<ICallBackInterface> mRemoteCallbackList = new RemoteCallbackList();
        private Lock mLock = new ReentrantLock();
    
    
        @Override
        public void simpleData(String msg) throws RemoteException {
            mLock.lock();
            int i = 0;
            try {
                i = mRemoteCallbackList.beginBroadcast();
                for (int j = 0; j < i; j++) {
                    mRemoteCallbackList.getBroadcastItem(j).onSimpleData(msg);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                mRemoteCallbackList.finishBroadcast();
                mLock.unlock();
            }
        }
    
        @Override
        public void complexData(ComplexData complexData) throws RemoteException {
            mLock.lock();
            try {
                int i = mRemoteCallbackList.beginBroadcast();
                for (int j = 0; j < i; j++) {
                    mRemoteCallbackList.getBroadcastItem(j).onComplexData(complexData);
                }
            } catch (RemoteException e) {
                e.printStackTrace();
            } finally {
                mRemoteCallbackList.finishBroadcast();
                mLock.unlock();
            }
        }
    
        @Override
        public void destroyService() throws RemoteException {
    
        }
    
        @Override
        public void unregisterListener(ICallBackInterface listener) throws RemoteException {
            mRemoteCallbackList.unregister(listener);
        }
    
        @Override
        public void registerListener(ICallBackInterface listener) throws RemoteException {
            mRemoteCallbackList.register(listener);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    客户端
    • 1、拷贝aidl 整个文件夹到main 目录下

    • 在这里插入图片描述

    • 2、拷贝数据类完整路径到java 下
      在这里插入图片描述

    • 3、启动服务,开始通信

    (1) 绑定服务

     fun bindService() {
            val intent = Intent()
            intent.setPackage("com.rayvison.socketserviceapp")
            intent.action = "com.sockets.server.Connect"
            bindService(intent, mConnection, BIND_AUTO_CREATE)
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (2)客户端向服务器发送复杂数据

      fun sendComplexDataToServer() {
            val complexData = ComplexData()
            complexData.data = leftHandValue1
            mBinder?.complexData(complexData)
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (3)服务器向客户端应答返回简单数据响应

       @Override
        public void complexData(ComplexData complexData) throws RemoteException {
            mLock.lock();
            try {
                int i = mRemoteCallbackList.beginBroadcast();
                for (int j = 0; j < i; j++) {
                    //服务器收到消息,发送一条回复
                    mRemoteCallbackList.getBroadcastItem(j).onSimpleData("收到消息");
                    mRemoteCallbackList.getBroadcastItem(j).onComplexData(complexData);
                }
            } catch (RemoteException e) {
                e.printStackTrace();
            } finally {
                mRemoteCallbackList.finishBroadcast();
                mLock.unlock();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    (4)解绑服务

        override fun onDestroy() {
            super.onDestroy()
            mBinder?.unregisterListener(listener)
            unbindService(mConnection)
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    看一下效果:

    代码已上传gitHub

    github

  • 相关阅读:
    【网络篇】第二篇——IP协议与MAC地址详解
    攻防世界-pwnCTFM-Off_By_one漏洞与Tcachebin绕过
    15:00面试,15:08就出来了,问的问题有点变态。。。
    Meta Q2财报:营收首次下滑,Metaverse将与苹果竞争
    RPA如何应用于在直播电商,有哪些应用场景?
    Python爬虫:scrapy从项目创建到部署可视化定时任务运行
    Go有关方法的笔记(掌握defer与闭包)
    析构函数和垃圾回收机制GC
    Ribbon实现Cloud负载均衡
    指针和数组笔试题解析
  • 原文地址:https://blog.csdn.net/Android_LeeJiaLun/article/details/131936272