欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2022-04-12 12:35:03
接触过android开发的同学们都知道在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);