加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

React-Native:调用(Android)Native方法

发布时间:2020-12-15 07:38:24 所属栏目:百科 来源:网络整理
导读:有的时候我们使用React Native无法满足一些使用特定场景,这个时候就需要使用原生的Android方法,比如一些耗时的写操作,操作数据库或者多线程操作等。React Native可以直接调用系统的API(java方法),实现JavaScript与java语言的通讯,如果React Native中没

有的时候我们使用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 app
在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;

在JavaScript可以这样调用:

rnToastAndroid.show("我的万能JS",function (args) {
            alert(args)
        });

最后我们定义一个React调用的方法:

@ReactMethod
    public void show(String msg,Callback callback){
        Toast.makeText(getReactApplicationContext(),"Js调用显示原生传递的参数是:"+msg,Toast.LENGTH_LONG).show();
        callback.invoke("RNToastModule 调用JS方法");
    }

完整RNToastModule代码:

/* ******************************* Copyright (c)********************************* ** ** (c) Copyright 2015,Allen,china,shanghai ** All Rights Reserved ** ** ** **-----------------------------------版本信息------------------------------------ ** 版 本: V0.1 ** **------------------------------------------------------------------------------ ********************************End of Head************************************ */
package com.app;

import android.widget.Toast;

import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

/** * 文 件 名: RNToastModule * 创 建 人: Allen * 创建日期: 17/1/2 23:17 * 邮 箱: AllenCoder@126.com * 修改时间: * 修改备注: */
public class RNToastModule extends ReactContextBaseJavaModule{
    public RNToastModule(final ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @Override
    public String getName() {
        return "RNToastAndroid";
    }
    @ReactMethod
    public void show(String msg,Toast.LENGTH_LONG).show();
        callback.invoke("RNToastModule 调用JS方法");
    }
}

这个使用了annotation定义的方式必须加上@ReactMethod。
这里的参数只能React Navive定义的参数。

注册ReactPackage
新建一个JsReactPackage类,继承ReactPackage。

/* ******************************* Copyright (c)********************************* ** ** (c) Copyright 2015,shanghai ** All Rights Reserved ** ** ** **-----------------------------------版本信息------------------------------------ ** 版 本: V0.1 ** **------------------------------------------------------------------------------ ********************************End of Head************************************ */
package com.app;

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;

/** * 文 件 名: JsReactPackage * 创 建 人: Allen * 创建日期: 17/1/2 22:34 * 邮 箱: AllenCoder@126.com * 修改时间: * 修改备注: */
public class JsReactPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(final 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(final ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

JsReactPackage创建了一个NativeModule的List。把JsReactPackage的实例都添加进去提供给JavaScript层调用。

需要在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 JsReactPackage()       
         ); 
     }
};

JavaScript中调用
在JavaScript显示Toast:

'use strict';

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

rnToastAndroid.show("我的万能JS",function (args) {
            alert(args)
        });

这样就完成了从JavaScript中直接调用了Java中定义的方法。

参考链接

  1. http://www.52php.cn/article/p-oontpilv-b.html
  2. http://www.52php.cn/article/p-vsvgomrh-bev.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读