概述
资源类型
在项目res/目录中支持的资源目录。
目录 | 说明 |
---|---|
animator/ | 定义属性动画的 XML 文件。 |
anim/ | 定义渐变动画的XML文件。(属性动画的XML在改目录中也会生效,因此,属性动画的XML文件应该优先存放于animator中,以便区分。) |
color/ | 定义颜色状态的 XML 文件。 |
drawable/ | 位图文件(.png、.9.png、.jpg、.gif)或编译为以下可绘制对象资源子类型的 XML 文件:位图文件、九宫格(可调整大小的位图)、状态列表、形状、动画可绘制对象、、其他可绘制对象。 |
mipmap/ | 适用于不同启动器图标密度的可绘制对象文件。 |
layout/ | 用于定义用户界面布局的 XML 文件。 |
menu/ | 用于定义应用菜单(如选项菜单、上下文菜单或子菜单)的 XML 文件。 |
raw/ | 需以原始形式保存的任意文件。 |
values/ | 定义字符串、整型数和颜色等简单值的 XML 文件。 |
xml/ | 可在运行时通过调用 Resources.getXML() 读取的任意 XML 文件。 |
font/ | 带有扩展名的字体文件(如 .ttf、.otf 或 .ttc),或包含 <font-family> 元素的 XML 文件。 |
注:
- 存放于raw/下的资源,如要使用原始 InputStream 打开,请使用资源 ID(即 R.raw.filename)调用 Resources.openRawResource()。
- assets/ 中的文件没有资源 ID,因此您只能使用 AssetManager 读取这些文件。
- 其他 res/ 子目录中的 XML 资源文件会根据 XML 文件名定义单个资源,而 values/ 目录中的文件可描述多个资源。
- 资源文件不能直接保存在 res/ 目录内,因为这样会造成编译错误。
备用资源
根据特定配置和地区的设备指定不同的资源文件,Android 会检测当前设备配置并为应用加载合适的资源。例如,可以指定屏幕的横向和竖向加载不同的layout文件。
https://developer.android.google.cn/images/resources/resource_devices_diagram2.png
在 res/ 中创建以 <resources_name>-<config_qualifier> 形式命名的新目录。
<resources_name>
是相应默认资源的目录名称。<config_qualifier>
是指定要使用这些资源的各个配置的名称。
res/
drawable/
icon.png
background.png
drawable-hdpi/
icon.png
background.png
注:
- 可以为单组资源指定多个限定符,并使用短划线分隔,这些限定符必须遵循官网中列出的顺序。
- 不能嵌套备用资源目录。例如,目录不能为 res/drawable/drawable-en/。
- 值不区分大小写。
- 每种限定符类型仅支持一个值。例如,若要对西班牙语和法语使用相同的可绘制对象文件,不能拥有名为 drawable-rES-rFR/ 的目录,而是需要两个包含相应文件的资源目录,如 drawable-rES/ 和 drawable-rFR/。
别名资源
图像
假设有一个应用图标 icon.png,加拿大英语和加拿大法语这两种语言区域都需使用这个图标的同一版本,则可以将用于二者的图像保存为 icon_ca.png(除 icon.png 以外的任何名称),并将其放入默认的 res/drawable/ 目录中。然后,在 res/drawable-en-rCA/ 和 res/drawable-fr-rCA/ 中创建 icon.xml 文件,使用 <bitmap>
元素引用 icon_ca.png 资源。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<drawable name="icon">@drawable/icon_ca</drawable>
</resources>
布局
使用 <merge>
和 <include>
元素。
<?xml version="1.0" encoding="utf-8"?>
<merge>
<include layout="@layout/main_ltr"/>
</merge>
如果将此文件保存为 main.xml,则系统会将其编译到可作为 R.layout.main 引用的资源中,但该文件实际是 R.layout.main_ltr 资源的别名。
字符串和其他简单值
如要创建指向现有字符串的别名,只需将所需字符串的资源 ID 用作新字符串的值。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello</string>
<string name="hi">@string/hello</string>
</resources>
访问资源
在代码中访问资源
以下是在代码中引用资源的语法:
[<package_name>.]R.<resource_type>.<resource_name>
<package_name>
是资源所在包的名称(如果引用的资源来自您自己的资源包,则不需要)。<resource_type>
是资源类型的 R 子类。<resource_name>
是不带扩展名的资源文件名,或 XML 元素中的 android:name 属性值(若资源是简单值)。
注意:切勿手动修改 R.java 文件 — 在编译项目时,aapt 工具会生成该文件。下次编译时,所有更改都会被覆盖。
在 XML 中访问资源
以下是在 XML 资源中引用资源的语法:
@[<package_name>:]<resource_type>/<resource_name>
<package_name>
是资源所在包的名称(如果引用的资源来自相同资源包,则不需要)。<resource_type>
是资源类型的 R 子类。<resource_name>
是不带扩展名的资源文件名,或 XML 元素中的 android:name 属性值(若资源是简单值)。
访问平台资源
Android 包含许多标准资源,例如样式、主题背景和布局。如要访问这些资源,请通过 android 包名称限定资源引用。
setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myarray));
Android 是如何匹配资源的
Android 根据当前的设备配置,并按照官方文档中限定的顺序进行备用资源的匹配,如果未找到。这时应用将使用默认资源,如果没有默认资源,则报错。如有以下目录:
drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/
设备配置如下:
语言区域 = en-GB
屏幕方向 = port
屏幕像素密度 = hdpi
触摸屏类型 = notouch
主要文本输入法 = 12key
最终会选择:
drawable-en-port/
应用配置变更
当应用配置发生变化时,Android系统会重新启动正在运行的Activity,通过这种方式,使得应用可以加载相应的备用资源来更新Activity(这个更新过程,会调用onDestroy()与onCreate()方法),Activity的状态、数据会被销毁,因此需要我们自行保存数据。
onSaveInstanceState()和onRestoreInstanceState()
在Activity因为配置发生销毁时,会先调用onSaveInstanceState()方法,该方法将保存一个Bundle以便在重启时恢复数据,而onRestoreInstanceState()只有在存在保存状态的情况下才会被调用,因此不需要检查是否Bundle为空。Bundle并非用于携带大量数据对象,因为其中的数据必须依次在主线程中进行序列化和反序列化,而这可能会消耗大量内存并降低配置变更的速度。
ViewModel对象
Activity进行重建的时候,ViewModel的数据不会被回收调用。这时候我们就可以不用通过onSaveInstanceState()方法来进行数据的存储了。而且用onSaveInstanceState()方法为了使Activity能够尽快的重建还只能存储少量的数据进行恢复。
自行处理重建情况
通过在 AndroidManifest.xml
文件的 <activity>
标签中添加android:configChanges属性可以阻止系统重建Activity。其属性值有:
- orientation:在屏幕方向发生变更时阻止重启。
- screenSize:在屏幕方向发生变更时阻止重启。但仅适用于 Android 3.2(API 级别 13)及以上版本的系统。若想在应用中手动处理配置变更,必须在 android:configChanges 属性中声明 “orientation” 和 “screenSize” 值。
- keyboardHidden:在键盘可用性发生变更时阻止重启。
多个配置值,用管道 | 字符将其进行分隔。
***注:***自行处理配置变更可能会提高使用备用资源的难度,因为系统不会为您自动应用这些资源。