Android - getResources().getIdentifier 替换

Dar*_*ony 6 android

在 android 中,我循环遍历数据库并分配文本和图像:

Cursor res = myDb.getAllData();

while (res.moveToNext()) {
    Actors actor = new Actors();
    actor.setName(res.getString(1));

    String th =  res.getString(11);
    Integer thumb = this.getResources().getIdentifier(th, "drawable", "mypackage");

    actor.setThumb(R.drawable.th);
}
Run Code Online (Sandbox Code Playgroud)

然而,Lint 建议不要使用 getIdentifier - 不鼓励使用此函数,因为资源反射会使执行代码的构建优化和编译时验证变得更加困难。

在数据库列中,我只有图像名称(字符串)。如何替换 getIdentifier?

即使我将 DB 列直接更改为R.drawable.imagename,它仍然是一个字符串,因为setThumb我需要一个可绘制对象。

Dar*_*ony 0

好的,所以我找到的唯一解决方案是在这里/sf/answers/309980191/

public static int getResId(String resName, Class<?> c) {

        try {
            Field idField = c.getDeclaredField(resName);
            return idField.getInt(idField);
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        } 
    }
Run Code Online (Sandbox Code Playgroud)

然后只需调用:

int resID = getResId("icon", R.drawable.class);
Run Code Online (Sandbox Code Playgroud)

这非常有效,但是一些用户报告说,从 Play 商店安装应用程序(不是我的应用程序,而是任何实现了此方法并启用了 proguard 的应用程序)后,一段时间后它将开始抛出NoSuchFieldException,因为更多的资源被映射到相同的资源类/领域。

它可能是由 proguard 引起的,但不确定。解决方案是将旧方法放在getResources().getIdentifier代码的异常部分。

  • 但这使用了直接反射,因此它比您原来的解决方案更加黑客。 (6认同)