动态加载 id 和对应用程序进行签名时不显示可绘制对象



>上下文

列表视图中的每个项目都会加载一个图像。给定项目的数据,返回资源的 id(可绘制对象)。此 id 用于图像视图的 setResourceId。

问题

当apk被签名时,不会显示任何内容(但是不会发生错误)。

测试

确保加载资源的正确 ID。创建了一个项目,其匹配资源是R.drawable.banana,记录了函数返回的id以及值R.drawable.banana(如下所示)。

int id = CropDataHelper.getCropsDrawable(myContext, txt);
Log.i("image id:"+id,"found id Fragment View Cycles");
Log.i("raw draw:"+R.drawable.banana,"drawable Fragment View Cycles");

记录的值相同,因此返回正确的 id。

进一步测试显示

如果直接使用资源,则显示 R.drawable.example 图像,即使函数返回相同的值也是如此。

id = R.drawable.banana;
...
iv.setImageResource(id);

以前的失败尝试

  • 将资源放入不同的文件夹(无 dpi 等)

文件夹尝试参考。但是,由于图像确实显示我是否使用 直接R 引用这是一个毫无根据的尝试。

  • 使用可绘制资源

使用获得的id直接加载可绘制对象并进行设置。

Drawable d = ContextCompat.getDrawable(myContext,id);
...
iv.setImageDrawable(d);

实际代码片段

int id = CropDataHelper.getCropsDrawable(myContext, txt);
Log.i("image id:"+id,"found id Fragment View Cycles");
Log.i("raw draw:"+R.drawable.banana,"drawable Fragment View Cycles");
//              id = R.drawable.banana; - testing use of direct resource
//              Drawable d = ContextCompat.getDrawable(myContext,id); drawable attempt
ImageView iv = ((ImageView) row.findViewById(R.id.icon_purchaseType));
if (id != -1) {
iv.setImageResource(id);
//                  iv.setImageDrawable(d); - drawable attempt
}

结语

调试时不会出现问题,仅在已签名的apk上发生,这使我相信R.drawable.example在已签名的apk上解锁了一些底层权限,但是当尝试直接使用该id时,这些权限不会解锁。任何帮助不胜感激,谢谢。

解决方法

字符串名称到R的 ID 的哈希映射

推理

尝试读取文件时似乎可能存在一些不可用的权限(仅在签名中发生 - 即使这些是应用程序图像)。为了解决此问题,不使用 json 文件按名称加载图像文件,而是使用字符串创建哈希映射以匹配R的 id。

示例代码

//create hashmap
private HashMap<String,Integer> resources;
//fill hash map with resources
resources.put("FIRST",R.drawable.example_img_1);
resources.put("SECOND",R.drawable.example_img_2);
//simple method to access resources
public Integer getResourceId(String key){
if(resources.containsKey(key))
return resources.get(key);
return R.drawable.default_image;
}

最新更新