React Native调用Android原生方法

作者: 辅助上分 | 来源:发表于2017-08-15 21:32 被阅读0次

当有时候RN项目需要访问原生的api但是rn官方并还没封装这个模块时,就需要使用自己去手动封装。调用Android原生代码,以最简单的弹Toast为例:

  • 定义ReactContextBaseJavaModule模块

    1. 首先在android的目录下定义一个类去继承ReactContextBaseJavaModule类,实现getName方法。此方法返回的参数就是你使用js调用的模块名。
    2. 根据自己的需求选择是否去重写getConstants方法,这个方法的作用是给js提供一些常量使用,通过map的键值去存储,map的键是js调用的名称,key是对应的值。
    3. 然后就是定义你对js提供的方法,对js提供的方法必须是没有返回值的,如果需要有返回值的话,则需要增加Callback参数,js通过callback获取函数需要返回的值。需要注意的是必须在方法上面加上@ReactMethod注解,才能让js识别调用。具体代码如下:
/**
 * 原生模块
 */
public class ToastModule extends ReactContextBaseJavaModule {

    private static final String DURATION_SHORT_KEY = "SHORT";
    private static final String DURATION_LONG_KEY = "LONG";
    public ToastModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    /**
     *
     * @return js调用的模块名
     */
    @Override
    public String getName() {
        return "ToastModule";
    }

    /**
     * 给rn定义模块的一些常量
     * @return 常量的一些键值
     */
    @Nullable
    @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注解,使这个方法被js调用
     * @param message 文本
     * @param duration 时长
     */
    @ReactMethod
    public void show(String message, int duration, Callback success,Callback error) {
        try {

            Toast.makeText(getReactApplicationContext(), message, duration).show();
            success.invoke("success");
        }
        catch (Exception e){
            error.invoke("error");
        }
    }
}

  • 定义好模块之后,接下来就需要去注册模块。非常简单,定义一个类去实现,ReactPackage接口。这个接口只有两个方法,createViewManagers他是注册需要被调用原生控件的(下篇文章会讲到),createNativeModules就是注册原生方法需要实现的,他的返回值是个list,创建一个list然后把你之前定义的ReactContextBaseJavaModule添加进去就好。代码如下。
public class ToastReactPackage implements ReactPackage {
    /**
     *
     * @param reactContext 上下文
     * @return 需要调用的原生控件
     */
    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    /**
     *
     * @param reactContext 上下文
     * @return 需要调用的原生模块
     */
    @Override
    public List<NativeModule> createNativeModules(
            ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();

        modules.add(new ToastModule(reactContext));

        return modules;
    }
}

  • 把上一步定义好的ReactPackage模块在application下注册。原生这边所有的工作就已经结束。
public class MainApplication extends Application implements ReactApplication {

    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
            return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(
                    new MainReactPackage(),
                    new ToastReactPackage()//新添加需要注册的模块
            );
        }
    };


  • 原生端工作已完成。接下来就是js端,只需要加载NativeModules模块,
    从NativeModules中获取之前定义的ReactContextBaseJavaModule对应的getName的值就可以调用对应的方法了,具体如下:
import React, {Component} from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    NativeModules
} from 'react-native';

export default class RNDemo extends Component {
    _toast(){
        NativeModules.ToastModule.show('toast', NativeModules.ToastModule.SHORT,(success)=>{alert(success)},(error)=>{alert(error)})
    }
    render() {
        return (
            <View style={styles.container}>
                <Text onPress={this._toast} style={styles.welcome}>
                    Welcome to React Native!
                </Text>

            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {

        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },

});

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

相关文章

网友评论

    本文标题:React Native调用Android原生方法

    本文链接:https://www.haomeiwen.com/subject/dwzvrxtx.html