reactnative桥接原生模块(代码片段)

rogerwu rogerwu     2023-04-24     381

关键词:

原生模块简介

有时候一个 RN 应用需要访问一个原生平台的 API 比如相机,但是,默认情况下 JavaScript 是无法访问原生 API 的。

原生模块系统暴露了一些 Java 类的实例对象给 JavaScript,这样就可以允许开发者在 JS 代码中执行一些特定的原生代码。

简单来说,桥接原生就是为了实现 react 层 JS 实现不了的需求,比如:

  • 复杂、高性能组件:复杂表格、视频播放等;
  • 原生层开发能力:传感器编程、widget等;
  • 平台属性:系统信息、设备信息等;
  • 对接三方应用:相机、相册、地图等;

 

桥接原生方法

◆ 编写并注册原生层方法

1、使用 Android Studio 编辑器依次找到 android > app > src > main > java > com.rndemo (RN应用的项目名称) > MainApplication.java

找到 getPackages 这个方法,可以看到该方法返回的是 ReactNative 桥接的各种包,当前还没有添加任何自定义的包

 

2、在上一步的 com.rndemo 这个包下新建一个 rn 文件夹,然后在 rn 目录下新建一个 RnDemoPackage.java

 

3、新建好的这个类需要实现 ReactPackage 接口,该接口会重写两个方法 createNativeModulescreateViewManagers

createNativeModules:用来导入 RN 原生模块

createViewManagers:用来导入 RN 原生组件

 

4、从图中可以看到 createNativeModules 方法返回的是一个原生模块(NativeModule)的集合,因此,这里先新建一个原生模块,取名为 AppModule.java

 

该类需要继承 ReactContextBaseJavaModule,并且重写 getName 方法

 

同时,AppModule 还需要一个构造函数,这里可以同时按住键盘 Alt + Insert,在弹出的窗口中选择 Constructor

 

Choose Super Class Constructor 窗口中提供了 2 个构造函数,这里选择第 2 个带参的构造函数

 

5、假如 AppModule 这个原生模块需要给 JavaScript 暴露一个打开手机相册的方法,这里可以给 AppModule 添加一个 openGallery 方法,并且添加注解 @ReactMethod 用来修饰 JS 调用的原生方法

 

至于方法中使用到的 DeviceUtil 这个工具类是我们提前准备好的,其位置在 rn 同级的 utils 目录下

 

最终原生模块 AppModule 的代码如下

package com.rndemo.rn;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.rndemo.utils.DeviceUtil;

public class AppModule extends ReactContextBaseJavaModule 
    public AppModule(@Nullable ReactApplicationContext reactContext) 
        super(reactContext);
    

    @NonNull
    @Override
    public String getName() 
    // 返回原生模块注册时的名称,也就是说从 react 层的 js 代码中调用 AppModule 这个原生模块,必须先知道这个模块叫什么名称
    // 这里约定 AppModule 原生模块暴露的名字叫 CustomApp,也可以叫其它的
        return "CustomApp";
    

    @ReactMethod
    public void openGallery() 
        // 判空
        if (getCurrentActivity() == null) 
            return;
        
        DeviceUtil.openGallery(getCurrentActivity());
    

 

6、回到上一步新建的 RnDemoPackage 类中,createNativeModules 这个方法返回的是一个原生模块(NativeModule)的集合,这里可以将刚才注册好的 AppModule 注册进来

 

7、最后,回到 MainApplication.java,把 RnDeomoPackage 注册进去

 

◆ JS 层调用原生方法

可以从 NativeModules 中取出注册好的原生模块,调用原生模块的方法

import React from \'react\';
import StyleSheet, View, Button, NativeModules from \'react-native\';

export default () => 
  return (
    <View style=styles.root>
      <Button
        title="桥接原生方法"
        onPress=() => 
          // 从原生模块中取出前面注册好的 AppModule,该模块的名称为 CustomApp
          const CustomApp = NativeModules;
          // 调用原生模块的方法
          CustomApp?.openGallery();
        
      />
    </View>
  );
;

const styles = StyleSheet.create(
  root: 
    width: \'100%\',
    height: \'100%\',
  ,
);

 

上例中,点击按钮就会读取相册,由于谷歌模拟器的效果不是很直观,这里直接展示手机模拟器的效果图

 

原生模块暴露带返回值的方法

上面的示例中,提供了一个没有返回值的 getGallery 方法供 JS 层调用,那如果有返回值的方法该怎么写呢?

这里需要特别注意一点,从 JS 层调用原生层的方法是一个异步的过程,所以,原生层中带返回值的方法不能直接返回,而是要用 Promise 来实现

原生层提供一个返回应用版本名称的方法 getVersionName

 

JS 层读取版本名称

 

重启项目以后,运行效果如下图

 

 

桥接原生常量

 

◆ 编写并注册原生常量方法

在 AppModule 原生组件中重写一个 getConstants 方法

 

◆ JS 层获取原生常量(同步获取)

在 JS 层可以直接读取原生组件的常量,无需异步获取

 

重启项目以后,运行效果如下图

 

reactnative桥接原生原子组件(代码片段)

♦实现一个原生自定义组件View 1、打开AndroidStudio编辑器,在android>app>src>main>java>com.rndemo(项目包名)下新建一个view包 2、在view包下新建一个InfoView类,这个就是要提供给JS层的原生组件 3、这个InfoView类需要继... 查看详情

reactnative学习笔记之调用原生模块(进阶)之callbackpromise使用(代码片段)

前言前文ReactNative学习笔记——调用原生模块(Android)简单说了下ReactNative调用Android原生模块的基本用法,下面讲解下调用原生模块经常会用到的Callback和Promise。很多时候我们可能不仅仅是调用Native的方法,还要... 查看详情

reactnative学习笔记——调用原生模块(android)(代码片段)

以crazyboycode/react-native-splash-screen为例,给一个RN应用添加一个应用启动屏,以掩盖app启动白屏的问题。说明:该模块应用场景是在app启动时,由于RN渲染需要时间,因手机性能的问题可能会导致应用2到3秒的白... 查看详情

原生android集成reactnative(代码片段)

使用ReactNative从零开始开发一款移动应用是一件很惬意的事情,但对于一些已经上线的产品,完全摒弃原有应用的历史沉淀,全面转向ReactNative是不现实的。因此,使用ReactNative去统一原生Android、iOS应用的技术栈,把它作为已有... 查看详情

从其他原生代码访问 React Native 模块

】从其他原生代码访问ReactNative模块【英文标题】:AccessingaReactNativemodulefromothernativecode【发布时间】:2015-12-0718:08:02【问题描述】:我使用nativemodule,它非常适合在ReactNative中的JS代码中获取设备信息。我还想在其他本机(Objectiv... 查看详情

react-native集成到原生项目(代码片段)

文章目录1.ReactNative集成到原生项目中1.1.RN的工作原理1.2.推荐集成方式1.3.集成RN的开发环境1.4.原生与JS通讯交互1.4.1.原生->JS1.4.2.JS->原生1.5.打包ReactNative编译后的bundle文件2.ReactNative模块在第三方项目中集成使用2.1.RN运行的本... 查看详情

React Native:Android 原生模块

】ReactNative:Android原生模块【英文标题】:ReactNative:AndroidNativeModule【发布时间】:2017-12-2917:22:27【问题描述】:我在ReactNative/Android项目上实现了原生模块。在android原生项目中,我使用startActivity函数移动到我手动创建的新活动... 查看详情

reactnative快速上手(代码片段)

工欲善其事,必先利其器。搭建ReactNative开发环境,需要安装以下辅助工具。Node.js:ReactNative需要借助Node.js来创建和运行JavaScript代码。原生开发工具及环境:ReactNative的运行需要依赖原生Android和iOS环境,因此需要分别安装原生An... 查看详情

react-native集成到原生项目(代码片段)

文章目录1.ReactNative集成到原生项目中1.1.RN的工作原理1.2.推荐集成方式1.3.集成RN的开发环境1.4.原生与JS通讯交互1.4.1.原生->JS1.4.2.JS->原生1.5.打包ReactNative编译后的bundle文件2.ReactNative模块在第三方项目中集成使用2.1.RN运行的本... 查看详情

reactnative添加包含原生代码的库需要几个步骤:(代码片段)

...S下载图片功能     连接原生库:https://reactnative.cn/docs/linking-libraries-ios/ 添加包含原生代码的库需要几个步骤:自动链接第一步安装一个带原生依赖的库:$npminstall某个带有原生依赖的库第二步运行以下命令... 查看详情

reactnative在原生项目中集成之坑点总结(代码片段)

...不过的方法就是在现有的项目基础上进行改良,集成ReactNative框架ÿ 查看详情

reactnative入门基础(代码片段)

一、前言ReactNative是Facebook推出的使用React和平台原生功能来构建Android和iOS应用的开源移动跨平台框架;-视图(Views)和移动开发在Android和iOS移动应用中,一个视图是UI的基本组成部分:屏幕上的一个小矩形元素、... 查看详情

[技术博客]reactnative事件监听与原生通信——实现对通知消息的响应(代码片段)

在reactnative中会涉及到很多页面之间的参数传递问题。静态的参数传递通常利用组件的Props属性,在初始化组件时即可从父组件中将参数传递到子组件中。对于非父子关系的组件来说,无法直接传递参数,此时可能会用到react-navig... 查看详情

混合开发架构|android工程集成reactnativeflutterreactjs(代码片段)

混合开发架构|Android工程集成ReactNative、Flutter、ReactJs架构设计说明创建安卓原生工程创建Flutter集成嵌入原生工程创建ReactNative解决RN报错问题集成嵌入原生工程RN集成后,启动报错底部导航栏架构设计原生仿招商银行首页原生... 查看详情

如何编写重用通用 JavaScript 代码的反应原生“本机模块”(桥)?

...-0115:52:07【问题描述】:原生模块如何回调到JavaScript内部桥接方法,然后在内部方法中进行处理,例如将数据解析为JSON,然后引发react 查看详情

(架构)reactnative导出项目全局共用组件的模块(代码片段)

自定义组件全局使用(类似如下)importReactNavComponent,Widget,Utilfrom‘rn-yunxi‘;constRegexpUtil,StorageUtil=Util;constButton,Text=Widget;首先在项目中文件下新建rn-yunxi文件夹,然后再package.json文件中导入“rn-yunxi”:&ldquo 查看详情

reactnative动画总结(代码片段)

  最近在使用reactnative进行App混合开发,相对于H5的开发,RN所提供的样式表较少,RN中不能使用类似于css3中的动画,因此,RN提供了Animated的API  1.写一个最简单的动画  importReact,Componentfrom‘react‘importAnimated,Text,Viewfrom‘re... 查看详情

如何在 React Native 0.60+ 中添加原生模块?

】如何在ReactNative0.60+中添加原生模块?【英文标题】:HowtoaddnativemodulesinReactNative0.60+?【发布时间】:2019-09-2020:11:17【问题描述】:我试图了解ReactNative0.60+中存在的自动链接与我们在之前的ReactNative版本中的自动/手动链接之间的... 查看详情