[英]Best way to handle continuous flow of small byte arrays that need to be flattened?
我通過NOTIFY
從 BLE 服務器接收大量數據。 在應用程序的 iOS 對應項上,此傳輸非常簡單,並且沒有性能下降,但是在 Android 上,我似乎找不到性能不差的實現。
最初的實現使用了一個簡單的 ByteArray 覆蓋:
// Warning! Semi-pseudocode
var rawData = ByteArray(0)
characteristic.onReceive { data ->
rawData += data
}
在傳輸大約 3MB 之前,這工作得很好。 在那之后,任務速度變慢了(例如,第一個 10% - ~1MB - 將在一分鍾內傳輸,第二個 10% 將在一分鍾左右,第三個 10% 幾乎 2 分鍾,然后所有后續批次的時間大約增加前一批的金額,想想斐波那契數列)。 我理解這是因為每次調用onReceive
時,我都會創建一個新的 ByteArray 並丟棄以前的 object,最后導致 GC 收集 2-3MB 對象。
這顯然不是最優的,尤其是當完全傳輸約為 16MB 時。
我嘗試了預分配的ByteBuffer
(本地和基於 Java 的分配)、 LinkedList
和 ByteArrays Array
,等等。
onReceive
部分使用 Kotlin 協程( ReceiveChannel<ByteArray>
和Flow<ByteArray>
)解決,如果我不保存數據,它甚至比 iOS 更快(主要是由於 MTU 差異 - 接收到 162 與 250 字節) .
將這些收到的批次整理成單個 ByteArray 的最佳方法是什么?
我不相信您的問題與緩沖區分配有關,但我們使用ByteArrayOutputStream
來聚合來自特征通知的 MTU 大小的段。
ByteArrayOutputStream inputBuffer = new ByteArrayOutputStream();
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic chr) {
inputBuffer.write(chr.getValue());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.