是否有任何指南在react-native中实现JavaScriptModule?

时间:2016-07-29 14:15:06

标签: android react-native

有兴趣在react-native中实施直接原生 javascript 调用。但没有找到任何指南。

请帮助一些在本地反应中创建和注册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模块。

2 个答案:

答案 0 :(得分:6)

最后,在查看了反应来源后,我想出了解决方案,你需要:

  1. 扩展JavaScriptModule并将其传递给自定义反应包的 createJSModules 方法(例如ActionsModule.java)。
  2. 注册您的内容包反应活动 getPackages 方法或直接认为 ReactInstanceManager
  3. 在js代码中创建具有相同名称的js文件
  4. 使用 BatchedBridge 注册,如下面的清单所述。
  5. 比反应上下文初始化后,您可以通过以下方式获取并致电:

    ActionsModule jsModule = context.getJSModule(ActionsModule.class); jsModule.callAction(&#34; greet&#34;,&#34; hello&#34;);

  6. 这将异步调用您注册的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&GT;使用android和ios的解决方案向github推送了一个演示项目:https://github.com/dmba/rct-native2js

答案 1 :(得分:0)

我不确定这是否可能,但为什么你还想这样做呢?使用NativeAppEventEmitter / DeviceEventEmitter并将其作为您将在JS方面收听的事件发送。