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);
}
  • 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);
}
  • 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]);
        }


    }
}


// ComplexData.aidl
package com.rayvison.socketserviceapp;

// Declare any non-default types here with import statements

parcelable   ComplexData;
  • 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、拷贝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)
    }

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

  fun sendComplexDataToServer() {
        val complexData = ComplexData()
        complexData.data = leftHandValue1
        mBinder?.complexData(complexData)
    }

(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();
        }
    }

(4)解绑服务

    override fun onDestroy() {
        super.onDestroy()
        mBinder?.unregisterListener(listener)
        unbindService(mConnection)
    }

看一下效果:

代码已上传gitHub

github

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值