Android 的 assets 资源和 raw 资源有什么区别?

众所周知,Android 里,assetsres/raw 都可以用来放资源文件。那么为什么要设计这两种方式呢?

结论是:

  • res/raw:受 Android 资源系统管理的文件,无目录结构,有资源 ID。参与资源选择(语言/夜间/屏幕密度);必须小写、无点号、无特殊字符。
  • assets:打包进 APK 的原始文件系统,像读普通文件一样,适合需要目录结构 / 动态读取 / 文件较多或名称不规则的场景。

一、不同点

1.1. 特性对比

特性 raw assets
是否生成 R.id
是否参与资源选择(语言/夜间/屏幕密度)
编译期校验
是否必须小写、无点号、无特殊字符
是否可以遍历目录

raw 的命名比较严格,我之前觉得这是一个缺陷,AI 老师说是是为了让资源名成为一种跨语言、跨工具、跨平台都稳定的符号。

比如要同时支持运行在大小写敏感/不敏感文件系统,那么就要让资源名舍弃大写字母;. 号在引用资源时已经用掉了之类的原因。

raw 要生成资源 id,在 Java / Kotlin / C++ 等语言中引用,使用有这些限制。

assets 没有这些限制,因为 APK 安装后,assets 文件在 APK 内部就是一个 ZIP entry,它是 严格大小写敏感,Android 在访问时直接从 ZIP 读取,不走宿主文件系统。

1.2. 放置位置:

raw 放在这里:

css 复制代码
app/
 └─ src/main/
    └─ res/
       └─ raw/
          └─ config.txt

assets 放在这里:

css 复制代码
app/
 └─ src/main/
    └─ assets/
       └─ configs/
          └─ config.txt

1.3. 使用场景

我之前有一个误解,apk 安装后,资源文件会被放在一个文件目录下,我误以为可以在 apk 安装后,从服务器下载文件,也放到这个目录下面,再通过 assets 或者 raw 来读取。我以为 assets 或者 raw 能够做到这一点。 实际上是不行的,APK 是一个 签名过的 ZIP 文件,任何修改都会破坏签名。

这种 case 通常的做法是,从 assets 拷贝到 filesDir 文件夹,然后服务器也下载到这个 filesDir 文件夹。而不是直接下到 assets 或者 raw 中,这是不可能的。

一个常见的使用 assets 的场景:

scss 复制代码
// SDK 启动时,把 assets 里的本地数据拷贝到 filesDir
copyAssetsToFilesDir()
// 与服务器通信,检查这些资源是否需要更新
updateFromServerIfNeeded()

这就是 固定资源 + 可更新数据 的组合,而 raw 做不到目录、遍历、动态拷贝。

一个常见的使用 raw 的场景:

bash 复制代码
res/raw/config.txt
res/raw-night/config.txt
res/raw-zh/config.txt
res/raw-zh-rCN/config.txt
...

Android 会自动帮你选:

  • night / notnight
  • zh / en
  • region
  • smallestWidth
  • density
  • ...

assets 完全没有这个能力

1.4. 读取方式

读取 raw 的方式是按 ID 取资源,以文件 res/raw/config.txt 为例:

ini 复制代码
val inputStream = resources.openRawResource(R.raw.config)
val text = inputStream.bufferedReader().use { it.readText() }

读取 assets 的方式是按路径读文件:

ini 复制代码
val inputStream = assets.open("configs/config.txt")
val text = inputStream.bufferedReader().use { it.readText() }

二、相同点

  • 两者在 apk 中都以原始资源文件的方式存在
  • 两者本质都是从 APK 中读取 InputStream
  • 性能差异基本可以忽略

三、如何选择

简单来说:

  • 如果你把它当成'资源'(需要参与语言/夜间等选择、生成 R.id),用 raw
  • 如果把它当成'文件'(目录结构、动态访问、可更新),用 assets。
相关推荐
氦客25 分钟前
Android Compose 图层的合成 : BlendMode
android·compose·jetpack·layer·blendmode·graphics·图层的合成
Sahadev_1 小时前
GitMemo 安卓版发布了:现在可以随时随地查看和记录自己的笔记
android·笔记·创业创新
龙之叶2 小时前
Android 12:在 ActivityStarter 层拦截分享、搜索与 HTTP 外链
android·chrome·http
牛奔2 小时前
Android 开发通用解决方案:使用 ADB 彻底卸载已安装 App(解决版本降级安装失败问题)
android·adb
tryqaaa_3 小时前
学习日志(三)【php语法学习,iscc校赛wp】
android·网络协议·学习·安全·web安全·web
plainGeekDev3 小时前
Kotlin协程面试题:suspend原理都说不清,协程你真会用?
android·面试·kotlin
Kapaseker3 小时前
Android 官方开始拥抱 WebView
android
ujainu小4 小时前
CANN hixl:大模型 PD 分离场景的零拷贝通信库
android·java·缓存
专注VB编程开发20年4 小时前
b4a用VB语言开发安卓APP-图片缩放库ZoomImageView讲解-双指缩放 + 单指拖动核心源码
android·java·前端
恋猫de小郭5 小时前
Dart 大更新,新增语法糖和各种能力,真的难得了
android·前端·flutter