有时候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";
    }

    @Override
    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();
    }
}

文件结构如下:


android原生做游戏 原生安卓怎么玩_react-native

第三步:注册模块 

createNativeModules方法中添加这个模块。以便在JavaScript中访问到刚才写的原生模块。

文件的目录结构参看上图

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() {
    return (
      <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',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
});

AppRegistry.registerComponent('ToastTest', () => ToastTest);