关于如何桥接native code,React Native的官网并没有多少篇幅介绍。通过Google和StackOverflow,收集了一些资料。这里分享下如何为Android写一个最简单,最干净的React Native Module。
准备工作
- Android Studio
- React Native CLI:
npm install -g react-native-cli
最简单的Native Module
工程的基本结构如下:
--Project folder
--package.json
--android // a folder that contains Java code for native module
--index.js
Package.json
创建一个工程目录react-native-helloworld。使用npm来初始化:
cd react-native-helloworld
npm init
自动生成package.json文件。
Android目录
Android目录里放置Android工程代码。结构如下:
包含build.gradle,AndroidManifest.xml,以及Java代码。
MyModule继承ReactContextBaseJavaModule,主要实现JavaScript需要调用的接口:
package com.yushulx.helloworld;
import android.widget.Toast;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
public class MyModule extends ReactContextBaseJavaModule {
public MyModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "MyModule";
}
@ReactMethod
public void alert(String message) {
Toast.makeText(getReactApplicationContext(), message, Toast.LENGTH_LONG).show();
}
}
注意getName中返回的string值和类名必须相同。
MyPackage用于注册模块:
package com.yushulx.helloworld;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MyPackage implements ReactPackage {
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules( ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new MyModule(reactContext));
return modules;
}
}
Index.js
这个文件主要用于导出native module,方便UI层的JavaScript调用:
import {NativeModules} from 'react-native';
module.exports = NativeModules.MyModule;
如何在React Native工程中使用Native Module
可以在模块工程目录下创建一个新的工程:
react-native init Example
如何安装这个本地磁盘上的插件?只需要把插件目录的路径写到package.json中,然后通过npm install安装即可:
"dependencies": {
"react": "16.0.0-alpha.6",
"react-native": "0.43.3",
"react-native-helloworld":"file:../"
},
通过命令行自动添加关联代码:
react-native link
这行命令会修改几个文件。
- android\settings.gradle
include ':react-native-helloworld' project(':react-native-helloworld').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-helloworld/android')
- android\app\build.gradle
dependencies { compile project(':react-native-helloworld') }
- android\app\src\main\java\com\example\MainApplication.java
import com.yushulx.helloworld.MyPackage; protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new MyPackage() ); }
在index.android.js中使用native module:
import MyModule from 'react-native-helloworld';
const onButtonPress = () => {
MyModule.alert('Hello World');
};
export default class Example extends Component {
render() {
return (
<View style={styles.container}>
<Button title='Click' onPress={onButtonPress}/>
</View>
);
}
}
运行程序: