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

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 createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
    @Override
    public List createNativeModules(
            ReactApplicationContext reactContext) {
        List 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 getPackages() {
      return Arrays.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 (
      
        
          Welcome to React Native!
        
        
          To get started, edit App.js
        
        
          {instructions}
        

        

你可能感兴趣的:(《React,Native跨平台开发》,React,Native学习笔记)