0

我目前正在通过从蓝牙设备接收数据到 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

4

0 回答 0