【问题标题】:Are there any guides for implementing JavaScriptModule in react-native?是否有在 react-native 中实现 JavaScriptModule 的指南?
【发布时间】:2016-07-29 14:15:06
【问题描述】:

有兴趣在 react-native 中实现直接 nativejavascript 调用。但没有找到任何指南。

请帮助提供一些在 react native 中创建和注册原生到 javascript 模块的示例。


已经发现官方 native modules android 文档中的代码有一个名为 createJSModules 的方法,它返回 JavaScriptModule 类的列表。

class AnExampleReactPackage implements ReactPackage {

  @Override
  public List<Class<? extends JavaScriptModule>> createJSModules() {
    return Collections.emptyList();
  }

  ...

}

com.facebook.react.bridge.JavaScriptModule 的 Javadoc 说:

/**
 * Interface denoting that a class is the interface to a module with the same name in JS. Calling
 * functions on this interface will result in corresponding methods in JS being called.
 * ...
 */
@DoNotStrip
public interface JavaScriptModule {
}

我能够创建接口并将其类传递给 createJSModules,但不知道如何从 js 代码注册适当的 javascript 模块。

【问题讨论】:

    标签: android react-native


    【解决方案1】:

    最后,在查看了 react js 源码后,我想出了解决方案,你需要:

    1. 扩展 JavaScriptModule 并将其传递给自定义 react 包(例如 ActionsModule.java)的 createJSModules 方法。
    2. 在你的反应活动中注册那个包 getPackages 方法或直接想到 ReactInstanceManager
    3. 在你的 js 代码中创建同名的 js 文件
    4. 使用 BatchedBridge 注册它,如下面的清单所述。
    5. 比react context初始化后,你可以通过以下方式获取和调用:

      ActionsModule jsModule = context.getJSModule(ActionsModule.class); jsModule.callAction("问候", "你好");

    这将异步调用你注册的 js 模块方法。


    // AppPackage.java
    public class AppPackage implements ReactPackage {
    
        @Override
        public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
            return Collections.emptyList();
        }
    
        @Override
        public List<Class<? extends JavaScriptModule>> createJSModules() {
            return Arrays.<Class<? extends JavaScriptModule>>asList(
                    ActionsModule.class
            );
        }
    
        @Override
        public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
            return Collections.emptyList();
        }
    
    }
    
    // ActionsModule.java
    public interface ActionsModule extends JavaScriptModule {
    
        void callAction(String type, String value);
    
    }
    
    // MyReactActivity.java
    public class MyReactActivity extends ReactActivity implements ReactInstanceManager.ReactInstanceEventListener {
    
        ...
    
        @Override
        public void onReactContextInitialized(ReactContext context) {
            ActionsModule jsModule = context.getJSModule(ActionsModule.class);
    
            jsModule.callAction("greet", "hello");
        }
    
        ...
    
    }
    

    // ActionsModule.js
    var ActionsModule = {
    
      callAction(type, value) {
        console.log("callAction => " + type + ":" + value);
      },
    
    }
    
    module.exports = ActionsModule;
    
    // index.android.js
    import {
      AppRegistry
    } from 'react-native';
    
    import App from './components/App';
    
    // js module registration
    var BatchedBridge = require('BatchedBridge');
    var ActionsModule = require('./ActionsModule');
    
    BatchedBridge.registerCallableModule(
      'ActionsModule',
      ActionsModule
    );
    //~ js module registration
    
    AppRegistry.registerComponent('MyApp', () => App);
    

    UPD> 将一个演示项目推送到 github,并提供适用于 android 和 ios 的解决方案:https://github.com/dmba/rct-native2js

    【讨论】:

    • 如果您尝试从 React 对象导入 BatchedBridge,则它是未定义的。
    • 很好的解决方案~ 只是缺少MyReactActivity 中的一些代码。请在其中添加此代码。 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getReactInstanceManager().addReactInstanceEventListener(this); }
    • 关于如何在 iOS 上做到这一点的任何想法?在我浏览的文档和标题中都没有提到 JSModules。我不相信这是一个单一平台的功能。
    • @OleksandrYefremov,是的,我的朋友能够在 iOS 上做到这一点,周末将尝试上传适用于 android 和 iOS 的工作解决方案。
    • @OleksandrYefremov,我已经添加了github链接,请看一下。
    【解决方案2】:

    我不确定这是否可行,但是您为什么要这样做呢?使用 NativeAppEventEmitter/DeviceEventEmitter 并将其作为您将在 JS 端监听的事件发送。

    【讨论】:

    • 我目前正在使用事件发射器,但对其他原生方式感兴趣 - js 通信,因为有 java API 表示您实际上可以通过代理使用 js 实现从 java 执行接口方法。
    • 我很想知道你是否让它工作,我主要使用 observables 来做这种事情。您可以尝试查看事件发射器的源代码,看看它在哪里。
    猜你喜欢
    • 2016-10-30
    • 1970-01-01
    • 1970-01-01
    • 2020-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多