美文网首页
React Native 原生模块封装(Android篇)

React Native 原生模块封装(Android篇)

作者: Scott昵称被占用 | 来源:发表于2018-01-05 01:45 被阅读116次

    React Native 原生模块封装(IOS篇)

    前言

    有时候React Native没有相应的模块, API无法满足我们的需要时,或者我们需要复用Object-C, Swift或者Java代码的时候,而又不是用JavaScript重新实 现一边,又或者你需要实现某些高性能、多线程的代码,譬如图片处理、数据库、或者各种高级扩展等等。

    我们把React Native设计为可以在其基础上编写真正的原生代码,并且可以访问平台所有的能力。这是一个相对高级的特性,我们并不认为它应当在日常开发的过程中经常出现,但具备这样的能力是很重要的。如果React Native还不支持某个你需要的原生特性,你应当可以自己实现该特性的封装。然后提供出Android或者IOS共用的接口给React Native调用

    用法

    第一步:

    在React Native中, 一个本地的“原生模块”其实就是继承了ReactContextBaseJavaModule的Java类,它可以实现一些JavaScript所需的功能。

    package com.my;
    
    import android.widget.Toast;
    
    import com.facebook.react.bridge.ReactApplicationContext;
    import com.facebook.react.bridge.ReactContextBaseJavaModule;
    import com.facebook.react.bridge.ReactMethod;
    
    /**
     * Created by scottwang on 2018/1/5.
     */
    
    public class UserNativeModules extends ReactContextBaseJavaModule {
        public UserNativeModules(ReactApplicationContext reactContext) {
            super(reactContext);
        }
    
        /**
         * ReactContextBaseJavaModule要求派生类实现getName方法。
         * 这个函数用于返回一个字符串名字,这个名字在JavaScript端标记这个模块。
         * 这里我们把这个模块叫做UserNativeModules,
         * 这样就可以在JavaScript中通过React.NativeModules.UserNativeModules访问到这个模块。
         * @return
         */
        @Override
        public String getName() {
            return "UserNativeModules";
        }
    
        /**
         * 要导出一个方法给JavaScript使用,Java方法需要使用注解@ReactMethod。
         * 方法的返回类型必须为void。React Native的跨语言访问是异步进行的。
         * @param name
         * @param password
         */
        @ReactMethod
        public void userLogin(String name, String password) {
            Toast.makeText(getReactApplicationContext(), name+" : "+password,Toast.LENGTH_LONG).show();
        }
    }
    

    第二步:注册模块

    在Java这边要做的最后一件事就是注册这个模块。我们需要在应用的Package类的createNativeModules方法中添加这个模块。如果模块没有被注册,它也无法在JavaScript中被访问到。

    package com.my;
    
    import com.facebook.react.ReactPackage;
    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 UserReactPackage implements ReactPackage {
        @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 UserNativeModules(reactContext));
            return modules;
        }
    }
    

    第三步: 导出包

    这个package需要在Application.java文件的getPackages方法中提供。

    package com.my;
    
    import android.app.Application;
    
    import com.facebook.react.ReactApplication;
    import com.facebook.react.ReactNativeHost;
    import com.facebook.react.ReactPackage;
    import com.facebook.react.shell.MainReactPackage;
    import com.facebook.soloader.SoLoader;
    
    import java.util.Arrays;
    import java.util.List;
    
    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 UserReactPackage()
          );
        }
    
        @Override
        protected String getJSMainModuleName() {
          return "index";
        }
      };
    
      @Override
      public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
      }
    
      @Override
      public void onCreate() {
        super.onCreate();
        SoLoader.init(this, /* native exopackage */ false);
      }
    }
    

    第四步: React Native中调用

    为了让你的功能从JavaScript端访问起来更为方便,通常我们都会把原生模块封装成一个JavaScript模块。这不是必须的,但省下了每次都从NativeModules中获取对应模块的步骤。这个JS文件也可以用于添加一些其他JavaScript端实现的功能。

    /**
     * Sample React Native App
     * https://github.com/facebook/react-native
     * @flow
     */
    
    import React, { Component } from 'react';
    import {
      Platform,
      StyleSheet,
      Text,
      View,
      Button,
      Alert
    } from 'react-native';
    
    import { NativeModules } from 'react-native';
    var UserNativeModules = NativeModules.UserNativeModules;
    
    const instructions = Platform.select({
      ios: 'Press Cmd+R to reload,\n' +
        'Cmd+D or shake for dev menu',
      android: 'Double tap R on your keyboard to reload,\n' +
        'Shake or press menu button for dev menu',
    });
    
    const onButtonPress = () => {
      Alert.alert('Button has been pressed!');
      UserNativeModules.userLogin("User Id","password");
    };
    
    export default class App extends Component {
      render() {
        return (
          <View style={styles.container}>
            <Text style={styles.welcome}>
              Welcome to React Native!
            </Text>
            <Text style={styles.instructions}>
              To get started, edit App.js
            </Text>
            <Text style={styles.instructions}>
              {instructions}
            </Text>
            
            <Button
              onPress={onButtonPress}
              title="Learn More"
              color="#841584"
              accessibilityLabel="Learn more about this purple button"
            />
    
          </View>
        );
      }
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
      },
      welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
      },
      instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5,
      },
    });
    
    

    相关文章

      网友评论

          本文标题:React Native 原生模块封装(Android篇)

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