采用aar方式将react-native集成到已有安卓APP

news2024/9/21 14:34:02

关于react-native和android的开发环境搭建、环境变量配置等可以查看官方文档。
官方文档地址
文章中涉及的node、react等版本:

node:v16.18.1
react:^18.1.0
react-native:^0.70.6
gradle:gradle-7.2

开发工具:VSCode和android studio
关于react-native和安卓的混合开发,官方文档已经提供了一种方式,按照文档一步一步操作还是比较容易实现的,但是官方文档方式,对已经存在的原生APP来说,不太友好,需要改动大,代码混在一起,不利于代码管理,项目耦合性高,所以决定采用aar的方式试一下react-native和安卓的混合开发。
创建项目目录文件夹
选择合适的盘符新建reactnativetest文件夹,然后使用vscode打开该文件夹。
在这里插入图片描述

安装JavaScript依赖包
在vscode打开的项目根目录下通过运行npm init创建一个名为package.json的文件夹文件。
在这里插入图片描述
在这里插入图片描述
安装react和react-native依赖

npm install react@^18.1.0
npm install react-native@^0.70.6

通过执行上面两个命令,在reactnativetest下面就会出现node_modules文件夹。
在这里插入图片描述
创建安卓原生项目文件夹android
在reactnativetest文件夹中创建android子文件夹,使用android studio在android文件夹下创建原生项目。
在这里插入图片描述
原生安卓项目依赖react-native aar和依赖库
到这一步,官方文档采用的是直接本地依赖,这里采用的aar的方式依赖,需要找到react-native的aar包,
C:\androidp\reactnativetest\node_modules\react-native\android\com\facebook\react\react-native\0.70.6
在node_modules文件夹中找到如下文件:
在这里插入图片描述
.aar就是react-native对应版本的aar库,.pom就是react-native对应版本的依赖库
C:\androidp\reactnativetest\node_modules\jsc-android\dist\org\webkit\android-jsc\r250230
在node-modules文件夹下找到如下:
在这里插入图片描述
在原生android项目中添加一个android module
在这里插入图片描述
将找到的react-native的aar包拷贝到mylibrary中libs下
在这里插入图片描述
接着将.pom文件中的依赖转换,找到该文件中的dependencies节点
在这里插入图片描述
对每一个dependency节点进行转换

	implementation 'androidx.appcompat:appcompat-resources:1.4.1'
    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'androidx.autofill:autofill:1.1.0'
    implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
    implementation 'com.facebook.fbjni:fbjni-java-only:0.2.2'
    implementation 'com.facebook.fresco:fresco:2.5.0'
    implementation 'com.facebook.fresco:imagepipeline-okhttp3:2.5.0'
    implementation 'com.facebook.fresco:ui-common:2.5.0'
    implementation 'com.facebook.infer.annotation:infer-annotation:0.18.0'
    implementation 'com.facebook.soloader:soloader:0.10.4'
    implementation 'com.facebook.yoga:proguard-annotations:1.19.0'
    implementation 'com.google.code.findbugs:jsr305:3.0.2'
    implementation 'com.squareup.okhttp3:okhttp-urlconnection:4.9.2'
    implementation 'com.squareup.okhttp3:okhttp:4.9.2'
    implementation 'com.squareup.okio:okio:2.9.0'
    implementation 'javax.inject:javax.inject:1'

将这些依赖和aar一起添加到mylibrary中的build.gradle文件中
在这里插入图片描述
在reactnativetest文件夹下创建index.js入口文件
在这里插入图片描述

import React from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';

class HelloWorld extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.hello}>我是react-native页面的</Text>
      </View>
    );
  }
}
var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center'
  },
  hello: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10
  }
});

AppRegistry.registerComponent(
  'MyReactNativeApp',
  () => HelloWorld
);

这里的index.js只是测试文件,具体根据实际需求编写。
将react-native中js代码打包成.bundle文件

npx react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/com/your-company-name/app-package-name/src/main/assets/index.android.bundle --assets-dest android/com/your-company-name/app-package-name/src/main/res/

android/com/your-company-name/app-package-name/src/main/assets/index.android.bundle
android/com/your-company-name/app-package-name/src/main/res/
上面两个输出目录和文件名称可以替换成实际需要的。
在android app module中新增assets文件夹,然后执行上面的命令。
在这里插入图片描述
接着将生成.bundle文件拷贝到mylibrary module中。
在这里插入图片描述
在原生项目中添加程序react-native页面的逻辑

public class MyReactNativeActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
    private ReactRootView mReactRootView;
    private ReactInstanceManager mReactInstanceManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SoLoader.init(this, false);

        mReactRootView = new ReactRootView(this);
        List<ReactPackage> packages = new PackageList(getApplication()).getPackages();
        // 有一些第三方可能不能自动链接,对于这些包我们可以用下面的方式手动添加进来:
//        packages.add(new SvgPackage());
        // 同时需要手动把他们添加到`settings.gradle`和 `app/build.gradle`配置文件中。


        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setCurrentActivity(this)
                .setBundleAssetName("index.android.bundle")
                .setJSMainModulePath("index")
                .addPackages(packages)
//                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
        // 注意这里的MyReactNativeApp 必须对应"index.js"中的
        // "AppRegistry.registerComponent()"的第一个参数
        mReactRootView.startReactApplication(mReactInstanceManager, "MyReactNativeApp", null);

        setContentView(mReactRootView);
    }
    @Override
    protected void onPause() {
        super.onPause();
        // 把一些 activity 的生命周期回调传递给ReactInstanceManager
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostPause(this);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 把一些 activity 的生命周期回调传递给ReactInstanceManager
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostResume(this, this);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 把一些 activity 的生命周期回调传递给ReactInstanceManager
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostDestroy(this);
        }
        if (mReactRootView != null) {
            mReactRootView.unmountReactApplication();
        }
    }

    @Override
    public void onBackPressed() {
        // 后退按钮事件传递给 React Native
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onBackPressed();
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
            mReactInstanceManager.showDevOptionsDialog();
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        // 最后,必须重写 onActivityResult() 方法(如下面的代码所示)以处理权限 Accepted 或 Denied 情况以实现一致的 UX。
        // 此外,为了集成使用 startActivityForResult 的 Native Modules,我们需要将结果传递给我们的 ReactInstanceManager
        mReactInstanceManager.onActivityResult(this, requestCode, resultCode, data);
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);
        startActivity(new Intent(this, MyReactNativeActivity.class));
        finish();
    }
}

在这里插入图片描述
这样就将一个简单的react-native加载到原生里面来展示了,所有的react-native aar包和依赖库都是放在mylibrary中的,可以将mylibrary打包成aar,拷贝到需要的项目中使用。这个是比较简单的demo集成,没有涉及到react-native第三库的使用,特别是react-native和安卓的混合第三方库。
react-native和安卓的混合第三方库使用
纯js的react-native不需要怎么处理,会被打包到.bundle文件中的,混合库会有些不太一样,这里简单使用一下react-native-svg这个混合库。

npm install react-native-svg//安装依赖库

在这里插入图片描述
在这里插入图片描述
会发现react-native-svg混合部分就是一个android module,如果是采用官方文档的依赖,启动原生模块的自动链接,会自动在android 原生中生产对应的svg module的。
启用原生模块的自动链接
要使用自动链接的功能,我们必须将其应用于几个地方。首先,将以下内容添加到settings.gradle:

apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)

接下来,在app/build.gradle的最底部添加以下内容:

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

不过很遗憾的是,采用aar的方式,这些依赖都没有,谈何的启动原生模块的自动链接呢。
既然react-native-svg库的混合部分是一个android module,那将它打包成aar进行依赖是可行的,所以将react-native-svg库的混合部分打包aar。
在这里插入图片描述
import进来后,构建发现报错,屏蔽掉repositories,具体报错具体分析。需要将dependencies中的react-native替换成aar方式依赖。这套干脆新增一个module,就专门用于依赖react-native的aar包和库,然后其他module依赖该module。
在这里插入图片描述
其他module的依赖变成如下:
在这里插入图片描述
在这里插入图片描述
开始对react-native-svg打包aar
在这里插入图片描述
打包好后,将react-native-svg的aar拷贝到mylibrary中进行依赖。
在这里插入图片描述
在这里插入图片描述
react-native-svg简易demo的js文件

import React from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';
import Svg, { Circle } from 'react-native-svg';
class HelloWorld extends React.Component {
  render() {
    return (
        <View style={styles.container}>
        <Svg height="50%" width="50%" viewBox="0 0 100 100" >
          <Circle cx="50" cy="50" r="50" stroke="purple" strokeWidth=".5" fill="violet" />
        </Svg>
      </View>
    );
  }
}
const styles = StyleSheet.create({
    container: {
      flex: 1,
      backgroundColor: '#fff',
      alignItems: 'center',
      justifyContent: 'center',
    },
  });

AppRegistry.registerComponent(
  'MyReactNativeApp',
  () => HelloWorld
);

重新打包生产.bundle文件。运行app,会看到如下错误:
在这里插入图片描述
在加载react-native的代码出添加SvgPackage实例对象
在这里插入图片描述
重新运行就看到效果了:
在这里插入图片描述
将mylibrary module打包成aar文件输出
可以将react-native和原生混合开发的逻辑都封装在mylibrary,然后根据实际需要将mylibrary打包成aar输出,可以解耦,同时大大提升开发效率等。
在这里插入图片描述
执行后看到报错了:
在这里插入图片描述
这个错误网上有不少对应的解决方案:
aar打包错误解决方案
大致就是将aar包放到独立的moudle,然后依赖module,再打包输出。那就将react-native-svg的aar包放到arrlib中,然后mylibrary依赖arrlib。
在这里插入图片描述
这样aar打包输出成功了。
demo链接:https://pan.baidu.com/s/1nlBDqF__LdpCcbtMUMKYGA
提取码:nps1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/359649.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

即拼商城系统之七人拼团会员模式

即拼商城系统之七人拼团会员模式&#xff0c;在商城选购399商品可加入会员体系&#xff0c;参加7人拼团盈利。购买产品或礼包成为团长&#xff0c;铺满剩余6个位置拼团成功。满团后即可用赚来的钱去复购礼包再次开团&#xff0c;继续盈利。 ◇◆商城系统团长获得礼包提成&#…

【matplotlib】可视化解决方案——如何向图表中添加数据表

概述 虽然 matplotlib 主要用途是绘图&#xff0c;但是他还是可以在绘图时帮助我们做一些其他事务&#xff0c;比如在图表旁边放置一个整齐的数据表格。我们必须明白为数据绘制可视化图形主主要是是为了解释那些不能理解的数据。将一些来自数据整体集合的总结性或者突出强调的…

大地量子全面使用亚马逊云科技提供的多样化云服务

近年来&#xff0c;我国光伏和风电并网装机容量持续增长&#xff0c;截至2021年底&#xff0c;全国可再生能源装机规模突破10亿千瓦&#xff0c;占总发电装机容量的44.8%。其中&#xff0c;风电装机3.28亿千瓦、光伏发电装机3.06亿千瓦。风光电总装机和新增装机规模多年来位居全…

PCB设计中降低噪声与电磁干扰的24个窍门

电子设备的灵敏度越来越高&#xff0c;这要求设备的抗干扰能力也越来越强&#xff0c;因此PCB设计也变得更加困难&#xff0c;如何提高PCB的抗干扰能力成为众多工程师们关注的重点问题之一。本文将介绍PCB设计中降低噪声与电磁干扰的一些小窍门。 下面是经过多年设计总结出来的…

MyBaits

MyBaitsMyBaits的jar包介绍MyBaits的入门案例创建实体java日志处理框架常用的日志处理框架Log4j的日志级别Mybatis配置的完善Mybatis的日志管理使用别名alias方式一方式二SqlSession对象下的常用API查询操作Mapper动态代理Mapper 动态代理规范查询所有用户根据用户ID查询用户Ma…

MMPBSA计算--基于李继存老师gmx_mmpbsa脚本

MMPBSA计算–基于李继存老师gmx_mmpbsa脚本 前期准备 软件安装 安装gromacs, 可以查阅 我的blogGromacs-2022 GPU-CUDA加速版 unbantu 安装 apbs, sudo apt install apbs 安装 gawk, sudo apt install gawk MD模拟好的文件 我们以研究蛋白小分子动态相互作用-III(蛋白配体…

钓鱼网站+bypassuac提权

本实验实现1 &#xff1a;要生成一个钓鱼网址链接&#xff0c;诱导用户点击&#xff0c;实验过程是让win7去点击这个钓鱼网站链接&#xff0c;则会自动打开一个文件共享服务器的文件夹&#xff0c;在这个文件夹里面会有两个文件&#xff0c;当用户分别点击执行后&#xff0c;则…

【面试题】vue中的插槽是什么?

大厂面试题分享 面试题库后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★地址&#xff1a;前端面试题库一、slot是什么在HTML中 slot 元素 &#xff0c;作为 Web Components 技术套件的一部分&#xff0c;是Web组件内的一个占位符该占位符可以在后期…

Docker----------day3

常规安装大体步骤 1.安装tomcat 1.查找tomcat docker search tomcat2.拉取tomcat docker pull tomcat3.docker images查看是否有拉取到的tomcat 4.使用tomcat镜像创建容器实例(也叫运行镜像) docker run -it -p 8080:8080 tomcat5.新版tomcat把webapps.dist目录换成webapp…

100种思维模型之九屏幕分析思维模型-016

一、认识九屏幕分析思维模型 1.九屏幕分析思维模型定义 九屏幕法是TRIZ理论中的创新思维方法五大方法之一。它是把问题当成一个系统来研究&#xff0c; 关注系统的整体性、 层级性、目的性&#xff0c;即各要素之间的结构。 九屏幕法是按照时间和系统层次两个维度进行思考。 包…

MAC中docker搭建fastdfs

1:首先搭建Docker2:通过Docker搭建fastdfs&#xff08;1&#xff09;查找镜像打开终端通命令查找fastdfs的镜像docker search fastdfs&#xff08;二&#xff09;拉取镜像在找到合适的镜像后执行命令:docker pull delron/fastdfs&#xff08;三&#xff09; 创建storage和track…

软件设计(十四)-UML建模(上)

软件设计&#xff08;十三&#xff09;-原码、反码、补码、移码https://blog.csdn.net/ke1ying/article/details/129115844?spm1001.2014.3001.5501 UML建模包含&#xff1a;用例图&#xff0c;类图与对象图&#xff0c;顺序图&#xff0c;活动图&#xff0c;状态图&#xff…

论文复现:模拟风电不确定性——拉丁超立方抽样生成及缩减场景(Matlab)

风电出力的不确定性主要源于预测误差&#xff0c;而研究表明预测误差&#xff08;e&#xff09;服从正态分布且大概为预测出力的10%。本代码采用拉丁超立方抽样实现场景生成[1,2]、基于概率距离的快速前代消除法实现场景缩减[3]&#xff0c;以此模拟了风电出力的不确定性。 1 …

26岁曾月薪15K,现已失业3个月,我依然没有拿到offer......

我做测试5年&#xff0c;一线城市薪水拿到15K&#xff0c;中间还修了一个专升本&#xff0c;这个年限不说资深肯定也是配得上经验丰富的。今年行情不好人尽皆知&#xff0c;但我还是对我的薪水不是很满意&#xff0c;于是打算出去面试&#xff0c;希望可以搏一个高薪。 但真到面…

无聊小知识01.serialVersionUID的作用

什么是serialVersionUIDJava&#xff08;TM&#xff09;对象序列化规范中描述到&#xff1a;serialVersionUID用作Serializable类中的版本控件。如果您没有显式声明serialVersionUID&#xff0c;JVM将根据您的Serializable类的各个方面自动为您执行此操作。(http://docs.oracle…

神经网络的基本骨架—nn.Module使用

一、pytorch官网中torch.nn的相关简介可以看到torch.nn中有许多模块&#xff1a;二、Containers模块1、MODULE&#xff08;CLASS : torch.nn.Module&#xff09;import torch.nn as nn import torch.nn.functional as Fclass Model(nn.Module):#nn.Module---所有神经网络模块的…

Find Any File for Mac,本地文件搜索工具

Find Any File for Mac是一款简单好用的本地文件搜索工具&#xff0c;可以让你在本地磁盘上搜索、查找任何文件&#xff0c;包括本地磁盘的名称、 创建或修改日期、 大小或类型和创建者代码等。更好的结果&#xff1a;它为找到的项目提供了另一种分层视图。您可以使用cmd 2切换…

Kafka 安装入门实战

1.下载Kafka 有2个下载网站都可以&#xff1a; https://www.apache.org/dyn/closer.cgi?path/kafka/3.4.0/kafka_2.13-3.4.0.tgz https://kafka.apache.org/downloads 下载完后解压缩&#xff1a; [roottest ~]# tar -xzf kafka-3.4.0-src.tgz [roottest ~]# cd kafka_2.12-…

C# String与StringBuilder 的区分

重点 1)它是比较的栈里面的值是否相等(值比较) 2)Equals它比较的是堆里面的值是否相等(引用地址值比较) 3)Object.ReferenceEquals(obj1,obj2)它是比较的是内存地址是否相等 问题描述&#xff1a; 今日提交代码时候&#xff0c;被检测工具发出修改建议。遂补充一下知识 1.什么…

【科研】一目了然单目深度估计实验评价指标

1.度量指标表概览&#xff08;自整待完善&#xff09; SI Scale-Invariant loss尺度不变损失YES像素深度损失bi-directional chamfer loss双向槽损失YESBin中心稠密损失L1 loss & LAD & LAEL1范数损失函数 把目标值与估计值的绝对差值的总和最小化 RMSE Root Mean …