一句话总结:
解决大数据传递问题的关键,是首先明确数据的“作用域”。应用内部的传递,应首选 ViewModel 和 Repository 架构;而跨进程的共享,则应采用现代的 SharedMemory 机制。
第一步:重新定义问题——你的数据要“搬”到哪里去?
在选择“搬家工具”之前,我们必须先回答两个核心问题:
- 数据传递的作用域是? 是在同一个 App 内部(Intra-Process),还是需要跨越 App 的边界(Inter-Process)?
- 数据的生命周期是? 数据是一次性的瞬时传递,还是需要在多个地方被缓存和复用?
根据这两个问题的答案,我们可以绘制出一张清晰的决策地图。
场景一:“户内搬运”——同一个应用内的数据传递 (Intra-Process)
当你在应用的 Activity、Fragment 之间传递数据时,所有组件都运行在同一个进程中。此时,我们有最高效、最安全的架构方案。
情况 A: 瞬时数据传递(把客厅的数据带到卧室)
-
需求: 将一个屏幕的数据(如用户填写的数据对象)传递给下一个屏幕。
-
最佳方案:使用
ViewModelViewModel的生命周期长于Activity/Fragment,能在屏幕旋转等配置变更后存活。将数据保存在ViewModel中,新的 UI 组件可以直接从中获取,无需通过Intent传递,避免了序列化和大小限制。- 这是 Jetpack 架构下的“标准答案”,它从根本上解决了进程内的数据共享问题。
情况 B: 缓存与复用(把常用物品放在公共储物柜)
-
需求: 缓存从网络或数据库加载的数据(如用户信息、配置),供 App 内多个页面使用。
-
最佳方案:Repository +
LRUCache- 在这里,
LRUCache终于找到了它正确的位置——作为数据仓库 (Repository) 内部的内存缓存策略。 - 正确架构: UI 层向
Repository请求数据,Repository优先从内部的LRUCache中查找,如果未命中,再从网络或数据库加载,并存入缓存。UI 层永远不应直接与LRUCache交互。
- 在这里,
场景二:“跨国运输”——跨进程数据共享 (Inter-Process)
当数据需要从你的 App 发送到另一个 App、一个独立的 Service 进程,或者反之时,我们必须使用真正的 IPC(跨进程通信)机制。
情况 A: 瞬时、大数据量的传递(空投一个大型集装箱)
-
需求: 发送一个大型 Bitmap、一段音频数据或一个机器学习模型文件给另一个进程。
-
最佳方案:现代
SharedMemoryAPI (Android 8.0+)SharedMemory是官方推荐的、用于跨进程共享大块数据的高性能“零拷贝”方案。它通过传递一个轻量的文件描述符,让多个进程直接映射到同一块物理内存。- 这是 Ashmem 技术的现代化、安全且无需反射的实现方式。
// 发送方:创建、写入并发送 SharedMemory val shm = SharedMemory.create("MySharedMemory", 1024 * 1024) // 创建 1MB 共享内存 val byteBuffer = shm.mapReadWrite() byteBuffer.put(largeDataByteArray) SharedMemory.unmap(byteBuffer) // 通过 Binder/Intent 传递 ParcelFileDescriptor val pfd = shm.parcelFileDescriptor // intent.putExtra("shm_pfd", pfd) // 接收方:通过 PFD 映射并读取 val receivedPfd = // ... 从 Intent/Binder 获取 ... val receivedShm = SharedMemory.fromFileDescriptor(receivedPfd) val readBuffer = receivedShm.mapReadOnly() val receivedData = ByteArray(readBuffer.remaining()) readBuffer.get(receivedData) // ... 使用数据后,记得关闭资源 ...
情况 B: 结构化、持久化的数据共享(建立一个标准化的海关口岸)
-
需求: 向其他应用安全地暴露你的文件、或数据库中的特定数据(如联系人应用)。
-
最佳方案:
ContentProvider- 这是 Android 平台官方指定的、用于跨进程共享结构化数据的标准机制。它拥有完善的权限模型和统一的 URI 查询接口,是实现安全、可控的数据共享的唯一正确方式。
四、总结:你的大数据传递决策矩阵
| 瞬时传递 (Transient) | 缓存/持久化 (Cached/Persistent) | |
|---|---|---|
| 应用内 (Intra-Process) | ViewModel | Repository + LRUCache |
| 跨进程 (Inter-Process) | SharedMemory | ContentProvider (背后可以是文件或数据库) |
通过这个矩阵,你可以清晰地看到,LRUCache 和 SharedMemory (Ashmem) 并非竞争关系,而是分别服务于完全不同架构场景的专属工具。在为你的大数据“搬家”前,请先用这个矩阵定位你的“作用域”,然后选择最高效、最正确的“交通工具”。