为什么调用本地反应原生模块阻止UI?

时间:2016-03-31 10:17:24

标签: react-native

正如文档中所建议的,我将一些长的数据获取代码移动到本机模块中以释放JS线程,但我发现这仍然阻止了UI。为什么这样做,我该怎么做才能避免这种情况?

从JS调用本机模块:

MyNativeModule.fetch(path).then( data => dispatchData(data) )

本机方法如下所示(它使用Android Firebase SDK):

@ReactMethod
public void fetch(final String path, final Promise promise) {
    root.child(path).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot snapshot) {
            if (snapshot.exists()) {
                promise.resolve(castSnapshot(snapshot));
            } else {
                promise.resolve(null);
            }
        }
        @Override
        public void onCancelled(FirebaseError firebaseError) {
            promise.reject(firebaseError.getMessage());
        }
    }
}

castSnapshot方法将Firebase DataSnapshot对象转换为WriteableMap。如果有用,我可以分享实现。

我观察到的是,即使我将promise.resolve(castSnapshot(snapshot));替换为castSnapshot(snapshot); promise.resolve(null);,该调用也会阻止UI:因此它不会通过作为罪魁祸首的网桥发送数据。如果数据量很大,castSnapshot可能需要一些时间,这显然是阻塞的。

即使此代码长时间运行,也不应该将其移动到本机模块中,而不是UI?我怎么没有得到这个?

非常感谢。

1 个答案:

答案 0 :(得分:4)

尝试在新的Thread实例中包装root.child行,如下所示:

@ReactMethod
public void fetch(final String path, final Promise promise) {
    new Thread(new Runnable() {
        public void run() {
            root.child(path)...
        }
    }).start();
}