React native 官网上有关于 native module 的开发文档, ios 和 android(假设你已经熟悉了官方的这个2篇文档)。 文档给出了实现 RN native module 的 Api 说明和基本的例子。例子演示性的在 RN 的工程里直接添加了现实 native module 相关的源文件。按照这2篇文档去实现 android 和 ios 的 native module 后,其目录结构如下:
.
├── App.js
├── index.js
├── android
| ├── app
| | ├── src/com/***/
| | | ├── MainActivity.java
| | | ├── MainApplication.java
| | | ├── NativeModule.java // 继承 ReactContextBaseJavaModule 的类,
| | | | // 实现导出的给 js 的 api 接口
| | | └── NativeModulePackage.java // 继承 ReactPackage 的类,
| | | | // 注册 native module
| | └── ***
| └── ***
└── ios
├── projectNameFolder
| ├── AppDelegate.m
| ├── AppDelegate.h
| ├── NativeModule.h // 声明导出的给 js 的 api 接口,
| | // 声明该类实现 RCTBridgeModule 接口
| ├── NativeModule.m // 实现导出的给 js 的 api 接口
| └── ***
├── main.m
└── ***
我们可以看到 native module 的实现代码(NativeModule.java,NativeModulePackage.java, NativeModule.h, NativeModule.m)被直接插在了 RN 工程的项目里了。
对于演示场景,这样的实现没有问题,但是到了生产中就是另外一回事了。往往我们生产中的 native module 会更复杂,可能会涉及很多的源文件和第三方 SDK, 还要在不同的 RN 工程之间复用, 所以把 native module 独立工程化在生产中是必要的。
实际上我们对此并不陌生, 因为我们所使用的知名第三方 RN 插件均是脱离具体 RN 工程的独立模块,比如: react-native-navigation。
构建 Native Module 插件工程
本文的主要思路是将 native module 的 ios 原生代码做成一个 static Library 工程, android 原生代码做成一个 Android Library, 最后把 static Library 工程、Android Library 工程以及js 代码一起打包成 npm 包, 便于发布。目录结构如下:
.
├── android // Android Library, Android 的原生实现
| ├── app
| | ├── src/com/***/
| | | ├── NativeModule.java // 继承 ReactContextBaseJavaModule 的类,
| | | | // 实现导出的给 js 的 api 接口
| | | └── NativeModulePackage.java // 继承 ReactPackage 的类,
| | | | // 注册 native module
| | └── ***
| └── ***
└── ios // Ios static Library, ios 的原生实现</