Android经典面试题之图片Bitmap怎么做优化

简介: 本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点

图片相关的内存优化

图片相关的优化主要涉及几个方面:分辨率的适配、图片的压缩、图片的缓存

分辨率的适配

分辨率的适配主是针对我们放在drawable目录下的图片资源,目录和对应的手机分辨率可以看下图

DPI、分辨率和drawable目录

所以我们需要不同分辨率的图片来放在对应的目录下来做适配,否则Android系统可能会将我们的图片拉伸导致变形。

或者直接使用svg图也是一个很好的选项。

图片的压缩

图片的压缩是指我们需要根据View所实际需要的图片尺寸来加载对应大小的图片。一般我们用的图片加载第三方库,比如Glide,都已经帮我们做了处理。所以这里的图片压缩我们只需要在我们自己处理图片的时候需要考虑。

图片压缩说起来也不复杂,主要是用到了BitmapFactory的Options,一般都分为如下几个步骤:

(1)先把inJustDecodeBounds设置为true,以便后面回去图片的实际大小

//先把inJustDecodeBounds设置为true,以便后面回去图片的实际大小
BitmapFactory.Options options = new BitmapFactory.Options();
//先解析图片的宽高信息,inJustDecodeBounds为true就只会加载图片的尺寸信息
options.inJustDecodeBounds = true;

(2)然后压缩图片

//Resources res, int resId
BitmapFactory.decodeResource(res, resId, options);

(3)计算压缩的比例,inSampleSize参数表示采样,会对图片的宽高进行缩放

//这里reqWidth和reqHeight表示实际需要的宽高
private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
   
    final int height = options.outHeight;
    final int width = options.outWidth;
    int sampleSize = 1;

    if (height > reqHeight || width > reqWidth) {
   
        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        while ((halfHeight / sampleSize) >= reqHeight && (halfWidth / sampleSize) >= reqWidth) {
   
            sampleSize *= 2;
        }
    }

    return sampleSize;
}

//设置inSampleSize参数
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

(4)将inJustDecodeBounds设置为false,加载图片数据

options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);

完整代码:

public static Bitmap decodeBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
   

    BitmapFactory.Options options = new BitmapFactory.Options();
    //先解析图片的宽高信息
    options.inJustDecodeBounds = true;

    BitmapFactory.decodeResource(res, resId, options);

    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    //加载压缩后的图片
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);

}

图片的缓存

同样的,一般我们加载图片都用的是第三方库,比如著名的Glide,图片缓存的事儿它已经帮我们做得很好了,所以我们不需要考虑缓存的事儿。但是我们还是要大致了解怎么样实现一个图片的缓存功能,以便不时之需。

实现缓存的话常用的就是LRU算法,具体的可以查看LinkedHashMap的源码分析和Glide的内存缓存思路。

这里简单介绍下Glide的内存缓存思路。内存缓存的作用就是对于内存中已经加载的图片避免重复加载。

(1)首先Glide内存缓存采用了2种策略,弱引用缓存和LRU算法内存缓存

(2)弱引用缓存就是把图片的弱引用缓存在一个HashMap中,被下载使用的图片首先会缓存在这个弱引用HashMap中。Glide会通过引用计数的方式来记录图片被引用的次数,当引用次数为0时,也就意味着图片资源不再被使用嘛,这时就会将图片资源从这个弱引用缓存中移除,并把这个图片资源加入到LRU算法内存缓存中

(3)LRU算法内存缓存的原理就是将图片资源用强引用的方式存储在LinkedHashMap中,当达到容量限制时移除最近最少使用的资源。Glide会在LRU缓存中的图片被重新使用时将图片资源从LRU缓存中删除,并添加到弱引用的缓存中去。这样做的原因就是防止图片被LRU算法缓存回收。

核心就是思考使用图片的每一个环节,用最低的开销来满足功能需求


欢迎关注我的公众号AntDream查看更多精彩文章!

目录
相关文章
|
1天前
|
Android开发 Kotlin
Android经典面试题之Kotlin的==和===有什么区别?
本文介绍了 Kotlin 中 `==` 和 `===` 操作符的区别:`==` 用于比较值是否相等,而 `===` 用于检查对象身份。对于基本类型,两者行为相似;对于对象引用,`==` 比较值相等性,`===` 检查引用是否指向同一实例。此外,还列举了其他常用比较操作符及其应用场景。
149 92
|
13天前
|
SQL 关系型数据库 MySQL
面试官:limit 100w,10为什么慢?如何优化?
面试官:limit 100w,10为什么慢?如何优化?
61 2
面试官:limit 100w,10为什么慢?如何优化?
|
6天前
|
Java Android开发 UED
安卓应用开发中的内存管理优化技巧
在安卓开发的广阔天地里,内存管理是一块让开发者既爱又恨的领域。它如同一位严苛的考官,时刻考验着开发者的智慧与耐心。然而,只要我们掌握了正确的优化技巧,就能够驯服这位考官,让我们的应用在性能和用户体验上更上一层楼。本文将带你走进内存管理的迷宫,用通俗易懂的语言解读那些看似复杂的优化策略,让你的开发之路更加顺畅。
14 2
|
7天前
|
Java Android开发 开发者
安卓应用开发中的线程管理优化技巧
【9月更文挑战第10天】在安卓开发的海洋里,线程管理犹如航行的风帆,掌握好它,能让应用乘风破浪,反之则可能遭遇性能的暗礁。本文将通过浅显易懂的语言和生动的比喻,带你探索如何优雅地处理安卓中的线程问题,从基础的线程创建到高级的线程池运用,让你的应用运行更加流畅。
|
4天前
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
16 0
|
4月前
|
XML Android开发 数据格式
[Android]Bitmap Drawable
[Android]Bitmap Drawable
48 0
|
Android开发
安卓根据需要压缩图片大小bitmap,drawable
安卓根据需要压缩图片大小bitmap,drawable
130 0
|
XML 存储 缓存
安卓 Bitmap 和 Drawable 的使用
Bitmap 的使用 高效加载大位图 解码大的 bitmap,然后加载一个较小的图片到内存中去,从而避免超出程序的内存限制。
241 0
 安卓 Bitmap 和 Drawable 的使用
|
Android开发
Android笔记:根据图片url获取bitmap或者drawable,然后再进行压缩处理
Android笔记:根据图片url获取bitmap或者drawable,然后再进行压缩处理
465 0