-1

コードを実行し、電話を数回回転させてから、メモリをダンプして分析します。

以下は私のコードです:

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 ヒープ

4

1 に答える 1

2

LeScanCallback はアクティビティへの参照を保持しています。Google が提供する BluetoothLeGatt サンプルをテストしているときに、これに遭遇しました。スキャン コードをアプリにコピーしたところ、突然、大量のリークが発生していることがわかりました。

スキャン コールバックを静的クラスにラップして、アクティビティへの弱い参照を保持することで解決しました。Handler を使用するときに Google が推奨するのと同じように。このような:

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();
    }
}
于 2016-04-08T03:41:03.053 に答える