有时候App需要访问平台API,但React Native可能还没有相应的模块包装;或者你需要复用一些Java代码,而不是用Javascript重新实现一遍;又或者你需要实现某些高性能的、多线程的代码,譬如图片处理、数据库、或者各种高级扩展等等。
我们把React Native设计为可以在其基础上编写真正的原生代码,并且可以访问平台所有的能力,我们可以自己实现一些封装,供JS调用。
react native中文网,和原官方网站给出的例子不是很详细,我这里就给出详细的步骤,一步一步的给出如何调用toast这个模块的。
第一步:在命令行下输入下面的命令 创建一个react native工程
$ react-native init ToastTest
第二步:创建一个原生模块。一个原生模块是一个继承了ReactContextBaseJavaModule 的Java类,它可以实现一些JavaScript所需的功能。代码如下:
package com.toasttest; 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; import java.util.Map; import java.util.HashMap; public class ToastHello extends ReactContextBaseJavaModule { private static final String DURATION_SHORT_KEY = "SHORT"; private static final String DURATION_LONG_KEY = "LONG"; public ToastHello(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { //返回供JS调用的模块名字 return "ToastHello"; } 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; @ReactMethod public void show(String message,int duration) { //供js调用的具体方法 Toast.makeText(getReactApplicationContext(),message,duration).show(); } }
文件结构如下:
第三步:注册模块
我们需要在应用的Package类的createNativeModules 方法中添加这个模块。以便在JavaScript中访问到刚才写的原生模块。
新建一个ToastHelloPackage.java类,输入一下代码:文件的目录结构参看上图
package com.toasttest; /** * Created by andy on 16/9/1. */ 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 ToastHelloPackage 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 ToastHello(reactContext)); return modules; } }
第四步:把原生模块封装成一个JavaScript模块
这一步不是必须的,但是不封装如何调用,我还不知掉,就按照文档说的封装吧,哈哈
在index.android.js 的同级目录新建一个文件ToastHello.js,输入一下内容:
'use strict'; /** * This exposes the native ToastAndroid module as a JS module. This has a function 'show' * which takes the following parameters: * * 1. String message: A string with the text to toast * 2. int duration: The duration of the toast. May be ToastAndroid.SHORT or ToastAndroid.LONG */ import { NativeModules } from 'react-native'; // 下一句中的ToastAndroid即对应上文 // public String getName()中返回的字符串 // 练习时请务必选择另外的名字! export default NativeModules.ToastHello;
第五步:在js调用刚才写的方法
本例子除了在js一加载就调用了该方法,还写了一个button,点击button也会调用刚才的方法。代码如下:
import React,{ Component } from 'react'; import { AppRegistry, StyleSheet,TouchableHighlight, Text, View } from 'react-native'; import ToastHello from './ToastHello' class Mybutton extends Component{ _onPressButton(){ ToastHello.show('Button call native fun!',ToastHello.SHORT); //点击按钮调用native方法 } render(){ return ( <TouchableHighlight onPress={this._onPressButton}> <Text>Button</Text> </TouchableHighlight> ); } class ToastTest extends Component { render() { <View style={styles.container}> <Mybutton style={{width:300,height:200}}/> <Text style={styles.welcome}> Welcome Andy! </Text> </View> } componentDidMount() {//React组件的一个生命周期方法,组件加载完后调用。 ToastHello.show('Hello andy! call native fun',ToastHello.LONG); //调用native方法 const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center',255)"> alignItems: 'center',255)"> backgroundColor: '#F5FCFF',255)"> },255)"> welcome: { fontSize: 20,255)"> textAlign: 'center',255)"> margin: 10,255)">}); AppRegistry.registerComponent('ToastTest',() => ToastTest);
参考文档: react native中文网 原生模块 Native Modules (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|