#android #bluetooth-gatt #deadobjectexception
#android #bluetooth-gatt #deadobjectexception
Вопрос:
В настоящее время я работаю над рисованием графиков, получая данные с устройства Bluetooth на Android.
У меня ошибка с нехваткой памяти, оставляю вопрос.
Сначала я получил данные, нарисовал график в реальном времени, и когда его накопилось больше определенного количества, IndexOutOfBoundsException Index -1
произошла ошибка в задаче очистки изначально накопленных данных, поэтому я поймал исключение с помощью try catch.
Затем произошла ошибка переполнения памяти.
Я попытался добавить android:largeHeap=true
и android:hardwareAccelerated=false
в Манифест, чтобы устранить эту ошибку переполнения памяти, но это, похоже, не принесло никакой практической помощи.
После того , как я получил предупреждение android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died
, график замедлился, и приложение было убито.
Вот часть кода обратного вызова Bluetooth.
@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 amp;amp; this.service != null amp;amp; 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] amp; 0xff) lt;lt; 8) | (read[15] amp; 0xff); int ECG = ((read[12] amp; 0xff) lt;lt; 8) | (read[13] amp; 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); }
И этот обратный вызов вызывается фрагментом, который рисует график в реальном времени.
@Override public void onConnected() { DeviceConnector.getDeviceConnector().getConnectedDevice().addHandler(new ScannedBleDevice.OnBCGDataHandler() { @Override public void onData(long timestamp, int bcg, int ecg) { updateChart(bcg, timestamp); } }); }
И это код обновления диаграммы.
public void updateChart(int bcg, long timestamp) { lineDataSet.addEntry(new Entry(System.currentTimeMillis() - prevTime, bcg - 7332 )); if ( count % 4 != 0) return; while (lineDataSet.getEntryCount() gt; 250) { try { lineDataSet.removeFirst(); } catch (Exception ignored) { } } lineDataSet.notifyDataSetChanged(); lineChart.setData(new LineData(lineDataSet)); lineChart.notifyDataSetChanged(); lineChart.postInvalidate(); }
And I initialize like lineChart, lineDataSet.. in onCreateView.
Actually I’m not sure that callback called time and initialize time are separate.
private void initBinding(View view) { lineChart = view.findViewById(R.id.chart_raw); setLineChart(lineChart); } private void initDataSet() { lineDataSet = new LineDataSet(new LinkedListlt;Entrygt;(), 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); }
There are 3 such fragments and each is called whenever data changes.
I have no idea to handle the data. Multiple answers please.. T_T