虽然但是,有时候就是会有这种需求,这种时候一般有两种传输方式,
一种是把数据转成byte[],然后当基础类型一样传过去,这种方式有大小的要求,byte不能超过一定大小,可以分批次传,但是这种方式会影响帧率性能,不是很推荐。
二种是把数据存文件,传句柄过去,这里着重介绍这种方式。
先定义服务端的aidl接口。
interface ITestResultListener {
//TestResult是自己定义的类 也要实现Parcelable接口
void onTestResultListener(in TestResult result, in ParcelFileDescriptor pfd);
}
接下来服务端拿到了bitmap数据,将其转化为句柄传输
private fun updatePrivacyMaskingResult(testResult: TestResult, originBitmap: Bitmap) {
val fileCount = originBitmap.byteCount
var mf: MemoryFile? = null
var fd: ParcelFileDescriptor? = null
try {
mf = MemoryFile("mosaicImg", fileCount)
fd = ParcelFileDescriptor.dup(getFileDescriptor(mf))
val buffer = ByteBuffer.allocate(fileCount)
originBitmap.copyPixelsToBuffer(buffer)
val data = buffer.array()
mf.writeBytes(data, 0, 0, data.size)
val size = mTestResultListenerList.beginBroadcast()
for (i in 0 until size) {
mTestResultListenerList.getBroadcastItem(i) .onTestResultListener(testResult, fd) }
mPrivacyMaskingListenerList.finishBroadcast()
buffer.clear()
} catch (e: Throwable) {
Log.e(TAG, "updatePrivacyMaskingResult :${e.message} ", e)
} finally {
kotlin.runCatching { fd?.close() }
kotlin.runCatching { mf?.close() }
}
}
客户端也要定义一样的aidl接口,这里就直接略过了,直接看还原bitmap的过程。
override fun onTestResultListener(result: TestResult, pfd: ParcelFileDescriptor?) {
try {
pfd?.let {
val buffer = SharedMemory.fromFileDescriptor(it).mapReadWrite()
val bytes = ByteArray(buffer.limit())
buffer.get(bytes)
val bitmap = reconstructBitmap(bytes, result.height, result.width)
}
} catch (e: Throwable) {
Log.e(TAG, "onPrivacyMaskingResultListener: ", e)
}
}
private fun reconstructBitmap(data: ByteArray, height: Int, width: Int): Bitmap {
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
// 直接使用 ByteBuffer 包装字节数组
val buffer = ByteBuffer.wrap(data)
bitmap.copyPixelsFromBuffer(buffer)
return bitmap
}
至此结束。