react-native:挪用Native要领(Android)

有的时刻我们运用React Native没法满足一些运用特定场景,这个时刻就须要运用原生的Android要领,比方一些耗时的写操纵,操纵数据库或许多线程操纵等。
React Native能够直接挪用体系的API(java要领),完成JavaScript与java言语的通讯,假如React Native中没有满足我们需求的Api,能够封装原生的要领供应JavaScript挪用。
JavaScript和java通讯是经由过程bridge完成的,在java层和JavaScript层的bridge离别存有雷同的一份模块设置表。Java与JavaScript互相通讯时,经由过程bridge里的设置表将所挪用模块体式格局转为{moduleID,methodID,args}的情势传递给处置惩罚层,处置惩罚层经由过程bridge里的设置表找到对应的要领实行,假如有callback,则回传给挪用层,假如没有实行就完毕。

我们经由过程JavaScript挪用Toast的例子来看下,JavaScript怎样挪用Java代码的。

新建一个项目:

react-native init RNAndroid

在android的项目目次下面新建一个类RNToastModule,此类须要继续ReactContextBaseJavaModule

ReactContextBaseJavaModule

ReactContextBaseJavaModule是一个抽象类,是用来被JavaScript挪用对象的父类,我们须要Override一些ReactContextBaseJavaModule的要领。

起首要Override getName()要领:

   @Override
   public String getName() {
       return "RNToastAndroid";
   }

这个要领的返回值就是JavaScript中挪用的称号,比方我们命名为RNToastAndroid,在JavaScript中能够如许挪用:

var {NativeModules}=require('react-native');
var rnToastAndroid = NativeModules.RNToastAndroid;

然后我们能够选择性的掩盖getConstants()要领:
这个要领的用在JavaScript和Java直接定义公用常量的,它运用key-value的体式格局保留。
在Java中定义两个变量:

   private static final String DURAION_SHORT_KEY = "SHORT";
   private static final String DURAION_LONG_KEY = "LONG";

getConstants()中给两个字符串赋值:

    @Override
    public Map<String, Object> getConstants() {
        final Map<String, Object> constants = new HashMap<>();
        constants.put(DURAION_SHORT_KEY, Toast.LENGTH_SHORT);
        constants.put(DURAION_LONG_KEY, Toast.LENGTH_LONG);
        return constants;
    }

我们把Toast的两个常量放在了 constants中。
在JavaScript能够如许挪用:

rnToastAndroid.show('Hello Toast of native', rnToastAndroid.SHORT);

末了我们定义一个React挪用的要领:

    @ReactMethod
    public void show(String message, int duration) {
        Toast.makeText(getReactApplicationContext(), message, duration).show();

    }

这个运用了annotation定义的体式格局必需加上@ReactMethod
这里的参数只能React Navive定义的参数。

ReactMethod的对应参数

@ReactMethod中传的参数必需是JavaScript和Java对应的。

Boolean -> Bool
Integer -> Number
Double -> Number
Float -> Number
String -> String
Callback -> function
ReadableMap -> Object
ReadableArray -> Array

注册ReactPackage

新建一个RNJavaReactPackage类,继续ReactPackage。

    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new RNToastModule(reactContext));
        return modules;
    }

    @Override
    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return new ArrayList<>();
    }

RNJavaReactPackage创建了一个NativeModule的List。把RNToastModule的实例都增加进去供应给JavaScript层挪用。

增加ReactPackage

android/app/src/main/java/com/your-app-name/中有个MainActivity.java个中的getPackages()要领用来返回用来的ReactPackage包,增加定义好的RNJavaReactPackage的实例
以上内容已经在0.31.0中更新。
新版本运用ReactNativeHost替代ReactInstanceManager,ReactNativeHost是设置Android相干设置的类。
须要在Application中实例化。
起首完成新建一个ReactNativeHost的实例并增加RNJavaReactPackage的实例:

private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 
   @Override   
   protected boolean getUseDeveloperSupport() {   
       return BuildConfig.DEBUG;   
   } 
   @Override   
   protected List<ReactPackage> getPackages() { 
         return Arrays.<ReactPackage>asList(
                new MainReactPackage(),         
               new RNJavaReactPackage()       
         ); 
     }
};

完成ReactApplication:

public class MainApplication extends Application implements ReactApplication {    
    @Override    
    public ReactNativeHost getReactNativeHost() {      
        return mReactNativeHost;   
   }
}

JavaScript中挪用

在JavaScript显现Toast:

'use strict';

var {NativeModules}=require('react-native');
var rnToastAndroid = NativeModules.RNToastAndroid;

rnToastAndroid.show('Hello Toast of native', rnToastAndroid.SHORT);

如许就完成了从JavaScript中直接挪用了Java中定义的要领。

代码地点:https://github.com/jjz/react-…

    原文作者:姜家志
    原文地址: https://segmentfault.com/a/1190000004486024
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞