考虑以下代码:
protected String getStringResourceByName(String aString) {
String r = null;
if (aString != null) {
String packageName = getPackageName();
int resId = getResources().getIdentifier(aString, "string", packageName);
if (resId == 0) {
r = aString;
} else {
r = getString(resId);
}
}
return r;
}
public void btnOnClick(View view) {
String txt = getStringResourceByName("notexists");
Log.d("test", "notexists: "+txt);
txt = getStringResourceByName("app_name");
Log.d("test", "app_name: "+txt);
txt = getStringResourceByName("12345");
Log.d("test", "12345:"+ txt);
}
输出:
2019-11-14 15:28:59.462 19822-19822/nl.tbwb.rnd.bixolontest D/test: notexists: notexists
2019-11-14 15:28:59.463 19822-19822/nl.tbwb.rnd.bixolontest D/test: app_name: My App Name
...
Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x3039
(0x3039是12345的十六进制)
这会在最后一次调用getStringResourceByName()
时崩溃,因为getResources().getIdentifier()
将12345
作为资源ID返回,而资源ID并不存在。
文档中没有提到任何异常。我做错了什么吗?
更新我知道标识符不能以数字开头,但是当使用12345A
作为标识符时,它确实有效。
发布于 2019-11-14 14:54:00
在检查了内部类之后,我发现了一些有趣的东西。
ResourcesImpl.java (内包android.content.res
)
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);
}
在此方法中,它首先尝试将名称解析为Integer,如果它是Integer,则只返回值。但如果没有,那就在路上再检查一下。
当您传递一个整数(它无论如何都不是一个有效的资源名称)时,它只返回值。但是这个资源实际上根本不存在!还有砰!这就是为什么坠机。
https://stackoverflow.com/questions/58859215
复制相似问题