RN开发搬砖经验之—React Native(RN)应用转原生化-Android 平台

ops/2024/11/19 12:09:40/

在过去的一年中,我的主要工作聚焦于将一个基于React Native(RN)框架开发的Android应用逐步转化为原生应用。我们采取了分阶段实施的策略,首先着手将应用中的二级和三级页面的核心功能以原生代码的形式进行重构。在这一过程中,我们通过在React Native页面中拉起原生Activity来实现这一目标,采用的是多Activity的应用架构。具体而言,每一个经过改造的功能模块在用户界面(UI)层面都对应一个独立的Activity。需要注意的是,这一原生化过程仅支持Android平台,因此未涉及iOS平台的相关处理。
通过将关键功能模块以原生代码的形式实现,我们旨在提升应用的性能和用户体验。这种方法不仅确保了应用在不同设备上的兼容性,而且能够充分利用原生平台的最新特性和优化,使得应用运行更为流畅。此外,原生化过程还有助于开发者更精确地控制应用资源的使用,减少不必要的电量消耗和内存占用,从而延长设备的使用寿命。
在这里插入图片描述

经过一段时间的精心改造,我们已经基本实现了应用核心功能模式的原生化。接下来的步骤是将应用中的MainActivity/RNActivity替换为新的原生Activity实例(NewMainActivity)。这一过程相对简单,只需为NewMainActivity配置启动时的Launcher intent-filter即可。随后,我们可以移除与React Native(RN)相关的代码,包括业务代码和RN框架代码。
尽管如此,我们仍然希望能够复用React Native的某些功能或页面,因此需要在原生Activity中启动RNActivity,并能够指定显示的React Native页面(即进行路由控制)。
为此,我们需要解决两个技术问题:首先,如何在启动RNActivity时传递参数,确保这些参数能够传递至React Native中的js根组件;其次,如何在React Native应用页面中动态配置路由,以便打开特定页面。

在React Native应用开发中,通常情况下,RNActivity会负责加载JavaScript代码。这些JavaScript代码的入口文件通常被命名为index.js。在index.js文件中,开发者会注册整个React Native应用的主组件或根组件。这个根组件通常会通过单独的文件来定义,而这个单独的文件一般被命名为app.js。
在app.js文件中,开发者会定义一个根组件,这个根组件在整个应用中起着至关重要的作用。它不仅承载了应用的初始界面,还负责管理整个应用的导航流程。为了实现页面之间的跳转和导航管理,开发者通常会在根组件中使用navigation组件。通过这个navigation组件,开发者可以方便地控制页面之间的跳转逻辑,从而实现一个流畅且用户友好的导航体验。
在这里插入图片描述
如上图所示,我们可以看到,首先遇到的第一个技术问题相对来说比较简单。这个问题涉及到两个Activity之间的参数传递。具体来说,当我们在一个Activity中需要启动另一个Activity时,可以通过Intent对象来传递所需的参数。在调用startActivity方法时,我们只需要在Intent对象中添加需要传递的参数,然后将这个Intent对象传递给startActivity方法即可。这种方式在Android开发中非常常见,也是实现Activity间通信的一种基本方法。
然而,第二个技术问题相对来说就比较复杂了。这个问题涉及到如何将RNActivity中的参数传递到根组件app中。app组件获取到相关的参数后,怎么配置路由指定显示的页面,由显示页面时还要传参数给页面。我们就一步一步来实现。
在这里,我们不再深入探讨在初始化React Native Activity时如何设置参数,因为该过程相对直接。我们假定已经传递了两个参数:一个名为pageName的数据和一个名为userId的参数。随后,我们需在React Native Activity的onCreate方法中处理这两个参数。同时,在getLaunchOptions方法中,我们应将这些参数纳入initialProperties中。应用程序的props将使我们能够访问initialProperties中设定的参数。因此,我们可以在应用程序的其他部分利用这些参数,以便根据传递的参数执行相应的操作和处理。我们通过设置Stack.Navigator的initialRouteName属性来指定打开/导航至特定页面,同时利用Stack.Screen的initialParams属性来传递打开页面时所需的参数,具体代码示例如下:

1、需要在React Native的Android原生桥接代码中处理从NewMainActivity传递过来的参数,并将它们放入ReactActivityDelegate的getLaunchOptions中。以下是如何实现这一点的步骤:

import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;public class MyReactActivityDelegate extends ReactActivityDelegate {private String pageName;private String userId;public MyReactActivityDelegate(ReactActivity activity, String mainComponentName) {super(activity, mainComponentName);}// 这个方法用于设置启动参数public void setLaunchOptions(String pageName, String userId) {this.pageName = pageName;this.userId = userId;}@Overrideprotected WritableMap getLaunchOptions() {WritableMap launchOptions = Arguments.createMap();if (userId != null) {launchOptions.putString("userId", userId);}if (pageName != null) {launchOptions.putString("pageName", pageName);}return launchOptions;}
}

2、然后,在你的RNActivity中,你需要使用MyReactActivityDelegate来启动React应用。

import com.facebook.react.ReactActivity;public class RNActivity extends ReactActivity {@Overrideprotected String getMainComponentName() {return "myApp"; // 这里应该是你的主组件名}@Overrideprotected ReactActivityDelegate createReactActivityDelegate() {// 创建自定义的ReactActivityDelegate实例MyReactActivityDelegate delegate = new MyReactActivityDelegate(this, getMainComponentName());// 从Intent中获取参数String pageName = getIntent().getStringExtra("pageName");String userId = getIntent().getStringExtra("userId");// 设置启动参数delegate.setLaunchOptions(pageName, userId);return delegate;}
}

3、在React Native代码中,你可以在App.js中接收这些参数,并根据参数来设置路由。

import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import React from 'react';const Stack = createNativeStackNavigator();function App({ userId, pageName }) {// 使用解构赋值从props中获取userId和pageNamereturn (<NavigationContainer><Stack.Navigator initialRouteName={pageName}><Stack.Screenname="Home"component={HomePage}initialParams={{ userId }}/>{/* 其他页面路由配置 */}</Stack.Navigator></NavigationContainer>);
}export default App;

参考文档

  • 从原生组件传递属性到 React Native

http://www.ppmy.cn/ops/134964.html

相关文章

鸿蒙next版开发:相机开发-元数据(ArkTS)

在HarmonyOS 5.0中&#xff0c;ArkTS提供了对相机元数据的访问能力&#xff0c;这对于开发者在相机应用中获取图像的详细信息非常有用。元数据&#xff08;Metadata&#xff09;是对相机返回的图像信息数据的描述和上下文&#xff0c;比如照片或视频中识别人像的取景框坐标等信…

Spring Boot汽车资讯:科技与速度的新纪元

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了汽车资讯网站的开发全过程。通过分析汽车资讯网站管理的不足&#xff0c;创建了一个计算机管理汽车资讯网站的方案。文章介绍了汽车资讯网站的系统分析部分&…

缓存及其不一致

在实际开发过程中&#xff0c;一般都会遇到缓存&#xff0c;像本地缓存&#xff08;直接在程序里搞个map也可以&#xff0c;但是可能会随着数据的增长出现OOM&#xff0c;建议使用正经的本地缓存框架&#xff0c;因为自己实现淘汰策略啥的挺费劲的&#xff09;、分布式缓存&…

Acwing342

这个代码实现了一种结合 连通块分解、拓扑排序 和 Dijkstra 算法 的复杂图的最短路径计算方法&#xff0c;适用于含有两类边的图结构&#xff1a;普通边&#xff08;在连通块内&#xff09;和特殊边&#xff08;跨连通块&#xff09;。 以下是详细的代码讲解&#xff0c;逐步解…

排序算法——快速排序

目录 一、快速排序的原理 二、快速排序的过程 三、代码的实现 四、代码的优化 总结 一、快速排序的原理 快速排序的思想是分治法&#xff0c;将一个大问题分割成几个小问题解决&#xff0c;首先选择一个数作为分水岭&#xff0c;然后让比该数大的都在它的右边&#xff0c…

【数据结构初阶】栈和队列的建立

栈 概念和结构 栈是一种特殊的线性表&#xff0c;它只允许一端进行插入和删除数据操作&#xff0c;这一端被称为栈顶&#xff0c;则另一端被称为栈底&#xff0c;而栈内的数据遵循后进后出&#xff0c;先进后出的原则 入栈&#xff1a;栈的插入操作被称为进栈、入栈、压栈&a…

blockchain实现遇到的问题

区块链分叉 v1114 : 基于python socket 创建TCP server&#xff0c;以中心化的形式暂时实现区块链的状态同步 C:\Users\vin0sen>nc 192.168.137.1 9000 Enter a new data: 111 {"index": 1, "timestamp": "2024-11-14 15:28:53.173112", &quo…

Shell脚本4 -- 数学运算

声明&#xff1a; 本文的学习内容来源于B站up主“泷羽sec”视频【shell &#xff08;3&#xff09;脚本参数传递与数学运算】的公开分享&#xff0c;所有内容仅限于网络安全技术的交流学习&#xff0c;不涉及任何侵犯版权或其他侵权意图。如有任何侵权问题&#xff0c;请联系本…