深入理解 Android 文件共享机制,掌握面试高频考点
context.getExternalFilesDir(Environment.DIRECTORY_MOVIES)
video.mp4.tmptempFile.renameTo(targetFile)LocalBroadcastManager或 FileObservertempFile.delete()| 方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 广播 | 简单,可跨应用 | 数据量小,全局广播不安全 | 同应用低频率通知 |
| FileObserver | 实时性好,高效 | 仅限同 UID | 同应用多进程 |
| ContentObserver | 标准跨应用通知 | 需依赖 ContentProvider | 跨应用文件共享 |
| Messenger/AIDL | 双向实时,可带结构化数据 | 需绑定 Service | 双向通信场景 |
FileChannel.lock()排他锁,适用于短时小数据写入一次性序列化会将整个对象列表和完整 JSON 字符串同时放在内存中,极易 OOM。
流式序列化(如 JsonWriter)遍历数据源,来一条写一条,内存中永远只保留当前一条数据的大小。
推荐方案:FileProvider
FileProvider.getUriForFile()生成 content://URIFLAG_GRANT_READ_URI_PERMISSION临时授权contentResolver.openInputStream(uri)读取,无需存储权限content://URIFLAG_GRANT_READ_URI_PERMISSION授予临时读权限,任务栈销毁后自动回收选择 Messenger:内存操作极快(微秒级),消息队列天然线程安全,数据到即通知。
文件共享磁盘 IO 慢(毫秒级),频繁写入伤闪存,且需要额外处理并发和通知。
| 场景 | 数据特点 | IPC 选择 | 理由 |
|---|---|---|---|
| 下载进度回调 | 高频、小数据 | AIDL 回调 | 服务端主动推送,实时性高 |
| 启动下载任务 | 一次性配置参数 | Bundle/Intent | 简单高效 |
| 下载完成的音乐文件 | 大文件 | 文件共享+广播 | 突破 Binder 限制 |
| 播放状态同步 | 状态小数据 | Messenger/AIDL | 低延迟双向 |