学习笔记
Java基础相关
JVM内存模型及线程空间
动态代理
java并发编程
Java基础知识
Java中Future
Java中9种常见的CMS GC问题分析与解决
移动端相关
杂乱整理
HarmonyOS 鸿蒙开发知识
ArkTS中如何自定义组件和复用统一样式
Android开发相关
WebView设置圆角
📄 Android 实时屏幕共享技术方案文档
开发工具相关
Git cmd学习整理
Markdown用法大全集
【2023年12月】工作常用
Git如何单独合并某次提交到另一个分支
Debina/Ubuntu安装Node环境
🐳 Docker 命令行与 Docker Compose 全面指南
使用Podman来替代Docker
中文注释提交git后变成"\u0087\u0079..."问题
macOS 容器化工具深度解析:Docker Desktop、OrbStack、Podman 及其他替代方案对比
前端开发相关
Node+TypeScript相关记录
TypeScript 读写 MariaDB
Node TypeScript项目 token生成、管理及拦截校验的实现
TypeScript+Express创建和实现一个服务示例
Express接口处理器抽取注册方式
Express 实现 RESTful API
创建 TypeScript Express 项目,并配置直接用 npm start 运行
TypeScript + Express 实现文件下载接口
export 和 export default的区别
TypeScript+Express 实现用户注册和登录接口
TypeScript 和 JavaScript 中,`===` 和 `==`
CSS中的尺寸大小标准
小程序px和rpx
使用Python快速处理Excel的合并拆分
读书写作相关
一些句子01
李敖语录
罗翔老师的一些经典语句
周易相关知识
周易是对自然描述还是为自然立法
40句落寞诗词,穿透柔魂弱魄
杂玩整理
黑苹果睿频问题
基于纯Linux自己部署Nas构思
Ubuntu换源
Ubuntu挂载tf卡
Ubuntu运行Docker报错
Ubuntu安装运行Docker报错处理
官方镜像安装Docker
Docker 设置root dir 切换数据到其他存储位置
systemctl stop docker 报错
NextCloud安装ffmpeg 显示视频缩略图
Docker源不生效解决方式
Docker源不生效解决方式II——搭建docker-hub镜像
搞定群晖总Docker部署gitea启用ssh协议
MacOS一键安装命令软件列表
群晖ssl证书目录
Android通过ADB命令播放视频
[完成] 群晖自动更新https证书项目
Linux设备整机限速
Linux限速2
Gitea部署Runner服务
精选网站
有声主播知识
学习笔记
有声主播入门到进阶
有声主播新手的入门练手内容推荐
DeepSeek分析喜马拉雅旗下 喜播平台 的有声主播培训
录书设备资料1
典故专辑资料整理
0B. 脚本和大纲
0A. 前置准备资料
Ai大数据模型
模型整理
使用 DeepSeek 通用公式
学会这8招,让DeepSeek变得超好用!
大数据购物分析选优
Windows和Ubuntu部署DeepSeek性能差距
本地部署 Ollam+DeepSeek 探索爬坑
模型对比测试
React Native 和 native 半屏弹窗
React Native Modal + WebView
AI模型使用心得
临时
Linux下对设备进行限速
C++ 学习
01 Android开发学习C++
其他资料分组
【面试相关】💡 面试后、Offer前,可以主动了解和确认的信息
【工作经验】会计师事务所工作中如何有效管理和规避法律风险
-
+
home page
React Native 和 native 半屏弹窗
你好!你遇到的这个问题非常典型,是理解 Android Activity 生命周期与 React Native (RN) 运行机制交叉影响的关键。 ### 问题根源 当你从一个正在运行的 RN 页面(它本身托管在一个 `Activity` 中,我们称之为 `RNActivity`)启动另一个半透明的 `Activity`(我们称之为 `HalfScreenActivity`)时,Android 系统的行为如下: 1. `HalfScreenActivity` 被推到前台,变为用户可交互的窗口。 2. 尽管 `RNActivity` 在视觉上仍然可见(因为 `HalfScreenActivity` 是半透明的),但它已经失去了焦点。根据 Android 的 Activity 生命周期,`RNActivity` 会进入 `onPause` 状态。 3. **关键点:** React Native 的 JavaScript 线程的执行与宿主 `Activity` 的生命周期紧密相关。当 `RNActivity` 进入 `onPause` 状态时,RN 框架可能会暂停或显著降低 JavaScript 线程的活动,包括计时器(`setTimeout`)、网络请求(`fetch`)的回调处理以及其他异步任务。 这就是为什么你发现后面的 RN 页面“停止加载数据”了——因为它的执行环境被暂停了。 ----- ### 如何处理? 根据你的具体需求,有几种推荐的处理方案,从最佳实践到特定场景的解决方案排序如下: #### 方案一:使用 React Native 的 Modal (最优选) 这是最符合 RN 生态和跨平台开发思想的方案。不要使用原生的 `Activity` 来实现弹窗,而是使用 RN 提供的组件。 **实现方式:** 使用 React Native 内置的 [`Modal`](https://www.google.com/search?q=%5Bhttps://reactnative.dev/docs/modal%5D\(https://reactnative.dev/docs/modal\)) 组件,或者功能更丰富的社区库,如 `react-native-modal`。 **为什么这是最好的方案?** * **单一 Activity,无生命周期中断:** Modal 是在同一个 `Activity` 的视图层级上渲染的,它不会导致 `RNActivity` 进入 `onPause` 状态。因此,RN 的 JavaScript 环境会持续正常运行,数据加载不会中断。 * **状态管理简单:** Modal 的显示和隐藏可以直接通过 RN 的 state (`useState`) 来控制,与你的业务逻辑无缝集成。 * **跨平台:** 一套代码,在 iOS 和 Android 上表现一致。 **示例代码:** ```jsx import React, { useState, useEffect } from 'react'; import { Modal, View, Text, Button, StyleSheet } from 'react-native'; const MyScreen = () => { const [data, setData] = useState(null); const [isModalVisible, setModalVisible] = useState(false); useEffect(() => { // 模拟数据加载 console.log('开始加载数据...'); const timer = setTimeout(() => { console.log('数据加载完成!'); setData('这是从服务器加载的数据'); }, 5000); // 5秒后完成 return () => clearTimeout(timer); }, []); return ( <View style={styles.container}> <Text>RN 页面</Text> <Text>数据: {data || '加载中...'}</Text> <Button title="打开半屏弹窗" onPress={() => setModalVisible(true)} /> <Modal animationType="slide" transparent={true} // 关键!使其透明 visible={isModalVisible} onRequestClose={() => { setModalVisible(!isModalVisible); }}> <View style={styles.modalOverlay}> <View style={styles.modalContent}> <Text>这是一个半屏窗口</Text> <Button title="关闭" onPress={() => setModalVisible(false)} /> </View> </View> </Modal> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', }, modalOverlay: { flex: 1, backgroundColor: 'rgba(0,0,0,0.5)', justifyContent: 'flex-end', // 使其在底部 }, modalContent: { height: '50%', // 半屏高度 backgroundColor: 'white', padding: 20, borderTopLeftRadius: 20, borderTopRightRadius: 20, }, }); export default MyScreen; ``` #### 方案二:使用原生 Fragment 或自定义 View (混合开发推荐) 如果你的半屏窗口必须用原生代码实现(例如,它是一个复杂的原生地图、视频播放器等),那么使用 `Fragment` 或一个自定义的 `View` 会比启动一个新的 `Activity` 更好。 **实现方式:** 1. 创建一个原生的 `Fragment` 或 `View`。 2. 编写一个 Native Module 或 ViewManager,提供 JS 调用的接口来展示和隐藏这个原生组件。 3. 在 RN 中,调用该接口将原生组件覆盖在当前的 `RNActivity` 之上。 **优点:** * 同样不会导致 `RNActivity` 进入 `onPause`,数据加载可以继续。 * 可以充分利用原生能力。 **缺点:** * 实现比方案一复杂,需要编写原生桥接代码。 #### 方案三:处理 Activity 生命周期 (如果必须使用 Activity) 如果你因为某些原因(比如集成第三方只提供 Activity 的 SDK)**必须**启动一个新的 `Activity`,那么你需要接受 `RNActivity` 会被暂停的事实,并在其恢复时做相应处理。 **实现方式:** 当 `HalfScreenActivity` 关闭后,`RNActivity` 会依次调用 `onStart` 和 `onResume` 方法。你需要利用这个时机来重新触发或检查你的数据加载逻辑。 在你的 React Native 组件中,你可以监听应用状态的变化。 **示例代码 (JS 端):** ```jsx import React, { useEffect, useState, AppState } from 'react'; import { View, Text } from 'react-native'; import { NativeModules } from 'react-native'; // 假设你有一个原生模块来启动Activity const MyComponent = () => { const [data, setData] = useState(null); const [appState, setAppState] = useState(AppState.currentState); // 数据加载函数 const loadData = () => { // 避免重复加载 if (data === null || data === '加载失败') { console.log('开始或重新加载数据...'); setData('加载中...'); // 模拟网络请求 setTimeout(() => { console.log('数据加载完成!'); setData('这是重新加载的数据'); }, 2000); } }; useEffect(() => { const subscription = AppState.addEventListener('change', nextAppState => { // 当应用从后台返回前台时,nextAppState 会变为 'active' // 这也对应了 Activity 的 onResume if (appState.match(/inactive|background/) && nextAppState === 'active') { console.log('App has come to the foreground! Resuming tasks.'); loadData(); // 重新加载数据 } setAppState(nextAppState); }); // 首次加载 loadData(); return () => { subscription.remove(); }; }, [appState]); // 依赖 appState 来响应变化 return ( <View> <Text>数据: {data}</Text> {/* 按钮去调用原生方法打开半屏Activity */} <Button title="打开原生Activity" onPress={() => NativeModules.MyModuleManager.openHalfScreenActivity()} /> </View> ); }; ``` 这种方法的逻辑是:当你的半屏 `Activity` 关闭时,`RNActivity` 会 `resume`,这会触发 `AppState` 的 `active` 事件,从而让你有机会重新执行加载逻辑。 ### 总结与对比 | 方案 | 实现方式 | 优点 | 缺点 | 推荐指数 | | :--- | :--- | :--- | :--- | :--- | | **方案一** | **React Native Modal** | **简单、纯JS、跨平台、无生命周期问题** | 对于极度复杂的原生UI可能有限制 | ⭐⭐⭐⭐⭐ (首选) | | **方案二** | 原生 Fragment / View | 性能好,可实现复杂原生UI,无生命周期问题 | 需要编写原生桥接代码,实现复杂 | ⭐⭐⭐⭐ | | **方案三** | 处理 Activity 生命周期 | 可以集成必须使用 `Activity` 的第三方SDK | **数据加载会中断和重启**,逻辑复杂,体验可能不佳 | ⭐⭐ (仅在别无选择时使用) | **强烈建议你首先尝试方案一**,使用 React Native 的 `Modal` 组件,这是最直接、最符合框架设计思想的解决方案。
嘿手大叔
Oct. 9, 2025, 7:08 p.m.
转发文档
Collection documents
Last
Next
手机扫码
Copy link
手机扫一扫转发分享
Copy link
Markdown文件
share
link
type
password
Update password