React Native原生模块回调不执行是怎么回事?

端木东宁 阅读 79

我写了个Android原生模块,通过Bridge调用后JS端收不到回调,promise也不resolve,卡住了。

Java那边确实执行完了,也调了promise.resolve("ok"),但RN这边.then()完全没反应。是不是线程问题?试过在主线程调用还是不行。

@ReactMethod
public void doSomething(Promise promise) {
    // 模拟耗时操作
    new Thread(() -> {
        try {
            Thread.sleep(1000);
            promise.resolve("done");
        } catch (Exception e) {
            promise.reject("ERR", e);
        }
    }).start();
}
我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
程序猿奕冉
问题出在你用了新线程执行异步操作,但RN的Bridge要求所有native模块回调必须在UI线程执行。直接用 @UiThread 注解或者手动切换到主线程就行了。

 
@ReactMethod
public void doSomething(Promise promise) {
new Handler(Looper.getMainLooper()).post(() -> {
try {
Thread.sleep(1000);
promise.resolve("done");
} catch (Exception e) {
promise.reject("ERR", e);
}
});
}


这样保证了promise.resolve是在主线程执行的。别忘了在Java里捕获异常,不然Promise会卡住。真遇到这种跨线程问题最烦了,调了半天才发现是线程惹的祸。
点赞
2026-03-30 20:02
技术亚美
在React Native中调用原生模块时,确实要注意线程问题。你现在的写法是在子线程中处理完操作后直接resolve promise,但JS端收不到回调,主要原因是Promise的resolve必须在主线程中执行。

可以这样改写代码,保证resolve在UI线程中执行:

 
@ReactMethod
public void doSomething(Promise promise) {
// 模拟耗时操作
new Thread(() -> {
try {
Thread.sleep(1000);
// 使用runOnUiThread确保resolve在主线程执行
reactContext.getJSExecutor().getUiThreadUtil().runOnUiQueueThread(new Runnable() {
@Override
public void run() {
promise.resolve("done");
}
});
} catch (Exception e) {
promise.reject("ERR", e);
}
}).start();
}


这样做更清晰,也符合React Native的设计原则。记得要导入相关依赖,比如reactContext和ui线程工具类。另外提醒下,尽量避免在原生模块中使用长时间阻塞的操作,会影响性能体验。

要是还有问题,检查下promise.reject是否被触发了,有时候异常捕获不当也会导致看起来像没回调的情况。这种异步调用场景真的挺容易踩坑的。
点赞
2026-03-30 17:24