前言
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