我连续扫描蓝牙设备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);
}
}
}