蓝牙扫描内存泄漏

时间:2019-07-29 02:20:40

标签: c# android xamarin bluetooth

我连续扫描蓝牙设备10秒钟,停一秒钟,然后再次开始扫描。问题是应用程序内存在不断增加,并最终导致OutOfMemory异常。我还无法确定是蓝牙扫描增加了内存还是其他。我想知道这段代码是否包含可能导致内存泄漏的内容。

 public interface IScanInterface
{
    bool IsScanning { get; }
    void StartScan();
    event ContinuosScanEventHandler ContinuosScanResultReceived;
    event DevicesDiscoveredEventHandler DevicesDiscovered;
    event ScanTimeoutEventHandler ScanTimeoutElapsed;
}

public delegate void ContinuosScanEventHandler(object sender, ContinousScanEventArgs eventArgs);
public delegate void DevicesDiscoveredEventHandler(object sender, SingleScanEventArgs eventArgs);
public delegate void ScanTimeoutEventHandler(object sender, SingleScanEventArgs eventArgs);

public class ContinousScanEventArgs : System.EventArgs
{
    public SensorData data { get; set; }
}

public class SingleScanEventArgs : System.EventArgs
{
    public List<SensorData> deviceList { get; set; }
}

SensorData是用于解析ScanResult的自定义类。

 public class ScanTest : IScanInterface
{
    private readonly BluetoothManager bluetoothManager;
    private readonly BluetoothAdapter bluetoothAdapter;
    private readonly ApiScanCallback callback;
    private List<ScanFilter> scanFilters = new List<ScanFilter>();
    private ScanSettings scanSettings;
    private List<SensorData> DeviceList = new List<SensorData>();
    public App app;

    public ScanTest()
    {
        bluetoothManager = (BluetoothManager)Android.App.Application.Context.GetSystemService(Android.Content.Context.BluetoothService);
        bluetoothAdapter = bluetoothManager.Adapter;
        callback = new ApiScanCallback(this);
        scanFilters.Add(GetScanFilter());
        scanSettings = GetScanSettings();
    }

    private volatile bool _isScanning;
    public bool IsScanning
    {
        get { return _isScanning; }
        set { _isScanning = value; }
    }

    public event ContinuosScanEventHandler ContinuosScanResultReceived;
    public event DevicesDiscoveredEventHandler DevicesDiscovered;
    public event ScanTimeoutEventHandler ScanTimeoutElapsed;

    public async void StartScan()
    {
        if (bluetoothAdapter.BluetoothLeScanner != null)
        {
            while (true)
            {
                DeviceList.Clear();
                if (IsScanning)
                    return;
                IsScanning = true;
                bluetoothAdapter.BluetoothLeScanner.StartScan(scanFilters, scanSettings, callback);
                await Task.Delay(10000);
                bluetoothAdapter.BluetoothLeScanner.StopScan(callback);
                IsScanning = false;
                ScanTimeoutElapsed?.Invoke(this, new SingleScanEventArgs() { deviceList = DeviceList });
            }
        }
    }

    public ScanFilter GetScanFilter()
    {
        ScanFilter.Builder builder = new ScanFilter.Builder();
        byte[] manufactureData = new byte[0];
        byte[] manufactureMask = new byte[0];
        builder.SetManufacturerData(41136, manufactureData, manufactureMask);
        return builder.Build();
    }

    public ScanSettings GetScanSettings()
    {
        ScanSettings.Builder builder = new ScanSettings.Builder();
        builder.SetScanMode(Android.Bluetooth.LE.ScanMode.LowLatency);
        return builder.Build();
    }

    private void AddDevice(SensorData data)
    {
        if (!DeviceList.Any(x => x.DeviceId == data.DeviceId))
        {
            if(data.AdvertisementData.ConnectionStatus == 1)
                DeviceList.Add(data);
        }
    }

    public class ApiScanCallback : ScanCallback
    {

        private readonly ScanTest scanTest;

        public ApiScanCallback(ScanTest test)
        {
            scanTest = test;
        }
        //Filters the result to check whether it has needed manufacture data
        private bool Filter(byte[] byteArray)
        {
            if (byteArray.Length > 20)
            {
                if (byteArray[2] == 0xB0 && byteArray[3] == 0xA0)
                {
                    return true;
                }
            }
            return false;
        }

        public override void OnScanResult([GeneratedEnum] ScanCallbackType callbackType, ScanResult result)
        {
            base.OnScanResult(callbackType, result);
            if (result == null)
                return;
            byte[] byteArray = result.ScanRecord.GetBytes();
            if (!Filter(byteArray))
                return;
            var dataStr = BitConverter.ToString(byteArray).Replace("-", "");
            var data = new SensorData() { Data = dataStr, TimeStamp = DateTime.UtcNow, RSSI = result.Rssi, DeviceId = result.Device.Address };
            scanTest.AddDevice(data);
            scanTest.ContinuosScanResultReceived?.Invoke(this, new ContinousScanEventArgs() { data = data });
        }

        public override void OnScanFailed([GeneratedEnum] ScanFailure errorCode)
        {
            base.OnScanFailed(errorCode);
        }

        public override void OnBatchScanResults(IList<ScanResult> results)
        {
            base.OnBatchScanResults(results);
        }
    }
}

0 个答案:

没有答案