当我在onCreate中使用startLeScan并在onDestroy中使用stopLeScan时它会泄漏

时间:2016-03-04 06:59:29

标签: memory-leaks android-bluetooth android-ble

我运行我的代码并将电话旋转几次,然后转储内存并进行分析。

以下是我的代码:

private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
            LogUtils.e("111");
        }
    };
    private boolean mScanning = false;
    private BluetoothManager bm;
    private void scanLeDevice(final boolean enable) {
        LogUtils.e(enable);
        try {
            if (enable) {
                mScanning = true;
                if(bm.getAdapter()!=null)bm.getAdapter().startLeScan(mLeScanCallback);
            } else {
                mScanning = false;
                if(bm.getAdapter()!=null)bm.getAdapter().stopLeScan(mLeScanCallback);
            }
            invalidateOptionsMenu();
        }catch (Throwable e){

        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        scanLeDevice(false);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initStage();
    }
    @Override
    protected void initStage() {
        bm = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
        scanLeDevice(true);
    }

java堆: java heap

1 个答案:

答案 0 :(得分:2)

LeScanCallback持有对Activity的引用。我在测试Google提供的BluetoothLeGatt示例时遇到了这个问题。我将扫描代码复制到我的应用程序中,突然发现大量泄漏。

我通过将扫描回调包装到静态类中来解决它,然后静态类保存对活动的弱引用。就像Google在使用Handler时的推荐一样。像这样:

private final BluetoothAdapter.LeScanCallback mLeScanCallback = new LeScanCallbackClass(this);

private static final class LeScanCallbackClass implements BluetoothAdapter.LeScanCallback {

    private String TAG = makeLogTag(LeScanCallbackClass.class.getName());
    private final WeakReference<TrackActivity> mAct;

    public LeScanCallbackClass(TrackActivity act) {
        mAct = new WeakReference<>(act);
    }

    @Override
    public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
        LOGI(TAG, String.format("BLE LeScan Result: %s", device.getAddress()));
        final TrackActivity act = mAct.get();
        act.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                        mLeDeviceListAdapter.addDevice(device);
                        mLeDeviceListAdapter.notifyDataSetChanged();
            }
        });
        act.sendNotification();
    }
}