[使用线程和处理程序扫描蓝牙时,Android内存问题

问题描述 投票:0回答:1

我正在使用线程和处理程序来实现具有一定扫描周期和频率的蓝牙扫描服务。但是,随着时间的流逝,我意识到它正在消耗内存。

然后,我尝试使用探查器查看发生了什么,我发现递归循环。我检查了我的代码,找不到问题。任何人都可以帮助/遇到相同的问题?

public class BleDetectionService extends Service {

    private static Handler handler;
    private static final long SCAN_PERIOD = 1100;

    ...

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        ....

        startBLEScanning();
        return super.onStartCommand(intent, flags, startId);

    }

    private void startBLEScanning() {
        mLeDeviceAdapter = new LeDeviceAdapter();
        mScanning = true;

        Toast.makeText(this, "BLE Service sucessfully started", Toast.LENGTH_SHORT).show();

        bleScanningThread = new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare(); 
                while (mScanning) {
                    scanLeDevice(true);
                }
            }
        }, "BLE Scanning Thread");

        bleScanningThread.start();
    }

    private void scanLeDevice(final boolean enable) {
        if (enable) {
            handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    bluetoothLeScanner.stopScan(scanCallback);
                }
            }, SCAN_PERIOD);

            // filter
            ScanFilter.Builder builder = new ScanFilter.Builder();
            ScanFilter filter = builder.build();
            ArrayList<ScanFilter> filters = new ArrayList<>();
            filters.add(filter);

            // scansetting
            ScanSettings.Builder settingsBuilder = new ScanSettings.Builder();
            settingsBuilder.setScanMode(ScanSettings.SCAN_MODE_BALANCED);
            settingsBuilder.setReportDelay(0);
            ScanSettings settings = settingsBuilder.build();

            bluetoothLeScanner.startScan(filters, settings, scanCallback);

        } else {
            bluetoothLeScanner.stopScan(scanCallback);
        }
    }
}


enter image description here较早记录的时间

c稍后记录

android multithreading bluetooth handler profiler
1个回答
1
投票

请考虑以下内容:

scanLeDevice()在无休止的循环中被调用,并且始终使用true作为参数。

[scanLeDevice()几乎立即返回(1ms或更短)。

每次调用scanLeDevice()都会创建一个新的Handler和一个新的匿名RunnableRunnableHandler的绑定涉及一个Message(每个对postDelayed()的调用都一个)。

您从您的帖子中省略了SCAN_PERIOD的定义,但是我要进行有根据的猜测,并说是60000(1分钟)。这意味着每个新的Handler必须存在1分钟,因为它需要将Message保持1分钟,因为它正在跟踪在该分钟到期时需要执行的Runnable

换句话说:您每秒呼叫scanLeDevice()大约1000次,并且每次呼叫都会创建3个相互关联的对象,这些对象必须存在至少1分钟。

您的架构错误可能包括bleScanningThread。可以在主线程上安全地调用scanLeDevice()。它只需要调用一次。它会立即返回,但是扫描仍将在后台(由操作系统)进行。即使您没有提供额外的线程,ScanCallback也会在适当的时候执行。当您的postDelayed() Runnable执行时,扫描将停止;这可能是您从一开始就打算的。

© www.soinside.com 2019 - 2024. All rights reserved.