285

我知道res目录中的文件可以访问,R.class而资产的行为类似于文件系统,但我想知道,一般来说,什么时候最好使用一个和另一个。
谁能帮助我了解资源和资产之间的真正区别?

4

8 回答 8

301

通过资源,内置支持为不同语言、操作系统版本、屏幕方向等提供替代方案,如此处所述。这些都不适用于资产。此外,API 的许多部分都支持使用资源标识符。最后,资源的名称被转换为在编译时检查的常量字段名称,因此代码和资源本身之间不匹配的机会更少。这些都不适用于资产。

那么为什么有一个资产文件夹呢?如果你想计算你想在运行时使用的资产,这很容易。对于资源,您必须声明可能使用的所有资源 ID 的列表,并计算列表中的索引。(如果资源集在开发周期中发生变化,这有点尴尬,并且会引入出错的机会。)(编辑:您可以使用名称检索资源 ID getIdentifier,但这失去了编译时检查的好处。)资产可以也被组织成一个文件夹层次结构,这是资源不支持的。这是一种不同的数据管理方式。尽管资源涵盖了大多数情况,但资产偶尔也会用到。

另一个区别:库项目中定义的资源会自动导入到依赖于库的应用程序项目中。对于资产,这不会发生;资产文件必须存在于应用程序项目的资产目录中。[编辑:使用 Android 新的基于 Gradle 的构建系统(与 Android Studio 一起使用),这不再适用。/assets库项目的资产目录被打包到 .aar 文件中,因此库项目中定义的资产被合并到应用程序项目中(因此,如果它们在引用的库中,它们不必存在于应用程序的目录中)。]

编辑:如果您想将自定义字体与您的应用程序打包,则会出现另一个差异。有API 调用Typeface可以从存储在文件系统或应用程序assets/目录中的字体文件创建一个。但是没有 API 可以Typeface从存储在res/目录中的字体文件(或从InputStream允许使用res/目录的 )创建一个。[注意:使用 Android O(现在提供 alpha 预览版),您将能够将自定义字体作为资源包含在内。请参阅此处对这个过期已久的功能的描述。但是,只要您的最低 API 级别为 25 或更低,您就必须坚持将自定义字体打包为资产而不是资源。]

于 2011-04-07T15:41:04.410 回答
71

两者都非常相似。两者之间真正的主要区别在于,在res目录中,每个文件都有一个预编译文件ID ,可以通过R.id.[res id]. 这有助于快速轻松地访问图像、声音、图标......

assets目录更像是一个文件系统,并提供了更多的自由来放置您想要的任何文件。然后,您可以访问该系统中的每个文件,就像通过 Java 访问任何文件系统中的任何文件一样。该目录适用于诸如游戏详细信息、字典等之类的内容。希望有帮助。

于 2011-04-07T15:34:45.390 回答
41

我知道这是旧的,但为了清楚起见,官方 android 文档中对每个都有解释:

来自http://developer.android.com/tools/projects/index.html

assets/

这是空的。您可以使用它来存储原始资产文件。您在此处保存的文件将按原样编译为 .apk 文件,并保留原始文件名。您可以使用 URI 以与典型文件系统相同的方式导航此目录,并使用 AssetManager 将文件作为字节流读取。例如,这是放置纹理和游戏数据的好位置。

res/raw/

对于任意原始资产文件。将资产文件保存在此处而不是 assets/ 目录中仅在您访问它们的方式上有所不同。这些文件由 aapt 处理,并且必须使用 R 类中的资源标识符从应用程序中引用。例如,这是存放 MP3 或 Ogg 文件等媒体的好地方。

于 2013-07-23T17:29:37.113 回答
14

以下是一些关键点:

  1. 原始文件的名称必须是有效的 Java 标识符,而 Assets 中的文件没有位置和名称限制。换句话说,它们可以分组在我们希望的任何目录中
  2. 原始文件很容易从 Java 和 xml 中引用(即,您可以从清单或其他 xml 文件中引用原始文件)。
  3. 在这里而不是在 assets/ 目录中保存资产文件仅在访问它们的方式上有所不同,如 http://developer.android.com/tools/projects/index.html中所述。
  4. 库项目中定义的资源会自动导入到依赖于库的应用程序项目中。对于资产,这不会发生;资产文件必须存在于应用程序项目的资产目录中
  5. assets 目录更像是一个文件系统,提供了更多的自由来放置您想要的任何文件。然后,您可以访问该系统中的每个文件,就像通过 Java 访问任何文件系统中的任何文件一样。比如游戏数据文件、字体、纹理等。
  6. 与资源不同,资产可以组织到资产目录中的子文件夹中。但是,您可以对资产做的唯一事情是获取输入流。因此,将字符串或位图存储在资产中没有多大意义,但您可以存储自定义格式的数据,例如输入校正字典或游戏地图。
  7. Raw 可以通过生成 R.java 文件为您提供编译时间检查,但是如果您想将数据库复制到私有目录,您可以使用为流式传输而制作的资产。

结论

  1. Android API 包含一个非常舒适的资源框架,该框架还针对各种移动应用程序的大多数典型用例进行了优化。您应该掌握资源并尽可能地使用它们。
  2. 但是,如果您的特殊情况需要更大的灵活性,Assets 可以为您提供较低级别的 API,允许以更高的自由度组织和处理您的资源。
于 2014-04-23T06:22:55.943 回答
4

如果您需要在 Java 代码中的某个地方引用它们,您最好将文件放入“res”目录中。

res 文件夹中的所有文件都将在 R 文件中建立索引,这使得加载它们变得更快(也更容易!)。

于 2011-04-07T15:32:35.437 回答
1

使用文件系统之类的资产来转储任何类型的文件。并使用 res 来存储它的用途、布局、图像、值。

于 2015-03-12T20:37:02.607 回答
0

Ted Hopp 很好地回答了这个问题。我一直在为我的 opengl 纹理和着色器文件使用 res/raw。我正在考虑将它们移动到资产目录以提供分层组织。

这个线程说服我不要。首先,因为我喜欢使用唯一的资源 ID。其次,因为使用 InputStream/openRawResource 或 BitmapFactory 读取文件非常简单。第三,因为能够在可移植库中使用非常有用。

于 2014-04-03T17:13:58.487 回答
-5

资产提供了一种在应用程序中包含任意文件(如文本、xml、字体、音乐和视频)的方法。如果您尝试将这些文件作为“资源”包含在内,Android 会将它们处理到其资源系统中,您将无法获取原始数据。如果您想访问原封不动的数据,资产是一种方法。

于 2013-07-20T16:37:43.013 回答