如何最小改动修改Android代码以消除getIdentifier使用警告?
解决Android中getIdentifier引发的资源检索警告问题
原代码
public Bitmap loadIMG(Context context) { File pfile = getIMGPathFile(context); Bitmap bitmap = null; if (pfile.exists()) { try { //noinspection IOStreamConstructor bitmap = BitmapFactory.decodeStream(new FileInputStream(pfile)); } catch (Exception e) { e.printStackTrace(); } } else { @SuppressLint("DefaultLocale") String from = String.format(FILE_PROD_PREFIX + Consts.FILE_NUMERIC_FORMAT, mId); bitmap = BitmapFactory.decodeResource(context.getResources(), context.getResources().getIdentifier(from, "drawable", context.getPackageName())); } return bitmap; }
触发的警告
Use of this function is discouraged because resource reflection makes
it harder to perform build optimizations and compile-time verification
of code. It is much more efficient to retrieve resources by identifier
(e.g.R.foo.bar) than by name (e.g.getIdentifier("bar", "foo", null)).
优化方案(最小副作用)
警告核心是getIdentifier依赖反射,导致编译期无法校验资源、运行性能偏低。以下两种方案可在最小改动前提下消除警告:
方案1:哈希映射表(推荐,适配多资源场景)
提前建立mId与drawable资源ID的静态映射,彻底规避反射:
// 类内定义静态映射表,初始化时填充所有mId对应的资源关系 private static final Map<Integer, Integer> ID_TO_DRAWABLE_MAP = new HashMap<>(); static { // 示例:mId=1对应prod_001,mId=2对应prod_002 ID_TO_DRAWABLE_MAP.put(1, R.drawable.prod_001); ID_TO_DRAWABLE_MAP.put(2, R.drawable.prod_002); // 补充其他mId对应的资源ID } public Bitmap loadIMG(Context context) { File pfile = getIMGPathFile(context); Bitmap bitmap = null; if (pfile.exists()) { // 优化:用try-with-resources自动关闭流,避免资源泄漏 try (FileInputStream fis = new FileInputStream(pfile)) { bitmap = BitmapFactory.decodeStream(fis); } catch (Exception e) { e.printStackTrace(); } } else { Integer drawableResId = ID_TO_DRAWABLE_MAP.get(mId); if (drawableResId != null) { bitmap = BitmapFactory.decodeResource(context.getResources(), drawableResId); } else { // 可选:处理无匹配资源的情况,加载默认图 bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.default_product); } } return bitmap; }
方案2:switch-case(适配少量资源场景)
直接通过switch匹配mId,返回对应资源ID:
public Bitmap loadIMG(Context context) { File pfile = getIMGPathFile(context); Bitmap bitmap = null; if (pfile.exists()) { try (FileInputStream fis = new FileInputStream(pfile)) { bitmap = BitmapFactory.decodeStream(fis); } catch (Exception e) { e.printStackTrace(); } } else { int drawableResId; switch(mId) { case 1: drawableResId = R.drawable.prod_001; break; case 2: drawableResId = R.drawable.prod_002; break; // 补充其他mId的匹配分支 default: drawableResId = R.drawable.default_product; break; } bitmap = BitmapFactory.decodeResource(context.getResources(), drawableResId); } return bitmap; }
额外优化点
- 原代码中
FileInputStream未手动关闭,改用try-with-resources语法可自动释放资源,避免内存泄漏 - 若
minSdkVersion >=24,可移除@SuppressLint("DefaultLocale"),改用String.format(Locale.getDefault(), ...)保证多语言环境下的格式化正确性
内容的提问来源于stack exchange,提问作者Chris972
相关产品推荐
相关产品推荐

