Android inter-process communication often uses AIDL, which is simple and convenient, but the amount of data is limited. If it exceeds a certain value, an error will be reported:
E !!! FAILED BINDER TRANSACTION !!! (parcel size = 2073744)
Big data can be transferred by using AIDL+MemoryFile
Create a new AIDL interface:
interface OnFileListener{
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void onFile(in ParcelFileDescriptor file);
}
Add listening interface
void addFileListener(OnFileListener listener);
Server sends data
MemoryFile imageFile = new MemoryFile(System.currentTimeMillis()+"image.data",image.length);
imageFile.writeBytes(image,0,0,image.length);
ParcelFileDescriptor pfd = getParcelFileDescriptor(imageFile);
if (pfd!=null){
listener.sendFile(pfd);
}
fun getParcelFileDescriptor(memoryFile: MemoryFile): ParcelFileDescriptor? {
return try {
val method: Method = MemoryFile::class.java.getDeclaredMethod("getFileDescriptor")
method.setAccessible(true)
val fd: FileDescriptor = method.invoke(memoryFile) as FileDescriptor
ParcelFileDescriptor.dup(fd)
} catch (e: Exception) {
e.printStackTrace()
null
}
}
Client receives data
service.addFileListener(new OnFileListener.Stub() {
@Override
public void onFile(ParcelFileDescriptor pfd) throws RemoteException {
try {
FileInputStream fis = new FileInputStream(pfd.getFileDescriptor());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[1920*1080];
int len;
while ((len = fis.read(buf)) != -1) {
bos.write(buf, 0, len);
}
bos.close();
fis.close();
pfd.close();
}catch (Exception e){
e.printStackTrace();
}
}
});
According to actual measurement, the real-time transmission of Camera data is relatively smooth.