You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 10:45:08