現在、Bluetooth デバイスから Android にデータを受信してグラフを描画する作業を行っています。
メモリ不足エラーが発生し、質問が残っています。
最初はデータを受け取り、リアルタイムでグラフを描いていき、一定量以上溜まるとIndexOutOfBoundsException Index -1
、最初に溜まったデータをクリアするタスクでエラーが発生したので、try catchで例外をキャッチしました。
その後、メモリオーバーフローエラーが発生しました。マニフェストにandを
追加して、このメモリ オーバーフロー エラーを解決しようとしましたが、実用的な助けにはならなかったようです。
について警告を受けた後、グラフが遅くなり、アプリが強制終了されました。
BluetoothGattCallback コードの一部を次に示します。android:largeHeap=true
android:hardwareAccelerated=false
android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
switch (newState) {
case STATE_CONNECTED:
gatt.discoverServices();
break;
case STATE_DISCONNECTED:
onDisconnected();
break;
}
}
private void onDisconnected() {
this.gatt = null;
this.service = null;
this.rxCharacteristic = null;
if (this.callback != null) {
this.callback.onDisconnected();
}
if (gatt != null) {
gatt.close();
}
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorWrite(gatt, descriptor, status);
if (status == GATT_SUCCESS) {
byte[] array = hexStringToByteArray(REQUEST_COMMAND);
BluetoothGattCharacteristic characteristic = this.gatt.getService(UUID.fromString(SERVICE_UUID)).getCharacteristic(UUID.fromString(RX_CHAR_UUID));
characteristic.setValue(array);
this.gatt.writeCharacteristic(characteristic);
if (this.callback != null && this.service != null && this.txCharacteristic != null) {
this.callback.onConnected();
}
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
byte[] read = characteristic.getValue();
long timestamp = System.currentTimeMillis();
int BCG = ((read[14] & 0xff) << 8) | (read[15] & 0xff);
int ECG = ((read[12] & 0xff) << 8) | (read[13] & 0xff);
if (this.callback != null) {
callback.onData(timestamp, BCG, ECG);
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (status == GATT_SUCCESS) {
this.gatt = gatt;
this.service = gatt.getService(UUID.fromString(SERVICE_UUID));
this.rxCharacteristic = this.service.getCharacteristic(UUID.fromString(RX_CHAR_UUID));
this.txCharacteristic = this.service.getCharacteristic(UUID.fromString(TX_CHAR_UUID));
setCharacteristicNotification(this.txCharacteristic, true);
} else {
onDisconnected();
}
}
private void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enable) {
if (this.gatt == null) {
Log.d("BCGBluetoothCallback", "BluetoothGatt not initialized");
}
this.gatt.setCharacteristicNotification(characteristic, enable);
BluetoothGattDescriptor descriptor = this.txCharacteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
this.gatt.writeDescriptor(descriptor);
}
そして、このコールバックは、リアルタイム グラフを描画する Fragment で呼び出されます。
@Override
public void onConnected() {
DeviceConnector.getDeviceConnector().getConnectedDevice().addHandler(new ScannedBleDevice.OnBCGDataHandler() {
@Override
public void onData(long timestamp, int bcg, int ecg) {
updateChart(bcg, timestamp);
}
});
}
これが updateChart コードです。
public void updateChart(int bcg, long timestamp) {
lineDataSet.addEntry(new Entry(System.currentTimeMillis() - prevTime, bcg - 7332 ));
if (++count % 4 != 0) return;
while (lineDataSet.getEntryCount() > 250) {
try {
lineDataSet.removeFirst();
} catch (Exception ignored) {
}
}
lineDataSet.notifyDataSetChanged();
lineChart.setData(new LineData(lineDataSet));
lineChart.notifyDataSetChanged();
lineChart.postInvalidate();
}
そして、onCreateViewでlineChart、lineDataSet..のように初期化します。
実際、コールバックと呼ばれる時間と初期化時間が別のものかどうかはわかりません。
private void initBinding(View view) {
lineChart = view.findViewById(R.id.chart_raw);
setLineChart(lineChart);
}
private void initDataSet() {
lineDataSet = new LineDataSet(new LinkedList<Entry>(), Raw Data);
setDataSet(lineDataSet);
lineDataSet.setColor(0xffff0000);
}
private void setLineChart(LineChart chart) {
chart.getLegend().setEnabled(false);
chart.setTouchEnabled(true);
chart.setDragEnabled(true);
chart.setScaleXEnabled(false);
chart.setScaleYEnabled(false);
chart.setVisibleXRangeMaximum(1000);
YAxis yAxis = chart.getAxisRight();
yAxis.setEnabled(false);
}
private void setDataSet(LineDataSet dataSet) {
dataSet.setDrawCircles(false);
dataSet.setDrawValues(false);
}
このようなフラグメントは 3 つあり、データが変更されるたびにそれぞれが呼び出されます。
データの扱いがわかりません。複数回答お願いします(T_T)