Android Resources - tenji/ks GitHub Wiki

Android Resources

Android 应用程序主要由两部分内容组成:代码和资源。资源是指代码使用的附加文件和静态内容,例如位图、布局定义、界面字符串、动画说明等。代码和资源分开可以使得应用程序在运行时根据实际需要来组织 UI。这样就可使得应用程序只需要编译一次,就可以支持不同的 UI 布局。这种特性使得应用程序在运行时可以适应不同的屏幕大小和密度,以及不同的国家和语言等。

一、Resources 类型分组

1.1 assets

assets 类资源放在工程根目录的 assets 子目录下,它里面保存的是一些原始的文件,可以以任何方式来进行组织。这些文件最终会被原装不动地打包在 apk 文件中。如果我们要在程序中访问这些文件,那么就需要指定文件名来访问。例如,假设在 assets 目录下有一个名称为 filename 的文件,那么就可以使用以下代码来访问它:

AssetManager am= getAssets();
InputStream is = assset.open("filename");

1.2 res

res 类资源放在工程根目录的 res 子目录下,它里面保存的文件大多数都会被编译,并且都会被赋予资源 ID。这样我们就可以在程序中通过 ID 来访问 res 类的资源。res 类资源按照不同的用途可以进一步划分为以下 11 种子类型:

1.2.1 animator

用于定义属性动画的 XML 文件。

属性动画通过改变对象的属性来实现动画效果,例如,通过不断地修改对象的坐标值来实现对象移动动画,又如,通过不断地修改对象的 Alpha 通道值来实现对象的渐变效果。

1.2.2 anim

用于定义渐变动画的 XML 文件。(属性动画也可保存在此目录中,但为了区分这两种类型,属性动画首选 animator/ 目录。)

渐变动画和属性动画不同,它不是通过修改对象的属性来实现,而是在对象的原来形状或者位置的基础上实现一个变换来得到的,例如,对对象施加一个旋转变换,就可以获得一个旋转动画,又如,对对象实施一个缩放变换,就可以获得一个缩放动画。从数学上来讲,就是在对象的原来形状或者位置的基础上施加一个变换矩阵来实现动画效果。注意,在动画的执行过程中,对象的属性是始终保持不变的,我们看到的只不过是它的一个变形副本。

1.2.3 color

用于定义颜色状态列表的 XML 文件。请参阅颜色状态列表资源

例如,我们可以定义一个选择子,规定一个对象在不同状态下显示不同的颜色。对象的状态可以划分为 pressed, focused, selected, checkable, checked, enabled, window_focused 等 7 种。

1.2.4 drawable

位图文件(.png、.9.png、.jpg、.gif)或编译为以下可绘制对象资源子类型的 XML 文件:

  • 位图文件
  • 九宫格(可调整大小的位图)
  • 状态列表
  • 形状
  • 动画可绘制对象
  • 其他可绘制对象

请参阅 Drawable 资源。

1.2.5 mipmap

适用于不同启动器图标密度的可绘制对象文件。如需了解有关使用 mipmap/ 文件夹管理启动器图标的详细信息,请参阅管理项目概览

1.2.6 layout

用于定义用户界面布局的 XML 文件。请参阅布局资源

1.2.7 menu

用于定义应用菜单(如选项菜单、上下文菜单或子菜单)的 XML 文件。请参阅菜单资源

1.2.8 raw

需以原始形式保存的任意文件。如要使用原始 InputStream 打开这些资源,请使用资源 ID(即 R.raw.filename)调用 Resources.openRawResource()

但是,如需访问原始文件名和文件层次结构,则可以考虑将某些资源保存在 assets/ 目录(而非 res/raw/)下。assets/ 中的文件没有资源 ID,因此您只能使用 AssetManager 读取这些文件。

Resources res = getResources();
InputStream is = res .openRawResource(R.raw.filename);

1.2.9 values

包含字符串、整型数和颜色等简单值的 XML 文件。

其他 res/ 子目录中的 XML 资源文件会根据 XML 文件名定义单个资源,而 values/ 目录中的文件可描述多个资源。对于此目录中的文件, 元素的每个子元素均会定义一个资源。例如, 元素会创建 R.string 资源, 元素会创建 R.color 资源。

由于每个资源均使用自己的 XML 元素进行定义,因此您可以随意命名文件,并在某个文件中放入不同的资源类型。但是,您可能需要将独特的资源类型放在不同的文件中,使其一目了然。例如,对于可在此目录中创建的资源,下面给出了相应的文件名约定:

请参阅字符串资源样式资源更多资源类型

1.2.10 xml

可在运行时通过调用 Resources.getXML() 读取的任意 XML 文件。各种 XML 配置文件(如可搜索配置)都必须保存在此处。

1.2.11 font

带有扩展名的字体文件(如 .ttf、.otf 或 .ttc),或包含 元素的 XML 文件。如需详细了解作为资源的字体,请参阅 XML 中的字体

二、提供备用 Resources

待更新...

三、访问应用 Resources

在应用中提供资源后,您可通过引用其资源 ID 来应用该资源。所有资源 ID 都在您项目的 R 类中进行定义,该类由 aapt 工具自动生成。

编译应用时,aapt 会生成 R 类,其中包含 res/ 目录中所有资源的资源 ID。每个资源类型都有对应的 R 子类(例如,R.drawable 对应所有可绘制对象资源),而该类型的每个资源都有对应的静态整型数(例如,R.drawable.icon)。该整型数就是可用来检索资源的资源 ID。

尽管资源 ID 是在 R 类中指定的,但您完全不需要在该类中查找资源 ID。资源 ID 始终由以下部分组成:

  • 资源类型:每个资源都被分到一个“类型”组中,例如 stringdrawablelayout。如需了解有关不同类型的详细信息,请参阅资源类型
  • 资源名称,它是不包括扩展名的文件名;或是 XML android:name 属性中的值(如资源是字符串等简单值)。

访问资源的方法有两种:

  • 在代码中:使用来自 R 类子类的静态整型数,例如:

    R.string.hello
    

    string 为资源类型,hello 为资源名称。当您提供此格式的资源 ID 时,有许多 Android API 可以访问您的资源。请参阅在代码中访问资源

  • 在 XML 中:使用同样与 R 类中所定义资源 ID 对应的特殊 XML 语法,例如:

    @string/hello
    

    string 为资源类型,hello 为资源名称。只要 XML 资源中的某处拥有您在资源中提供的值,则您便可在该 XML 资源中使用此语法。请参阅在 XML 中访问资源

3.1 在代码中访问 Resources

3.2 在 XML 中访问 Resources

3.3 访问原始文件

尽管并不常见,但您的确有可能需要访问原始文件和目录。如果确有需要,则将文件保存在 res/ 中并没有用,因为从 res/ 读取资源的唯一方法是使用资源 ID。您可以改为将资源保存在 assets/ 目录中。

保存在 assets/ 目录中的文件没有资源 ID,因此您无法通过 R 类或在 XML 资源中引用它们。您可以改为采用类似普通文件系统的方式查询 assets/ 目录中的文件,并利用 AssetManager 读取原始数据。

不过,如果您只需要读取原始数据(例如视频文件或音频文件)的能力,则可将文件保存在 res/raw/ 目录中,并利用 openRawResource() 读取字节流。

3.4 访问平台资源

Android 包含许多标准资源,例如样式、主题背景和布局。如要访问这些资源,请通过 android 包名称限定您的资源引用。例如,您可以将 Android 提供的布局资源用于 ListAdapter 中的列表项:

setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myarray));

四、利用 Resources 提供最佳设备兼容性

待更新...

五、Android 如何查找最佳匹配资源

待更新...

六、总结

  • 除了 assets 和 res/raw 资源被原装不动地打包进 APK 之外,其它的资源都会被编译或者处理;
  • 除了 assets 资源之外,其它的资源都会被赋予一个资源 ID;
  • 打包工具负责编译和打包资源,编译完成之后,会生成一个 resources.arsc 文件和一个 R.java,前者保存的是一个资源索引表,后者定义了各个资源 ID 常量;
  • 应用程序配置文件 AndroidManifest.xml 同样会被编译成二进制的 XML 文件,然后再打包到 APK 里面去;
  • 应用程序在运行时通过 AssetManager 来访问资源,或通过资源 ID 来访问,或通过文件名来访问;
  • 在项目文件夹的 gen 文件夹里面有个 R.java,我们平常引用的资源主要引用这个类的变量。注意:R 类是自动生成的,并且它不能被手动修改。当资源发生变动时,它会自动修改;
  • Android 资源除了 assets 目录是与 res 同级外,其它资源均被放在 res/ 目录下面,该目录下面的资源文件夹并不是随意命名的,需要遵循严格的规范,否则编译生成 R.java 过程中会报类似 “invalidresource directory name **” 的错误提示,并且导致 R.java 自动生成失败。

参考链接

⚠️ **GitHub.com Fallback** ⚠️