应用因系统或异常崩溃时能否调用方法?如何终止BLE会话及对象?
应用崩溃时终止BLE会话及相关对象的解决方案
全局异常捕获与清理入口
实现自定义UncaughtExceptionHandler替换系统默认处理器,在应用崩溃触发异常时优先执行BLE资源清理逻辑:
public class AppCrashHandler implements Thread.UncaughtExceptionHandler { private final Thread.UncaughtExceptionHandler defaultHandler; private final BleManager bleManager; public AppCrashHandler(BleManager manager) { defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); bleManager = manager; } @Override public void uncaughtException(Thread t, Throwable e) { // 优先执行BLE全量清理 bleManager.cleanupAllSessions(); // 交回系统默认崩溃处理流程 if (defaultHandler != null) { defaultHandler.uncaughtException(t, e); } } }
在Application的onCreate中注册该处理器:
@Override public void onCreate() { super.onCreate(); Thread.setDefaultUncaughtExceptionHandler( new AppCrashHandler(BleManager.getInstance()) ); }
统一BLE会话集中管理
避免在零散类中独立持有BLE对象,用全局单例BleManager统一管理所有Gatt实例、会话回调:
public class BleManager { private static volatile BleManager instance; private final Map<String, BluetoothGatt> gattMap = new HashMap<>(); private final Map<String, BluetoothGattCallback> callbackMap = new HashMap<>(); public static BleManager getInstance() { if (instance == null) { synchronized (BleManager.class) { if (instance == null) { instance = new BleManager(); } } } return instance; } // 注册BLE会话 public void registerSession(String deviceAddr, BluetoothGatt gatt, BluetoothGattCallback callback) { gattMap.put(deviceAddr, gatt); callbackMap.put(deviceAddr, callback); } // 全量清理BLE会话 public void cleanupAllSessions() { for (Map.Entry<String, BluetoothGatt> entry : gattMap.entrySet()) { BluetoothGatt gatt = entry.getValue(); // 移除回调避免内存泄漏 BluetoothGattCallback callback = callbackMap.get(entry.getKey()); if (callback != null) { gatt.setCallback(null); } // 断开并关闭Gatt连接 gatt.disconnect(); gatt.close(); } // 清空资源集合 gattMap.clear(); callbackMap.clear(); } }
所有类创建BLE会话时,必须通过BleManager.registerSession()注册,确保崩溃时能被统一清理。
零散BLE对象的补充清理
针对无法纳入全局管理的零散BLE操作类,定义统一的资源释放接口,在崩溃时遍历执行释放:
// 定义资源释放接口 public interface BleResourceReleasable { void releaseBleResources(); }
在BLE操作类中实现该接口:
public class CustomBleTask implements BleResourceReleasable { private BluetoothGatt gatt; @Override public void releaseBleResources() { if (gatt != null) { gatt.disconnect(); gatt.close(); gatt = null; } } }
修改AppCrashHandler,维护可释放对象列表:
public class AppCrashHandler implements Thread.UncaughtExceptionHandler { // ... 原有代码 private final List<BleResourceReleasable> releasableList = new ArrayList<>(); // 对外提供注册入口 public void registerReleasable(BleResourceReleasable obj) { releasableList.add(obj); } @Override public void uncaughtException(Thread t, Throwable e) { // 先清理零散BLE对象 for (BleResourceReleasable obj : releasableList) { obj.releaseBleResources(); } releasableList.clear(); // 再执行全局BLE会话清理 bleManager.cleanupAllSessions(); // ... 系统默认处理 } }
关键注意事项
- 崩溃清理逻辑必须极简,避免在清理过程中再次抛出异常,覆盖原始崩溃信息;
- Android中BLE断开为异步操作,清理时无需等待回调确认,直接执行
disconnect()+close()即可确保资源释放; - 测试时可主动抛出异常(如
throw new RuntimeException("Crash Test"))验证清理逻辑有效性。
内容的提问来源于stack exchange,提问作者srinivasan cp
相关产品推荐
相关产品推荐

