Android中实现根据资源名获取资源ID

接触过Android开发的同学们都知道在Android中访问程序资源基本都是通过资源ID来访问。这样开发起来很简单,并且可以不去考虑各种分辨率,语言等不同资源显式指定。

痛点

但是,有时候也会有一些问题,比如我们根据服务器端的值取图片,但是服务器端绝对不会返回给我们的是资源id,最多是一种和文件名相关联的值,操作资源少的时候,可以维护一个容器进行值与资源ID的映射,但是多的话,就需要另想办法了。

便捷的方法

在这种情况下,使用文件名来得到资源ID显得事半功倍。 通过调用Resources的getIdentifier可以很轻松地得到资源ID。 几个简单的示例:

代码如下:

Resources res = getResources();
final String packageName = getPackageName();
int imageResId = res.getIdentifier("ic_launcher", "drawable", packageName);
int imageResIdByAnotherForm = res.getIdentifier(packageName + ":drawable/ic_launcher", null, null);
 
int musicResId = res.getIdentifier("test", "raw", packageName);
     
int notFoundResId = res.getIdentifier("activity_main", "drawable", packageName);

Log.i(LOGTAG, "testGetResourceIds imageResId = " + imageResId
              + ";imageResIdByAnotherForm = " + imageResIdByAnotherForm
              + ";musicResId=" + musicResId
              + ";notFoundResId =" + notFoundResId);

运行结果

代码如下:

I/MainActivity( 4537): testGetResourceIds imageResId = 2130837504;imageResIdByAnotherForm = 2130837504;musicResId=2130968576;notFoundResId =0

看一看API

直接API

1.这个方法用来使用资源名来获取资源ID
2.完整的资源名为package:type/entry,如果资源名这个参数有完整地指定,后面的defType和defPackage可以省略。
3.defType和defPackage省略时,需要将其设置成null
4.注意这个方法不提倡,因为直接通过资源ID访问资源会更加效率高
5.如果资源没有找到,返回0,在Android资源ID中0不是合法的资源ID。

代码如下:

**
     * 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.
     *
     * <p>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) {
        try {
            return Integer.parseInt(name);
        } catch (Exception e) {
            // Ignore
        }
        return mAssets.getResourceIdentifier(name, defType, defPackage);
    }

间接API

实际上上述API调用的是AssetManager.class中的native方法。

代码如下:

/**
     * Retrieve the resource identifier for the given resource name.
     */
    /*package*/ native final int getResourceIdentifier(String type,
                                                       String name,
                                                       String defPackage);

(0)

相关推荐

  • 解析Android资源文件及他们的读取方法详解

    Sam在Android开发中,有两种处理资源文件的方式.其一,是将所有资源文件以及JNI程序放置于一个单独的资源包.使用到他们时,使用文件方式读取.或者直接使用C++层代码读取. 其二,则是将资源文件加入到APK内部.使用各种不同的办法去得到其内容.方法一:适合于移植较大的C++程序时使用,因为C++代码数量众多,不太可能修改为JAVA代码.所以将其与资源文件以一定方式存放,并让他们自称体系是个好办法.但这造成软件的发布必须以APK+资源包的方式发布.方法二:则比较适合代码量不是非常大,且资源数

  • Android字符串资源文件format方法使用实例

    很多时候我们感性Google在设计Android时遵守了大量MVC架构方式,可以让写公共代码.美工和具体逻辑开发人员独立出来.有关Android 的资源文件values/strings.xml中如何实现格式化字符串呢? 这里Android123举个简单的例子,以及最终可能会用到哪些地方. 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?> <resources> <string name=

  • Android中加载网络资源时的优化可使用(线程+缓存)解决

    网上关于这个方面的文章也不少,基本的思路是线程+缓存来解决.下面提出一些优化: 1.采用线程池 2.内存缓存+文件缓存 3.内存缓存中网上很多是采用SoftReference来防止堆溢出,这儿严格限制只能使用最大JVM内存的1/4 4.对下载的图片进行按比例缩放,以减少内存的消耗 具体的代码里面说明.先放上内存缓存类的代码MemoryCache.java: 复制代码 代码如下: <SPAN style="FONT-SIZE: 18px"><STRONG>publ

  • Android 原始资源文件的使用详解

    背景知识介绍与其他平台的应用程序一样,Android中的应用程序也会使用各种资源,比如图片,字串等,会把它们放入源码的相应文件夹下面,如/res/drawable, /res/xml, /res/values/, /res/raw, /res/layout和/assets.Android也支持并鼓励开发者把UI相关的布局和元素,用XML资源来实现.总结起来,Android中支持的资源有:•颜色值                 /res/values               以resourc

  • android开发教程之系统资源的使用方法 android资源文件

    一.颜色资源1.颜色XML文件格式 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?><resources> //resources根元素   <color name="" >#000000</color>//color子元素</resouces> 2.引用格式: java代码中:R.color.color_name  (这是一个int型的

  • 在Android开发中替换资源图片不起作用的解决方法

    现象 在android开发中,经常会需要替换res\drawable中的图片,打开res\layout下的文件预览布局页面发现图片已经被替换,但在模拟器或者真实机器上运行时发现该图片并没有被替换,还是使用的是原来的资源图片. 原因 在开发过程中,由于使用模拟器测试了程序,在首次运行后会将res文件夹下的图片资源文件(如drawable-hdpi.drawable-ldpi和drawable-mdpi)拷贝到bin文件夹下.在替换资源图片后,eclipse并不清楚是否有图片改变,所以会使用原来bi

  • Android 资源 id详解及的动态获取

    Android 资源 id详解 我们平时获取资源是通过 findViewById 方法进行的,比如我们常在onCreate方法中使用这样的语句: btnChecked=(ImageView)findViewById(R.id.imgCheck); findViewById是我们获取layout中各种View 对象比如按钮.标签.ListView和ImageView的便利方法.顾名思义,它需要一个int参数:资源id. 资源id非常有用.Android回自动为每个位于res目录下的资源分配id,包

  • android图像绘制(六)获取本地图片或拍照图片等图片资源

    从SD卡中获取图片资源,或者拍一张新的图片. 先贴代码 获取图片: 注释:拍照获取的话,可以指定图片的保存地址,在此不说明. 复制代码 代码如下: CharSequence[] items = {"相册", "相机"}; new AlertDialog.Builder(this) .setTitle("选择图片来源") .setItems(items, new OnClickListener() { public void onClick(Dia

  • Android 往Framework中添加新资源的方法详解

    有时候我们想在标准的Framework中添加自己的新的资源怎么办呢?办法就是我们来尝试下.通过Eclipse的联系,我们可以联想到是否就是简单的把字符串放在res的各个文件夹里面.先来试试看,编译,系统立即报错.为什么呢?它提示你利用make update-api这个命令来更新public.xml文件或者把这个声明称hide类型.这个肯定不是我们想要的.所以方法有二:方法1:正常添加完资源后,执行make update-api函数.系统更新res/values/public.xml文件.方法2:

  • Android中主要资源文件及文件夹介绍

    在Android项目文件夹里面,主要的资源文件是放在res文件夹里面的 1:assets文件夹是存放不进行编译加工的原生文件,即该文件夹里面的文件不会像xml,java文件被预编译,可以存放一些图片,html,js, css等文件. 2:res文件夹里面的多个文件夹的各自介绍 res/anim/ XML文件,它们被编译进逐帧动画(frame by frame animation)或补间动画(tweened animation)对象 res/drawable/ .png..9.png..jpg文件

  • 基于将Android工程做成jar包和资源文件的解决方法

    需要特别注意的是,以jar包和资源包方式提供给第三方开发者,我们的工程的代码中就不能使用类似于R.layout.main.R.string.name等等这样的方式来引用资源了. 为此,我们就不能直接使用R文件,而是要通过字段名称来动态的获取资源的id,再来使用. 以下封装了一个类,可以通过字段名称动态获取id. 复制代码 代码如下: package com.arui.util; import android.content.Context; public class ResourceUtil {

随机推荐