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);