使用LiveData观察BLE设备SDK方法返回结果无后续更新如何解决?
问题根因
- 状态变量仅初始化赋值:
MyWrappedDevice的status字段仅在单例构造时计算了一次值,后续蓝牙连接、断开状态变化时没有主动更新该字段,上层感知不到变更。 - LiveData无更新触发逻辑:ViewModel中的
MutableLiveData仅在首次调用getStatus()时赋值了初始状态,没有监听设备状态变更的入口,不会主动推送新值给观察者。 - 未注册SDK状态回调:BLE SDK一般都会提供连接状态变更的监听器接口,你当前实现中没有注册该回调,没有状态变更的事件源。
修复方案(Java实现)
1. 改造设备单例类,增加状态监听能力
假设你使用的BLE SDK提供了连接状态变更回调,按如下逻辑改造MyWrappedDevice:
public MyWrappedDevice { private DeviceSDKClass myDevice; private static MyWrappedDevice myWrappedDeviceInstance; // 自定义状态变更监听器接口 public interface OnConnectionStateChangedListener { void onChanged(boolean isConnected); } private OnConnectionStateChangedListener stateListener; public boolean status; public static MyWrappedDevice getInstance(@NonNull final Context context) { if (isNull(myWrappedDeviceInstance)) { myWrappedDeviceInstance = new MyWrappedDevice(context); } return myWrappedDeviceInstance; } private MyWrappedDevice(Context context) { ... // 原有设备初始化逻辑 myDevice = xxx; // 注册SDK自带的连接状态回调(方法名替换为你实际SDK的对应方法) myDevice.setConnectionStateListener(new DeviceSDKClass.ConnectionStateListener() { @Override public void onConnectionStateChange(boolean isConnected) { // 状态变更时同步更新本地status字段 status = isConnected; // 通知上层监听器 if (stateListener != null) { stateListener.onChanged(status); } } }); // 初始化初始状态 this.status = !isNull(myDevice) && myDevice.isConnected(); } // 暴露注册监听器的方法 public void setOnConnectionStateChangedListener(OnConnectionStateChangedListener listener) { this.stateListener = listener; } // 暴露解注册方法,避免内存泄漏 public void removeConnectionStateListener() { this.stateListener = null; } ... }
2. 改造ViewModel,监听状态变更并同步到LiveData
public class MyDeviceViewModel extends AndroidViewModel { private MutableLiveData<Boolean> connected; private MyWrappedDevice device; public MyDeviceViewModel(@NonNull Application application) { super(application); this.device = MyWrappedDevice.getInstance(application.getApplicationContext()); } public LiveData<Boolean> getStatus() { if (isNull(connected)) { connected = new MutableLiveData<>(); // 赋值初始状态 connected.setValue(device.status); // 注册设备状态监听器 device.setOnConnectionStateChangedListener(isConnected -> { // 如果SDK回调运行在子线程,必须使用postValue更新LiveData connected.postValue(isConnected); }); } return connected; } @Override protected void onCleared() { super.onCleared(); // ViewModel销毁时解注册监听器,避免内存泄漏 device.removeConnectionStateListener(); } }
3. Fragment层逻辑
原有观察逻辑无需修改,可正常接收状态变更通知。
可选兜底方案
如果你使用的BLE SDK确实没有提供连接状态变更回调,可采用定时轮询方案(不推荐,会增加设备功耗):在ViewModel中启动固定间隔的轮询任务,每隔1~2秒查询一次myDevice.isConnected(),对比状态变化后更新LiveData,ViewModel销毁时停止轮询任务即可。
内容的提问来源于stack exchange,提问作者r08y
相关产品推荐
相关产品推荐

