我目前正在通过从蓝牙设备接收数据到 Android 来绘制图形。
我遇到内存不足错误,留下一个问题。
一开始是接收数据,绘制实时图,当累积超过一定数量IndexOutOfBoundsException Index -1时,清除初始累积数据的任务出现错误,所以我用try catch捕获了异常。
然后发生内存溢出错误。
我尝试在 Manifest 中添加android:largeHeap=trueandandroid:hardwareAccelerated=false来解决这个内存溢出错误,但它似乎没有任何实际帮助。
在我收到警告后android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died,图表变慢了,应用程序被杀死了。
这是 BluetoothGattCallback 代码的一部分。
@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