React-Native开发鸿蒙NEXT-本地与沙盒加载bundle
React-Native开发鸿蒙NEXT-本地与沙盒加载bundle
来晚了来晚了,不是想偷懒,实在是一个图片问题没搞定导致效果出不来,今天刚靠工具查出了原因。
RN的加载无非本地加载与沙盒加载两种方式。之所以用RN开发,想节省一点原生的开发人力是一方面,另一方面肯定绕不过希望借助bundle天生的可下载优势,来搞个远程更新。通过下载bundle到沙盒环境再加载,达到近似于热更新的效果。对于加载了n个bundle的应用来说这点尤为重要,毕竟不能因为某个bundle的更新就让用户去频繁更新app。
应用之前的加载方式是本地加载,bundle和图片资源都放在了代码的资源文件下。先来看看如何通过沙盒加载。artTS中,加载沙盒bundle和加载本地bundle可以分别调用不同api来实现。
沙盒,利用FileJSBundleProvider加载
provider = new FileJSBundleProvider(bundle.bundlePath);
本地,利用ResourceJSBundleProvider加载
provider = new ResourceJSBundleProvider(rnohCoreContext.uiAbilityContext.resourceManager, bundle.bundlePath);
下一步来看看如何把资源从远程服务器下载到沙盒。在RN中,可以使用react-native-fs+eact-native-zip-archive来实现下载与解压缩。两个依赖的安装可以参考官方文档简单给个示例,只是展示下载与解压缩,实际应用还得考虑断点续传等细节。
// 下载并解压缩
const download = async (downloadUrl = '远程下载地址.zip', unzipPath = '') =>{
try {
// 下载
const zipPath = `${RNFS.DocumentDirectoryPath}/harmony.zip`;
console.log('zipPath' + zipPath);
const downloadResult = await RNFS.downloadFile({
fromUrl: downloadUrl,
toFile: zipPath,
progress: (res) => {
console.log(`下载进度: ${Math.floor((res.bytesWritten / res.contentLength) * 100)}%`);
}
}).promise;
if (downloadResult.statusCode !== 200) {
console.log('下载失败');
throw new Error('下载失败');
}
// 解压缩
const targetDir = `${RNFS.DocumentDirectoryPath}/metro`;
await unzip(zipPath, targetDir);
console.log('解压完成,路径:', targetDir);
return targetDir;
} catch (error) {
console.error('流程失败:', error.message);
return null;
}
}
加载的bundle,是一个简单的demo页面,仅仅把demo的header组件改成了一张自定义的图片。
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
*/
import React, {useEffect} from 'react';
import type {PropsWithChildren} from 'react';
import SplashScreen from 'react-native-splash-screen';
import versionUtil from './versionUtil';
import {
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
Image,
} from 'react-native';
import {
Colors,
DebugInstructions,
Header,
LearnMoreLinks,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {createStackNavigator} from '@react-navigation/stack';
const Tab = createBottomTabNavigator();
type SectionProps = PropsWithChildren<{
title: string;
}>;
function Section({children, title}: SectionProps): JSX.Element {
const isDarkMode = useColorScheme() === 'dark';
/**
* 模拟componentDidMount,即只运行一次该函数
*/
useEffect(() => {
SplashScreen.hide();
versionUtil
.download()
.then(result => {
console.log('下载成功,路径:', result);
})
.catch(error => {});
return () => {};
}, []);
return (
<View style={styles.sectionContainer}>
<Text
style={[
styles.sectionTitle,
{
color: isDarkMode ? Colors.white : Colors.black,
},
]}>
{title}
</Text>
<Text
style={[
styles.sectionDescription,
{
color: isDarkMode ? Colors.light : Colors.dark,
},
]}>
{children}
</Text>
</View>
);
}
function App(): JSX.Element {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
backgroundColor={backgroundStyle.backgroundColor}
/>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}>
{/* <Header /> */}
{/* 换成一张自定义图片 */}
<Image style={{width: '100%', height: 200}} source={require('./assets/banner.png')}/>
<View
style={{
backgroundColor: isDarkMode ? Colors.black : Colors.white,
}}>
<Section title="Step One">
Edit <Text style={styles.highlight}>App.tsx</Text> to change this
screen and then come back to see your edits.
</Section>
<Section title="See Your Changes">
<ReloadInstructions />
</Section>
<Section title="Debug">
<DebugInstructions />
</Section>
<Section title="Learn More">
Read the docs to discover what to do next:
</Section>
<LearnMoreLinks />
</View>
</ScrollView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
},
highlight: {
fontWeight: '700',
},
});
export default App;
打包后的文件结构,可以看到图片已经被打包到了资源文件中
assets与bundle文件压缩,得到压缩文件。手动拖到服务器上,让RN完成下载放入手机的沙盒。利用DevEco-Studio的Device File Browser功能,可以很方便地查看应用沙盒中的文件。可以看到此时文件已经正常下载并解压缩了,文件夹结构也和压缩前一样。
重新启动应用,添加一旦判断沙盒文件是否存在的逻辑让它走沙盒加载,结果不出所料,页面加载出来了但图片是空的。
不显示自然是路径不对,在rnohCoreContext.createAndRegisterRNInstance的属性assetsDest里调整了半天也没猜对,一时间有些没头绪。
网上查了下发现发现还可以在DevEco的ArkUI Inspector里直接查看页面,哪怕是RN的页面?!那就直接看起来。一看什么鬼?怎么路径和打包的不一样啊?丢了一层assets?
对比下打包的文件夹结构
先直接利用Device File Browser,向外层的assets文件夹下拖了一个图片进去。
直接可以显示了。
为什么打包的资源路径和最终加载的路径会出现不一致?目前还没查明。
趁热打铁看看如果本地加载bundle,它读取的资源最终是在哪个路径?
有点惊讶这个诡异的路径了,本地加载的时候又是两层assets文件夹了。。。。。。
原因可以后面去排查,已经知道了是路径问题,也知道了实际的路径,这些已经可以继续推进下去了。更重要的是知道了如何查看沙盒文件与查看运行时UI页面,比起之前纯纯的一边ai一边猜,效率提高了不止一点半点。
到头来,还得靠工具。
总算是解决了这个React-Native开发鸿蒙NEXT系列自打出生就困扰的一个大问题。看似不大的问题,却有轻舟已过万重山的感觉。
在三月的最后一天,终于小小地开心了一下。
不经常在线,有问题可在微信公众号或者掘金社区私信留言
更多内容可关注
我的公众号悬空八只脚
作者:悬空八只脚
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
React-Native开发鸿蒙NEXT-本地与沙盒加载bundle的更多相关文章
- react native中的欢迎页(解决首加载白屏)
参照网页: http://blog.csdn.net/fengyuzhengfan/article/details/52712829 首先是在原生中写一些方法,然后通过react native中js去 ...
- React Native 之FlatList 下拉刷新和上拉加载更多
接上一篇代码: 只修改了FlatListDemo.js里面的代码 import React, {Fragment,Component} from 'react'; import { SafeAreaV ...
- iOS程序员的React Native开发工具集
本文整理了React Native iOS开发过程中有用的工具.服务.测试.库以及网站等. 工具 你可以选择不同的开发环境:DECO.EXPO或者你可以使用Nuclide+Atom,目前我使用EXPO ...
- React Native开发 - 搭建React Native开发环境
移动开发以前一般都是原生的语言来开发,Android开发是用Java语言,IOS的开发是Object-C或者Swift.那么对于开发一个App,至少需要两套代码.两个团队.对于公司来说,成本还是有的. ...
- React Native开发入门
目录: 一.前言 二.什么是React Native 三.开发环境搭建 四.预备知识 五.最简单的React Native小程序 六.总结 七.参考资料 一.前言 虽然只是简单的了解了一下Reac ...
- React Native开发技术周报2
(1).资讯 1.React Native 0.22_rc版本发布 添加了热自动重载功能 (2).技术文章 1.用 React Native 设计的第一个 iOS 应用 我们想为用户设计一款移动端的应 ...
- React Native开发技术周报1
(一).资讯 1.React Native 0.21版本发布,最新版本功能特点,修复的Bug可以看一下已翻译 重要:如果升级 Android 项目到这个版本一定要读! 我们简化了 Android 应用 ...
- DECO 一个REACT NAtive 开发IDE工具
DECO 一个REACT NAtive 开发IDE工具. 目前只支持 OS,NO WINDOWS https://www.decosoftware.com/ 一个方便的快速 ERXPRESS 教程:h ...
- React Native 开发之 (02) 用Sublime 3作为React Native的开发IDE
Sublime Text是一个代码编辑器.也是HTML和散文先进的文本编辑器.漂亮的用户界面和非凡的功能,例如:迷你地图,多选择Python插件,代码段等等.完全可自定义键绑定,菜单和工具栏等等.漂亮 ...
- React Native 开发笔记
ReactNativeDemo 学习ReactNative开发,搭建ReactNative第一个项目 React Native 开发笔记 1.安装Homebrew $ /usr/bin/ruby -e ...
随机推荐
- 基于RAG的MaxKB知识库问答系统如何选择向量模型
在MaxKB中替换向量模型前,我们需要先了解向量相关的原理和技术,此处不做赘述,大家可以自行学习.可以了解下Embedding.Embedding核心,向量库等内容. 一.MaxKB 默认向量模型 M ...
- DeepSeek 全套资料pdf合集免费下载(持续更新)
有很多朋友都关注DeepSeek相关使用的教程资料,本站也一直持续分享DeepSeek 学习相关的pdf资料,由于比较零散,这篇文章主要就是做一个汇总,并且持续更新,让大家可以及时获取下载最新的相关D ...
- Gits-命令
Git基础命令 Git是一个分布式版本控制系统,由Linus Torvalds创建,用于有效.高速地处理从小到大的项目版本管理.以下是一些基本的Git命令和概念,它们对于使用Git进行版本控制至关重要 ...
- .NET周刊【3月第1期 2025-03-02】
国内文章 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章 https://www.cnblogs.com/shanyou/p/18737657 2025年2月25日,.NET ...
- 前端解析excel表格实现
1. 背景:在做react项目时,遇到一个解析excel的需求变更,把从原来后端解析变更为前端解析. 1.1 由于后端解析excel文件有安全隐患,因为项目中后端不允许上传文件,当然后端解析对前端来说 ...
- k8s v1.19版本之后,自签证书过期x509: certificate has expired or is not yet valid
前言 在 Kubernetes 1.16 版本之前,kubeadm 工具的 alpha certs 子命令用于生成和管理 Kubernetes 集群的证书.然而,从 Kubernetes 1.19 版 ...
- 密码编码学与网络安全 原理与实践(第七版)William Stallings---读书笔记(1.1-1.5)
密码编码学与网络安全 原理与实践(第七版)William Stallings---读书笔记 第一部分 概览 第1章 计算机与网络安全概念 密码算法与协议又可分为4个主要领域: 对称加密 加密任意大小的 ...
- 大模型提示词(Prompt)模板推荐
只有提示词写得好,与大模型的互动才能更高效.提示词不仅仅是与AI对话的起点,更是驱动模型产生高质量输出的关键因素.本文将介绍大模型提示词的概念.意义,并分享一些实用的提示词模板,帮助AI玩家更好地利用 ...
- 英语面试-Behavioral Question - first part
前言 希望我总结的行为面试问题和答案能够给大家帮助. 学习方法:每个问题都有三部分组成. 第一部分是语料积累,这里是根据视频中的内容总结而来: 第二部分是中文描述,这里主要根据我自己的经历结合问题做出 ...
- 《机器人SLAM导航核心技术与实战》第1季:第1章_ROS入门必备知识
<机器人SLAM导航核心技术与实战>第1季:第1章_ROS入门必备知识 视频讲解 [第1季]1.第1章_ROS入门必备知识-视频讲解 [第1季]1.1.第1章_ROS入门必备知识-ROS简 ...