React-Native Native Module In Practise
React-Native 是Facebook 开发的一套移动端跨平台开发的框架,其脱胎于 ReactJS 。React-Native允许你使用JavaScript开发移动端的应用,相对于 PhoneGap React-Native 确实带来了原生应用的性能,如果之前有写过ReactJS,用React-Native开发一个移动端应用是非常容易的。不过虽然React-Native社区一天天壮大,但是仍旧可能需要自己开发一些React-Native的原生模块。
什么是React-Native原生模块
React-Native 模块就是包含原生代码库的React-Native的模块(在Android 里是包含Java代码库,在iOS里是包含Objecive-C/Swift代码库),其工作原理是将原生代码库加载到React-Native的包管理器中,然后用JS通过React-Native的bridge调用原生库里的方法,最后返回结果。
Setup
- 需要安装Node.JS和NPM
- 需要安装Android SDK 和Android Studio https://developer.android.com
创建React-Native项目
- 创建工作目录
mkdir hello-rct
- 使用
npm init
初始化项目 - 使用android sdk自带的cli工具初始化一个android library项目
android create lib-project \
--name hellorct \ # Project name
--target android-23 \ # Android SDK version(target)
--package com.xeodou.hellorct \ # Package name
--gradle --gradle-version 1.3+ \ # Use gradle and 2.4 later version
--path android # The project's directory
4.在android/build.gradle
最后添加
dependencies {
compile 'com.facebook.react:react-native:0.13.+'
}
5.创建Java组件
添加HelloRCTManager.java
/*
* @Author: xeodou
* @Date: 2015
*/
package com.xeodou.hellorct
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 HelloRCTManager 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 HelloRCT(reactContext));
return modules;
}
}
创建HelloRCT.java
/*
* @Author: xeodou
* @Date: 2015
*/
package com.xeodou.hellorct
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
public class HelloRCT extends ReactContextBaseJavaModule {
public static final String REACT_CLASS = "HelloRCT";
public HelloRCT(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return REACT_CLASS; //这里的getName方法是将你的原生模块注册
} //到React-Native的模块包管理器中,然后
//在使用JS使用相同的名字获得该原生模块
@ReactMethod // ReactMethod表明该方法是暴露给JS的
public void hello(Callback cb) {// 的外部方法,返回一个字符串`Hello RCT`
cb.invoke("Hello RCT"); // React-Native的调用是异步的
} // 所以这里我们用Callback返回结果
}
6.创建index.android.js
/*
* hello-rct - index.android.js
* Copyright(c) 2015 xeodou <[email protected]>
* MIT Licensed
*/
var { NativeModules } = require('react-native');
module.exports = NativeModules.HelloRCT;
7.使用react-native init Example
创建一个React-Native的Example应用测试我们的模块
- 修改
Example/settings.gradle
include ':app','hellorct'
project(':hellorct').projectDir = new File(rootProject.projectDir, '../../android')
- 修改
Example/app/build.gradle
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.facebook.react:react-native:0.13.+'
compile project(':hellorct') // <- 添加这行
}
- 修改
Example/app/src/main/java/.../MainActivity.java
import com.xeodou.hellorct.HelloRCTManager; //<- import java class
public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.addPackage(new HelloRCTManager()) //<- 注册模块
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager, "Example", null);
setContentView(mReactRootView);
}
...
}
- 修改
Example/index.android.js
...
var { NativeModules } = require('react-native');
var HelloRCT = NativeModules.HelloRCT;
var Example = React.createClass({
getInitialState: function() {
return {};
},
click: function() {
HelloRCT.hello( msg => {
this.setState({
hello: msg
})
})
},
render: function() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Hi, {this.state.hello}
</Text>
<TouchableHighlight onPress={this.click}>
<Text >Press!</Text>
</TouchableHighlight>
</View>
);
}
});
...
8.cd Example && react-native run-android
Cheers!!