Android开发中的性能调优

本文深入探讨Android应用中图片加载与内存管理的重要性,通过优化图片加载方式和内存使用策略,有效避免内存溢出问题,提升应用性能。重点介绍了如何优先加载缩略图、使用多级图片缓存及LruCache机制,以及如何在退出界面时回收常用图片资源,以减少内存消耗。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android性能优化主要分几个方面

  1. 图片加载
  2. 数据库操作
  3. Http请求
  4. UI优化
  5. 代码好习惯

图片加载

app在加载较大Bitmap的时候经常会包OOM异常,反复改变一个控件的图片或者加载太多图片到内存的时候会报OOM;原因如下,android给每个app开辟的运行内存是固定的,有的是16MB,有的更多,具体根据手机而定,而当大图片被加载到内存之后可能导致内存超过了android系统给定的内存,这时候就报OOM,或者反复加载一个小图片,例如反复调用BitmapFactory.decodeResource()方法加载xml文件,而xml文件里面定义的可能是按钮的点击图片效果,反复的加载也会导致内存溢出;

解决方案:加载大的图片可以优先加载缩略图,网上找的代码;

public class BitmapUtils {
    private static int calculateInSampleSize(BitmapFactory.Options options,
            int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

    // 如果是放大图片,filter决定是否平滑,如果是缩小图片,filter无影响
    private static Bitmap createScaleBitmap(Bitmap src, int dstWidth,
            int dstHeight) {
        Bitmap dst = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false);
        if (src != dst) { // 如果没有缩放,那么不回收
            src.recycle(); // 释放Bitmap的native像素数组
        }
        return dst;
    }

    // 从Resources中加载图片
    public static Bitmap decodeSampledBitmapFromResource(Resources res,
            int resId, int reqWidth, int reqHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options); // 读取图片长款
        options.inSampleSize = calculateInSampleSize(options, reqWidth,
                reqHeight); // 计算inSampleSize
        options.inJustDecodeBounds = false;
        Bitmap src = BitmapFactory.decodeResource(res, resId, options); // 载入一个稍大的缩略图
        return createScaleBitmap(src, reqWidth, reqHeight); // 进一步得到目标大小的缩略图
    }

    // 从sd卡上加载图片
    public static Bitmap decodeSampledBitmapFromFd(String pathName,
            int reqWidth, int reqHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(pathName, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        Bitmap src = BitmapFactory.decodeFile(pathName, options);
        return createScaleBitmap(src, reqWidth, reqHeight);
    }
}

可以把常用的图片(例如按钮点击效果图片等)事先加载到内存中,在退出界面的时候再进行回收,因为这些图片较小,如果反复加载的话上一次加载的图片还在内存中没释放,下一次还加载相同的图片,有可能造成内存溢出,我就遇到过这种情况:我在之前的项目中反复调用BitmapFactory.decodeResource(),然后就OOM了,后来把图片资源事先缓存到内存中就ok了;
采用多级图片缓存,在内存中缓存图片,在sdk卡中缓存图片,一般很多图片加载的三方库都是采用多级缓存,充分利用LruCache这篇博客对于LruCache有一个比较清晰的解释,关于图片的缓存还可以去阅读图片缓存的第三方库的源码,学习它们是如果实现图片的高效的缓存的,比如说:picassoImageLoader,其实可以直接选择第三方库来实现开发中的图片缓存
未完待续。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值