Android:BitmapFactory.decodeStream Bitmap的内存优化OutOfMemory异常以后Crash闪退

本文主要是介绍Android:BitmapFactory.decodeStream Bitmap的内存优化OutOfMemory异常以后Crash闪退,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

自己项目中使用如下方法,有的手机上会奔溃报错,原因是BitmapFactory.decodeStream部分没有使用options参数改变内存大小

改成如下形式后正常了;正确解决方案:设置inSampleSize

一)Android BitmapFactory.decodeStream(is) 解析
在 Android 开发中,我们经常需要加载图片资源来显示在应用界面上。而 BitmapFactory 类中的 decodeStream() 方法是一个常用的方法,用于将一个输入流(InputStream)解码为一个位图(Bitmap)对象。在本文中,我们将介绍 BitmapFactory.decodeStream(is) 方法的使用以及相关的注意事项。

decodeStream() 方法的使用
decodeStream() 方法用于从一个输入流中解码位图。它的常见用法是从网络或本地文件中加载图片资源,并将其显示在 ImageView 或其他支持位图显示的视图中。

以下是 decodeStream() 方法的基本用法:

InputStream is = // 获取输入流
Bitmap bitmap = BitmapFactory.decodeStream(is);
imageView.setImageBitmap(bitmap);

上述代码首先获取一个输入流 is,然后调用 BitmapFactory.decodeStream(is) 方法来解码该输入流,并将返回的位图对象设置到一个 ImageView 控件中。

输入流的来源
在实际应用中,输入流的来源可以是多样的:

从网络加载图片:
URL url = new URL("
InputStream is = url.openStream();

从本地文件加载图片:
File file = new File("path/to/image.jpg");
InputStream is = new FileInputStream(file);

从资源文件中加载图片:
InputStream is = getResources().openRawResource(R.raw.image);

从内容提供器中加载图片:
Uri uri = // 获取内容提供器 Uri
InputStream is = getContentResolver().openInputStream(uri);

无论输入流的来源是什么,只要是一个有效的输入流,都可以作为参数传递给 decodeStream() 方法进行解码。

注意事项
在使用 decodeStream() 方法时,我们需要注意以下几点:

输入流的关闭:在使用完位图后,务必关闭输入流,以释放资源。
InputStream is = // 获取输入流
Bitmap bitmap = BitmapFactory.decodeStream(is);
is.close(); // 关闭输入流

内存管理:位图占用较大的内存,使用完后应及时释放以避免内存泄漏。
bitmap.recycle(); // 释放位图内存

压缩处理:如果图片的分辨率过大,可能会导致内存溢出。我们可以通过调整 BitmapFactory.Options 中的 inSampleSize 字段来进行压缩。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2; // 压缩为原图的 1/2 大小
Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);

异常处理:decodeStream() 方法可能会抛出 OutOfMemoryError 异常,这是因为图片过大导致内存不足。我们应该在使用该方法时进行适当的异常处理。
复制 
try {
    Bitmap bitmap = BitmapFactory.decodeStream(is);
    // 使用位图进行界面显示
} catch (OutOfMemoryError e) {
    // 处理内存不足异常
}
 

二)BitmapFactory.Options这个类简介

BitmapFactory.Options这个类,有一个字段叫做 inJustDecodeBounds 。SDK中对这个成员的说明是这样的:
If set to true, the decoder will return null (no bitmap), but the out…
也就是说,如果我们把它设为true,那么BitmapFactory.decodeFile(String path, Options opt)并不会真的返回一个Bitmap给你,它仅仅会把它的宽,高取回来给你,这样就不会占用太多的内存,也就不会那么频繁的发生OOM了。
示例代码如下:

1. BitmapFactory.Options options = new BitmapFactory.Options();

2. options.inJustDecodeBounds = true;

3. Bitmap bmp = BitmapFactory.decodeFile(path, options);

 

这段代码之后,options.outWidth 和 options.outHeight就是我们想要的宽和高了。

有了宽,高的信息,我们怎样在图片不变形的情况下获取到图片指定大小的缩略图呢?
比如我们需要在图片不变形的前提下得到宽度为200的缩略图。
那么我们需要先计算一下缩放之后,图片的高度是多少 

1. int height = options.outHeight * 200 / options.outWidth;

2. options.outWidth = 200;

3. options.outHeight = height; 

4. options.inJustDecodeBounds = false;

5. Bitmap bmp = BitmapFactory.decodeFile(path, options);

6. image.setImageBitmap(bmp);

 

这样虽然我们可以得到我们期望大小的ImageView
但是在执行BitmapFactory.decodeFile(path, options);时,并没有节约内存。要想节约内存,还需要用到BitmapFactory.Options这个类里的 inSampleSize 这个成员变量。
我们可以根据图片实际的宽高和我们期望的宽高来计算得到这个值。

1. inSampleSize = options.outWidth / 200;

另外,为了节约内存我们还可以使用下面的几个字段:

1. options.inPreferredConfig = Bitmap.Config.ARGB_4444;// 默认是Bitmap.Config.ARGB_8888

2. options.inPurgeable = true;

3. options.inInputShareable = true;

这篇关于Android:BitmapFactory.decodeStream Bitmap的内存优化OutOfMemory异常以后Crash闪退的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/763101

相关文章

Python内存管理机制之垃圾回收与引用计数操作全过程

《Python内存管理机制之垃圾回收与引用计数操作全过程》SQLAlchemy是Python中最流行的ORM(对象关系映射)框架之一,它提供了高效且灵活的数据库操作方式,本文将介绍如何使用SQLAlc... 目录安装核心概念连接数据库定义数据模型创建数据库表基本CRUD操作创建数据读取数据更新数据删除数据查

Python异常处理之避免try-except滥用的3个核心原则

《Python异常处理之避免try-except滥用的3个核心原则》在Python开发中,异常处理是保证程序健壮性的关键机制,本文结合真实案例与Python核心机制,提炼出避免异常滥用的三大原则,有需... 目录一、精准打击:只捕获可预见的异常类型1.1 通用异常捕获的陷阱1.2 精准捕获的实践方案1.3

Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧

《Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧》本文将通过实际代码示例,深入讲解Python函数的基本用法、返回值特性、全局变量修改以及异常处理技巧,感兴趣的朋友跟随小编一起看看... 目录一、python函数定义与调用1.1 基本函数定义1.2 函数调用二、函数返回值详解2.1 有返

k8s容器放开锁内存限制问题

《k8s容器放开锁内存限制问题》nccl-test容器运行mpirun时因NCCL_BUFFSIZE过大导致OOM,需通过修改docker服务配置文件,将LimitMEMLOCK设为infinity并... 目录问题问题确认放开容器max locked memory限制总结参考:https://Access

Docker多阶段镜像构建与缓存利用性能优化实践指南

《Docker多阶段镜像构建与缓存利用性能优化实践指南》这篇文章将从原理层面深入解析Docker多阶段构建与缓存机制,结合实际项目示例,说明如何有效利用构建缓存,组织镜像层次,最大化提升构建速度并减少... 目录一、技术背景与应用场景二、核心原理深入分析三、关键 dockerfile 解读3.1 Docke

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

在Android中使用WebView在线查看PDF文件的方法示例

《在Android中使用WebView在线查看PDF文件的方法示例》在Android应用开发中,有时我们需要在客户端展示PDF文件,以便用户可以阅读或交互,:本文主要介绍在Android中使用We... 目录简介:1. WebView组件介绍2. 在androidManifest.XML中添加Interne

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

Debian 13升级后网络转发等功能异常怎么办? 并非错误而是管理机制变更

《Debian13升级后网络转发等功能异常怎么办?并非错误而是管理机制变更》很多朋友反馈,更新到Debian13后网络转发等功能异常,这并非BUG而是Debian13Trixie调整... 日前 Debian 13 Trixie 发布后已经有众多网友升级到新版本,只不过升级后发现某些功能存在异常,例如网络转