美文网首页react-nativeReact Native其他
[React Native]原生模块(上)

[React Native]原生模块(上)

作者: zhuhf | 来源:发表于2016-05-19 22:32 被阅读1492次

    正如上篇文章[React Native]移植原生Android项目中提到,ReactNative目前更多的是用于在原生App中加入一个新的模块。那么,此时如果这个ReactNative模块需要使用到一些原生模块的功能,比如访问平台的API;或者你要复用现成的Java代码;又或者使用Java已经成熟的第三方Library,那么这篇文章会一步步告诉你,如何去调用一个已经封装好的Android原生代码。

    实际上,正如上篇文章[React Native]移植原生Android项目中提到,目前更多的还是使用React来做V的工作,那么诸如网络请求之类还是通过在ReactNative模块中调用原生已经封装好的库来实现(据说饿了么目前就是这个方案~)

    为了更好的理解,本文演示如何在ReactNative中使用Android平台的Toast功能。

    • 步骤一:新建ReactNative项目

      使用下面的命令新建一个ReactNative项目,确保你的环境已经配置正确,有问题可以参考[React Native]入门篇
      react-native init Demo2
      让我们运行下新建的项目,效果如下

      Paste_Image.png
    • 步骤二:新建原生模块

      用AS开发工具打开Demo2目录下的android项目,新建一个classToastModule继承ReactContextBaseJavaModule,我们的目标是在JS中这样写ToastAndroid.show("Test Toast",ToastAndroid.SHORT),来显示一个Toast
      public class ToastModule extends ReactContextBaseJavaModule {
      public ToastModule(ReactApplicationContext reactContext) {
      super(reactContext);
      }
      }
      ReactContextBaseJavaModule要求实现getName方法,该方法返回一个String,表示模块的名称,这里返回ToastAndroid
      @Override
      public String getName() {
      return "ToastAndroid";
      }
      一个可选的方法getConstants,用来封装常量给JS模块使用,比如我们将要用到的常量ToastAndroid.SHORT

      @Override
      public Map<String, Object> getConstants() {
        final Map<String, Object> constants = new HashMap<>();
        constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
        constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
        return constants;
      }
      

    Java中的方法需要导出才能给JS使用,要导出Java方法,需要使用@ReactMethod来注解,且方法的返回值只能是void
    @ReactMethod
    public void show(String message, int duration) {
    Toast.makeText(getReactApplicationContext(), message, duration).show();
    }
    这样,我们的原生模块已经创建完毕,下面需要注册原生模块了。

    • 步骤三:注册原生模块

      新建一个classMyReactPackager,实现ReactPackager接口,我们需要实现createNativeModules方法,该方法返回所有需要被加载的原生模块。
      public class MyReactPackager implements ReactPackage {
      @Override
      public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
      List<NativeModule> viewManagers = new ArrayList<>();
      viewManagers.add(new ToastModule(reactContext));
      return viewManagers;
      }

        @Override
        public List<Class<? extends JavaScriptModule>> createJSModules() {
          return Collections.emptyList(); // 返回null会报错
        }
      
        @Override
        public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
          return Collections.emptyList(); // 返回null会报错
        }
      }
      

    我们新建的MyReactPackager,需要在MainActivitygetPackages中注册并返回。

      /**
       * A list of packages used by the app. If the app uses additional views
       * or modules besides the default ones, add more packages here.
       */
      @Override
      protected List<ReactPackage> getPackages() {
        return Arrays.<ReactPackage>asList(
            new MainReactPackage(),
            new MyReactPackager() // 这是我们自定义的ReactPackager
        );
      }
    

    到此原生模块的工作已经告一段落,下面让我们看下如下在ReactNative中调用我们的原生模块。

    • 步骤四:使用原生模块
      打开index.android.js文件,在render方法中用TouchableOpacity封装一个可以点击的视图Text,文本内容为Click to show native Toast

      render() {
        return (
          <View style={styles.container}>
            <TouchableOpacity onPress={this.onPressButton}>
              <Text style={styles.instructions}>
              Click to show native Toast
              </Text>
            </TouchableOpacity>
          </View>
        );
      }
      

    JS文件中,引入我们步骤二中新建的原生模块ToastAndroid

      var ToastAndroid = require('ToastAndroid');
    

    TouchableOpacity点击方法为onPressButton,它会调用原生模块导出的show方法。

      onPressButton() {
        ToastAndroid.show('Android Toast', ToastAndroid.SHORT);
      }
    

    让我们运行下项目,最终效果图如下:

    device-2016-05-19-221758_0-24.gif

    本文的源码地址Demo2

    下一篇文章会介绍JS调用原生模块的高级用法,敬请期待~

    相关文章

      网友评论

      • Jics:getName方法的返回值为“ToastAndroid”会跟RN内置的ToastAndroid模块名字冲突
      • putaozhuose:博主真是爱死你了,你写的都是都是我需要的。

      本文标题:[React Native]原生模块(上)

      本文链接:https://www.haomeiwen.com/subject/lnrgrttx.html