在Android原生应用中集成React Native版本的豆瓣电影

2,034 阅读2分钟

Github 项目 HybridApp

这是一个在Android原生应用中集成React Native 的项目。在原生应用中集成了一个仿豆瓣客户端(很久之前写的,UI已经不怎么像了o(╯□╰)o)的React Native应用。

效果图

top250

yuanxian

更多效果图可参考HybridApp

集成React Native到原生应用

其实,关于怎么把React Native集成到原生应用中,React Native的官方文档Integration with Existing Apps已经有了详细的说明,严格的照着文档一步一步执行下来,基本上是没有什么问题的。

这里再补充一点官网没有提及的内容吧,就是如果在React Native 应用中使用到了原生应用的组件,比如常见的react-native-camera/react-native-image-picker 等,这个时候该如何正确的把这写原生组件集成到原生项目中呢?

其实,如果你用AS打开过React Native项目下Android目录的话,可以发现其实原生组件(比如react-native-camera)就是一个主工程(app)依赖的子module.在React Native的项目中,我们通过执行react-native link 这个命令,React Native框架会自动帮我们实现整个依赖过程,在这中间主要做了三件事:

  • 在setting.gradle 文件中添加依赖组件的别名及路径
include ':react-native-camera'
project(':react-native-camera').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-camera/android')
  • 在app/build.gradle dependencies 结点中添加依赖
dependencies {
    compile project(':react-native-camera')
    compile fileTree(dir: "libs", include: ["*.jar"])
    compile "com.android.support:appcompat-v7:23.0.1"
    compile "com.facebook.react:react-native:+"  // From node_modules
}
  • 在MainApplication.java 的getPackages()方法中,为我们添加组件所对应的Package。
    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
            return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(
                new MainReactPackage(),
                new RCTCameraPackage()
            );
        }

        @Override
        protected String getJSMainModuleName() {
            return "index";
        }
    };

不得不说,这几个自动实现的步骤的确很牛逼,不知道内部是咋实现的?୧(๑•̀◡•́๑)૭

稍显遗憾的是,把React Native集成到原生项目中后,再次执行react-native link后上述步骤是无法自动实现的,因此这就需要我们去手动添加原生组价的依赖。其实这个过程也很简单,理解了node_modules目录和项目目录之间的相对路劲关系即可。这里以此项目中setting.gradle 中的路劲为例:

include ':app'
include ':react-native-camera'
project(':react-native-camera').projectDir = new File(rootProject.projectDir, 'node_modules/react-native-camera/android')
include ':react-native-video'
project(':react-native-video').projectDir = new File(rootProject.projectDir, 'node_modules/react-native-video/android')
include ':react-native-image-crop-picker'
project(':react-native-image-crop-picker').projectDir = new File(rootProject.projectDir, 'node_modules/react-native-image-crop-picker/android')

这里其实和原生应用中子module是一个意思,只不过在原生项目中,子module一般都是直接创建在项目根目录中,就省去了写projectDir 的步骤了。有了这个自module,剩下的两个步骤就很简单了,这里就不再赘述,直接看代码就明白了。

更多细节源码,有兴趣的同学可参考github源码了解。

更多

应用中用到的数据,抓取自豆瓣API及豆瓣开发平台,仅供学习