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

扫码后调用initLoader报错:必须在主线程调用该方法

解决initLoader must be called on the main thread异常

嘿,我一眼就看出问题所在了——你是在后台线程里调用initLoader了!

问题根源

BarcodeDetector的Processor.receiveDetections()方法是在后台线程运行的,而Android的Loader框架有严格的线程要求:initLoader必须在主线程(UI线程)中调用。所以你直接在这里触发realizarConsulta(),自然就抛出了线程违规的异常。

快速修复方案

只需要把调用realizarConsulta的逻辑切换到主线程执行就行,Android的Activity自带runOnUiThread()方法可以帮你搞定这个:

修改你的Procesador类里的receiveDetections方法:

@Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
    SparseArray<Barcode> objetosDetectados = detections.getDetectedItems();
    if(objetosDetectados.size() > 0) {
        Barcode barcode = objetosDetectados.valueAt(0);
        EscaneoActivity.codigoActual = barcode;
        Bundle b = new Bundle();
        b.putLong(ConsultorProductosBD.X, Long.parseLong(barcode.displayValue));
        
        // 关键:切换到主线程执行查询
        escaneoActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                escaneoActivity.realizarConsulta(b);
            }
        });
    }
}

为什么你之前的尝试没解决问题?

你之前把操作移到Activity的成员方法里,但问题的核心不是方法在哪里,而是调用这个方法的线程不对。receiveDetections是BarcodeDetector在后台线程触发的,所以哪怕调用的是Activity的方法,执行环境还是后台线程,必须显式切换到主线程才能安全调用initLoader。

简化写法(可选)

如果你的项目支持Java 8及以上,用Lambda表达式可以让代码更简洁:

escaneoActivity.runOnUiThread(() -> escaneoActivity.realizarConsulta(b));

这样看起来清爽多了~

内容的提问来源于stack exchange,提问作者JuanDavid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:27:49