Android:如何将ImageView图片保存到SharedPreferences并读取?
核心适配前提
SharedPreferences为轻量键值对存储组件,仅支持基础数据类型、字符串/字符串集合写入,无法直接存储Uri、Bitmap这类自定义对象,且SP的全量内容会在App启动时一次性加载到内存,不建议存储体积过大的内容。
注意:SP存储图片的方案仅适合小尺寸展示类资源(如用户头像),如果是大尺寸照片,建议将图片存在应用私有目录,SP仅保存对应文件路径即可,不要把高清图转Base64存入SP,否则会拖慢App启动速度,甚至触发ANR。
结合现有onActivityResult代码的补充逻辑
- 统一图片格式转换流程:现有代码在选图、拍照分支拿到的图片源(相册的Uri、相机返回的Bitmap),需要先统一解码为Bitmap对象,按对应ImageView的实际展示尺寸做采样压缩,避免大图带来OOM和SP内存占用过高问题
- 增加序列化转换步骤:将压缩后的Bitmap转成Base64编码字符串,这是SP兼容支持的可存储格式
- 补充写入逻辑:在每个图片获取分支(相册选主图、拍照取主图、相册选次图、拍照取次图),拿到转换后的Base64字符串后,调用SharedPreferences的Editor接口,通过
putString()将值绑定到提前定义的固定存储键上,使用apply()异步提交写入,避免主线程阻塞
复用场景的补充逻辑
- 新增页面初始化时的读取流程:在页面
onCreate、配置变更重建时,提前从SP中读取对应键存储的Base64字符串,将字符串解码为Bitmap后直接设置给对应ImageView,无需用户重新选图即可实现上次保存的图片展示
现有代码的待修正风险点
- 原有相机分支的空指针风险:部分厂商相机应用不会在返回Intent的extra中携带缩略图Bitmap,直接调用
data.getExtras().get("data")会触发空指针,需要增加非空判断 - 原有相册分支的权限适配:Android 13及以上系统需要申请
READ_MEDIA_IMAGES运行时权限,否则读取相册Uri会抛出异常无法展示图片 - 原代码直接调用
imageView.setImageURI()的性能问题:主线程做图片解码容易造成卡顿,建议统一走压缩后的Bitmap解码流程
参考工具代码片段
// Bitmap转压缩Base64 public String bitmapToBase64(Bitmap targetBmp, int reqWidth, int reqHeight) { Bitmap scaledBmp = Bitmap.createScaledBitmap(targetBmp, reqWidth, reqHeight, true); ByteArrayOutputStream baos = new ByteArrayOutputStream(); scaledBmp.compress(Bitmap.CompressFormat.JPEG, 50, baos); return Base64.encodeToString(baos.toByteArray(), Base64.NO_WRAP); } // Base64解码为Bitmap public Bitmap base64ToBitmap(String base64Str) { byte[] bytes = Base64.decode(base64Str, Base64.NO_WRAP); return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); }
内容的提问来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

