Android应用Screen10页面调用setImageURI设置图片URI时崩溃求助
问题根因
- URI临时访问权限丢失:从图库获取的内容URI(
content://开头)默认只给当前接收的Activity(即Screen7)授予临时读取权限,你直接将Uri通过Parcelable传递给Screen10时未同步传递权限,导致Screen10无权限访问对应图片资源,调用setImageURI时触发异常崩溃。 - setImageURI无异常容错:
ImageView.setImageURI是同步加载逻辑,没有内置异常捕获能力,遇到Uri无效、权限不足、图片过大等场景都会直接抛出异常导致崩溃。 - 权限申请不合理:你申请的
MANAGE_EXTERNAL_STORAGE是面向文件管理器类应用的特殊权限,普通场景无需申请,且该权限需要用户手动主动授权,未授权时也会无法访问外部存储图片。
解决方案
1. 传递URI时附带临时权限
在Adapter跳转Screen10的逻辑中,给Intent添加读取Uri的临时权限标识,将权限同步传递给Screen10:
holder.imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent myIntent=new Intent(c,Screen_10.class); Ad ad=values.get(holder.getAdapterPosition()); myIntent.putExtra("viewClass",ad); // 新增如下权限标识 myIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); c.startActivity(myIntent); } });
2. 优化图片加载逻辑
推荐使用Glide、Picasso等专业图片加载库,自带异步加载、权限适配、异常容错能力,以Glide为例:
首先在模块级build.gradle引入依赖:
implementation 'com.github.bumptech.glide:glide:4.16.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
替换Screen10中的图片加载逻辑:
// 替换原有upload_image.setImageURI(im);逻辑 Glide.with(Screen_10.this) .load(im) .error(R.drawable.ic_default_placeholder) // 加载失败时显示的默认占位图 .into(upload_image);
如果不想引入第三方库,至少给setImageURI增加异常捕获:
try { upload_image.setImageURI(im); } catch (Exception e) { e.printStackTrace(); // 加载异常时设置默认图,避免崩溃 upload_image.setImageResource(R.drawable.ic_default_placeholder); }
3. 权限适配优化
根据targetSdkVersion调整权限申请逻辑,不要使用MANAGE_EXTERNAL_STORAGE:
- targetSdk >= 33:申请
READ_MEDIA_IMAGES权限即可访问图库图片 - 29 <= targetSdk <=32:申请
READ_EXTERNAL_STORAGE权限即可
内容的提问来源于stack exchange,提问作者Hamza Malik
相关产品推荐
相关产品推荐

