/ res和/ assets目录之间的区别


266

我知道res可以从目录访问文件,R.class而资产的行为就像文件系统一样,但是我想知道,通常情况下,何时最好使用一个文件。
谁能帮助我了解资源和资产之间的真正差异?

Answers:


284

随着资源,有内置的支持,提供不同的语言,操作系统版本,屏幕方向等的替代品,如所描述这里。这些都不适用于资产。而且,API的许多部分都支持使用资源标识符。最后,资源的名称将转换为在编译时检查的常量字段名称,因此,代码与资源本身之间不匹配的可能性较小。这些都不适用于资产。

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

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

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


1
res代表资源,那assets代表什么?
Vivek Warde 2014年

40
@vwvwvwvwvwvwvwvwvw-嗯...这并不“代表”任何东西;它仅表示“资产”(如资产中英文单词的复数:有用或有价值的东西)。
泰德·霍普

1
是否可以写入目录中的raw/文件?
王子

6
@Prince-否。/res和'/ assets'目录中的所有内容均为只读,因为它们打包在.apk文件中。
Ted Hopp

我们可以将apk文件放在资产文件夹中,当用户单击该ui时安装该apk吗?
Vivek Mishra'9

63

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

assets目录更像一个文件系统,并提供了更大的自由度,可将您想要的任何文件放入其中。然后,您可以像通过Java访问任何文件系统中的任何文件一样来访问该系统中的每个文件。该目录非常适合诸如游戏详细信息,字典等内容。希望能有所帮助。


5
如果我们想在我们的应用程序中添加external_fonts,则将它们放置在asset文件夹中。
Tushar Pandey 2014年

1
@TusharPandey现在我们不必将字体放在Assets文件夹中,Android系统现在包含fonts目录,我们可以在其中放置自定义字体文件,也可以让Android Studio为我们下载它。
CopsOnRoad

@Jack,对于奥利奥来说。
Tushar Pandey

1
@TusharPandey它在奥利奥加入真实,但它已被向后移植到Android支持库的方式回到API级别16
CopsOnRoad

36

我知道这很老了,但是为了清楚起见,在官方的android文档中有每个说明:

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

assets/

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

res/raw/

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


4
我认为这实际上使这个问题感到困惑-纹理和ogg文件都是您馈送到用户层API(openGL / MediaPlayer)的大量数据...为什么在这里将它们区别开来?

9

以下是一些关键点:

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

结论

  1. Android API包含一个非常舒适的资源框架,该框架也针对各种移动应用程序的最典型用例进行了优化。您应该掌握参考资料并尝试尽可能使用它们。
  2. 但是,如果您在特殊情况下需要更大的灵活性,Assets可以为您提供较低级别的API,该API可以以更高的自由度组织和处理资源。

根据公认的答案,对于使用Gradle构建系统的项目,第4点不再成立。库中的资产被捆绑到应用程序项目的资产集合中。
Venryx

4

如果需要在Java代码中的某处引用它们,则可以将文件放入“ res”目录。

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


6
您也可以从Java访问资产中的文件
Heiko Rupp

2
是的,但是没有索引->会慢一些,这是移动开发中的真正问题。
L.Butz 2011年

那么,资源/原始资源和资产之间有什么区别?res / raw也会被索引吗?
anticafe 2011年

查看@TedHopp的帖子-他给出的答案很明确。
L.Butz 2011年

1

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


0

泰德·霍普(Ted Hopp)回答得很好。我一直在为我的opengl纹理和着色器文件使用res / raw。我当时正在考虑将它们移至资产目录以提供层次结构。

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


1
InputStreams和BitmapFactory支持的第2点对于资源和资产都是正确的(请参见:stackoverflow.com/a/8501428/2441655)。第3点不再适用。(请参见已接受的答案)
Venryx

-5

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


5
这是不正确的。如果输入数据res/raw,则可以使用来获取原始数据openRawResource(resourceName)
Ted Hopp

我在库中有opengles纹理和着色器文件。我必须使用res / raw来存储它们。我使用InputStream和BitmapFactory读取它们。我将其添加为独立评论。
dturvene 2014年

似乎是从Xamarin Microsoft文档复制而来的。复制文本时提供您的信息来源。docs.microsoft.com/en-us/xamarin/android/app-fundamentals/...
Sjoerd Pottuit
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.