1 什么是Resource

Resource,即资源,在Android中,资源是指代码中使用附加文件和静态内容,例如位图、界面布局、界面字符串、动画说明等等。

我们将资源放在分类目录下,以便单独对其进行维护,例如图像和代码中的字符串。此外,还应为特定设备提供备用资源,例如根据屏幕尺寸提供不同界面布局,或者根据语言设置提供不同的字符串,

1.1 分组资源类型

各种类型的资源被放入项目res/目录的特定子目录中。如下所示为一个简单项目的文件层次结构。

注意:切勿将资源文件直接保存在 res/ 目录内,因为这样会造成编译错误,应按类别新建子目录。
MyProject/    src/        MyActivity.java    res/        drawable/            graphic.png        layout/            main.xml            info.xml        mipmap/            icon.png        values/            strings.xml

Android支持的分组资源类型请参考官方文档:分组资源类型

1.2 提供备用资源

之所以提供备用资源,是为了支持特定的设备配置。如针对不同的屏幕密度和语言,应分别加入备用的可绘制对象资源和备用字符串资源。在运行时,Android会检测当前设备配置并为应用加载合适的资源。
格式:在res/目录下创建以-形式命名的新目录

举例:如下所示为备用的可绘制对象资源:

更多有关可绘制对象资源类型请参考下图:

更多配置限定符的内容请参考官方文档 提供备用资源,以及关于创建别名资源的方法请参考 创建别名资源。

2 如何引用(访问)Resource

编译应用时,aapt会生成R类,其中包含res/目录下所有资源的资源ID,每种资源类型都有对应的R子类,并且该类型下的每个资源都有静态的整型数——资源ID。于是,我们可以在项目中借助R类中生成的资源ID来访问这些资源。例如R.drawable对应于所有可绘制对象资源,引用方式为R.drawable.icon。

2.1 在代码中引用资源

格式:[.]R..

说明:

  • :是资源所在包的名称,如果引用的资源是自己的提供的资源,则不需要;
  • :是资源类型的R子类;
  • :是不带扩展名的资源文件名。
注意资源名称是不包含扩展名的,例如引用图片时没有必要加上 .jpg或者 .png等。

举例:R.drawable.myimageR.string.main_titleR.layout.main_screen等。

2.2 在xml中引用资源[email protected]

格式:@[:]/

说明(同上):

  • :是资源所在包的名称,如果引用的资源是自己的提供的资源,则不需要;
  • :是资源类型的R子类;
  • :是不带扩展名的资源文件名。

举例:@color/opaque_red、@string/hello

如要引用系统资源,则您需要加入包名称。例如:android:textColor="@android:color/secondary_text_dark"

由于系统资源分为public和非public,public的声明是在 \platforms\android-版本号\data\res\values\public.xml,而 @*代表引用系统的非public资源。

格式:@*android:/,可以调用系统定义的所有资源,

而上面的@android:/,则只能够调用public属性的资源。
例如将 Android 提供的布局资源用于 ListAdapter 中的列表项:setListAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, myarray));,其中,simple_list_item_1是平台为 ListView 中的项目所定义的布局资源,即可以使用该资源,而不必自行创建列表项布局。

2.3 引用样式属性-?

样式属性资源允许你在当前应用的主题中引用属性的值。 引用样式属性,可以通过对UI元素进行样式设置以匹配当前主题提供的标准变体来自定义UI元素的外观,而不是提供硬编码的值(即具体的值)。 引用样式属性本质上说:“在当前主题中使用此属性定义的样式。”

格式:?[:][/]

举例1,在xml文件中引用主题属性:

在以上代码中,是将android:textColor属性指定为当前主题背景中某个样式属性的名称,即将android:textColorSecondary样式属性的值用作此控件textColor的值。

显示声明的格式为: ?android:attr/textColorSecondary,但是这里无须显示声明。

举例2,在style文件中引用主题属性:

2.4 访问原始文件

若我们要访问原始文件,则不应该将文件放于res/目录下,因为从res/读取资源的唯一方法是使用资源 ID,因此,我们可以将资源保存在assets/目录中。

而访问的方式则需要利用AssetManager读取原始数据。如下所示

StringBuilder stringBuilder = new StringBuilder();try {    AssetManager assetManager = context.getAssets();    BufferedReader bf = new BufferedReader(new InputStreamReader(                    assetManager.open(file.json)));    String line;    while ((line = bf.readLine()) != null) {        stringBuilder.append(line);    }} catch (IOException e) {    e.printStackTrace();}

但若是只需要读取原始数据的能力,例如读取视频文件或音频文件,则可将文件保存在res/raw/目录中,并利用openRawResource()读取字节流。如:mMediaPlayer = MediaPlayer.create(this, R.raw.song);

2.5 用 @+ 创建或引用资源

通过上面讲解可以知道@是引用的意思,那么+呢?+表示在R.java中名为type的内部类中添加一条记录。举个例子:android:id="@+id/submit_btn"表示新建一个名为submit_btn资源id。上面的例子就是最常见的用法,即定于控件id。

@+id/ID名称:表示新建一个资源ID;

@id/ID名称:引用已定义的资源ID,包括系统ID;

@android:id/ID名称:引用系统ID,其等效于@+id/ID名称

3 根据资源名称获取资源ID

如何根据文件名来得到资源ID,这就要借助Resources的getIdentifier方法了。如下代码所示:

Resources res = getResources();final String packageName = getPackageName();//方法1 测试1int imageResId = res.getIdentifier("ic_launcher", "mipmap", packageName);//方法2 测试1int imageResId2 = res.getIdentifier(packageName + ":mipmap/ic_launcher", null, null);//测试2int musicResId=res.getIdentifier("song", "raw", packageName);//测试3int notFoundResId=res.getIdentifier("activity_main", "drawable", packageName);Log.d("TAG", "imageResId: " + imageResId        + ";imageResId2: " + imageResId2        + ";musicResId: " + musicResId        + ";notFoundResId: " + notFoundResId);

运行结果:

imageResId: 2131361792;imageResId2: 2131361792;musicResId: 2131427328;notFoundResId: 0

看看源码中getIdentifier方法实现:

/** * Return a resource identifier for the given resource name.  A fully * qualified resource name is of the form "package:type/entry".  The first * two components (package and type) are optional if defType and * defPackage, respectively, are specified here. *  * 

Note: use of this function is discouraged. It is much more * efficient to retrieve resources by identifier than by name. * * @param name The name of the desired resource. * @param defType Optional default resource type to find, if "type/" is * not included in the name. Can be null to require an * explicit type. * @param defPackage Optional default package to find, if "package:" is * not included in the name. Can be null to require an * explicit package. * * @return int The associated resource identifier. Returns 0 if no such * resource was found. (0 is not a valid resource ID.) */public int getIdentifier(String name, String defType, String defPackage) { return mResourcesImpl.getIdentifier(name, defType, defPackage);}

注释内容要点如下:

  • 该方法返回给定资源名称的资源标识符(即资源ID);
  • 完整的资源名为package:type/entry,如果资源名这个参数有完整地指定,后面的defType和defPackage可以省略,如上面代码中res.getIdentifier(packageName + ":drawable/ic_launcher", null, null);的形式;
  • 并不提倡使用该方法,因为通过资源ID访问资源效率更高;
  • 如果没有找到资源,则返回0,而0不是一个有效的资源ID。
  • 如代码所示,该方法间接调用了AssetManager.class中的native方法
int getIdentifier(String name, String defType, String defPackage) {    if (name == null) {        throw new NullPointerException("name is null");    }    try {        return Integer.parseInt(name);    } catch (Exception e) {        // Ignore    }    return mAssets.getResourceIdentifier(name, defType, defPackage);}
/** * Retrieve the resource identifier for the given resource name. */ /*package*/ native final int getResourceIdentifier(String type,                                                       String name,                                                       String defPackage);

参考资料:

  1. 访问资源
  2. 应用资源概览
  3. [Android] 关于Android的问号?和@符号的用法
  4. Android根据资源名获取资源ID

更多相关文章

  1. android 属性系统,SystemProperties 的简介
  2. (六)android recovery 升级UI显示之资源文件
  3. android 里面资源应用 Drawable
  4. Android(安卓)Add外部library工程,总是链接失败的解决办法
  5. 自定义 View:用贝塞尔曲线绘制酷炫轮廓背景
  6. Android基于TCP和URL协议的网络编程示例【附demo源码下载】
  7. MVP在Android中的初学之路
  8. 自定义UI框架
  9. 【Android】【学习笔记】运行时资源替换-Runtime Resource Overl

随机推荐

  1. Android(安卓)视频播放
  2. relative相关属性
  3. android 把TextView中的文字添加阴影效果
  4. android 图片 上下左右滑动,能放大放小
  5. android 解决小米手机Android(安卓)Studi
  6. android文件关联之mime type
  7. Android:TextView跑马灯-详解
  8. Android构建工具
  9. 命令行装android
  10. 2011.07.08(5)——— android shortcut