Android扫码器布尔状态监听空对象与LifecycleOwner转换报错求解
Android扫码器扫描状态监听可行解决方案
两个报错的根本原因:
- 第一个空指针异常:自定义
scanStatusListener类中,成员变量scanManager未完成初始化就直接调用isReading()方法赋值scanStatus,此时scanManager为null,触发空引用。同时你原有的自定义监听类没有状态变化检测逻辑,即使修复空指针也无法触发onChange回调。 - 第二个类型转换异常:原生
Service类默认未实现LifecycleOwner接口,无法直接强转后作为LiveData的观察者宿主。
方案1:修复自定义监听类实现(无需依赖LiveData)
首先修改自定义监听类,添加构造方法传入初始化完成的ScanManager,增加状态轮询检测逻辑:
public class ScanStatusListener { private final ScanManager scanManager; private boolean lastScanStatus; private ChangeListener listener; private final Handler handler = new Handler(Looper.getMainLooper()); // 状态检测间隔,可自行调整,单位毫秒 private static final long CHECK_INTERVAL = 200; // 构造方法强制传入初始化好的ScanManager,避免空指针 public ScanStatusListener(ScanManager scanManager) { this.scanManager = scanManager; this.lastScanStatus = scanManager.isReading(); // 启动状态轮询 startStatusCheck(); } public void setListener(ChangeListener listener) { this.listener = listener; } private void startStatusCheck() { handler.postDelayed(new Runnable() { @Override public void run() { boolean currentStatus = scanManager.isReading(); // 状态发生变化时触发回调 if (currentStatus != lastScanStatus) { lastScanStatus = currentStatus; if (listener != null) { listener.onChange(currentStatus); } } handler.postDelayed(this, CHECK_INTERVAL); } }, CHECK_INTERVAL); } // 页面销毁时调用,停止轮询避免内存泄漏 public void release() { handler.removeCallbacksAndMessages(null); listener = null; } public interface ChangeListener { // 回调返回当前扫描状态 void onChange(boolean isScanning); } }
在Service中使用:
public class ScanHook extends Service implements ScanManager.DataListener { private ScanManager _scanManager; private ScanStatusListener ss; @Override public void onCreate() { super.onCreate(); _scanManager = ScanManager.createScanManager(getApplicationContext()); // 传入已经初始化完成的ScanManager ss = new ScanStatusListener(_scanManager); ss.setListener(new ScanStatusListener.ChangeListener() { @Override public void onChange(boolean isScanning) { if (!isScanning) { // 扫描停止时执行指定操作 } } }); } @Override public void onDestroy() { super.onDestroy(); // 停止轮询,避免内存泄漏 if (ss != null) { ss.release(); } } // 省略其他Service必须实现的方法... }
方案2:修复LiveData实现方案
如果要继续用LiveData,有两种修复方式:
方式A:使用observeForever观察(无需修改父类)
注意observeForever使用后必须手动移除观察者,否则会造成内存泄漏
MutableLiveData<Boolean> listenBool = new MutableLiveData<>(); Observer<Boolean> scanStatusObserver = new Observer<Boolean>() { @Override public void onChanged(Boolean isScanning) { if (!isScanning) { // 扫描停止时执行指定操作 } } }; // 不需要LifecycleOwner,直接永久观察 listenBool.observeForever(scanStatusObserver); // 后续扫描状态变化时调用setValue/postValue更新即可 // listenBool.setValue(_scanManager.isReading()); // 在onDestroy里移除观察者 @Override public void onDestroy() { super.onDestroy(); listenBool.removeObserver(scanStatusObserver); }
方式B:让Service继承LifecycleService
修改Service的父类为LifecycleService(需要提前导入lifecycle-service依赖),此时Service天然实现LifecycleOwner接口,可直接使用observe方法:
public class ScanHook extends LifecycleService implements ScanManager.DataListener { private ScanManager _scanManager; @Override public void onCreate() { super.onCreate(); _scanManager = ScanManager.createScanManager(getApplicationContext()); MutableLiveData<Boolean> listenBool = new MutableLiveData<>(); listenBool.observe(this, new Observer<Boolean>() { @Override public void onChanged(Boolean aBoolean) { // 执行对应操作 } }); listenBool.setValue(_scanManager.isReading()); } // 省略其他逻辑 }
内容的提问来源于stack exchange,提问作者lvl 1 slime
相关产品推荐
相关产品推荐

