-1

I run my code and rotate the phone couple of times, then dump memory and analyze it.

Below is my code:

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);
    }

The java heap: java heap

Jojodmo
  • 23,357
  • 13
  • 65
  • 107
tiny sunlight
  • 6,231
  • 3
  • 21
  • 42

1 Answers1

3

The LeScanCallback is holding a reference to the Activity. I just ran into this when testing the BluetoothLeGatt sample provided by Google. I copied the scanning code into my app and I suddenly found massive leaks occurring.

I solved it by wrapping the scan callback into a static class which then holds a weak reference to the activity. Much like Google reccomends when using a Handler. Like this:

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();
    }
}
Gary
  • 13,303
  • 18
  • 49
  • 71
eknovack
  • 31
  • 2