• 【Android开发坑系列】之经常被忽略的背景图片内存泄露


    我们平时设置图片的时候,几乎都忘记回收老的(背景)图片,比如:

    • TextView.setBackgroundDrawable()
    • TextView.setBackgroundResource()
    • ImageView.setImageDrawable()
    • ImageView.setImageResource()
    • ImageView.setImageBitmap()

    这样造成内存浪费,积少成多,整个软件可能浪费不少内存。

    如果记得优化,整个软件的内存占用会有10%~20%的下降。

    // 获得ImageView当前显示的图片
    Bitmap bitmap1 = ((BitmapDrawable) imageView.getBackground()).getBitmap();
    Bitmap bitmap2 = Bitmap.createBitmap(bitmap1, 0, 0, bitmap1.getWidth(),bitmap1.getHeight(), matrix, true);
    // 设置新的背景图片
    imageView.setBackgroundDrawable(new BitmapDrawable(bitmap2));
    // bitmap1确认即将不再使用,强制回收,这也是我们经常忽略的地方
    if (!bitmap1.isRecycled()) {
        bitmap1.recycle();
    }

    看上面的代码,设置新的背景之后,老的背景确定不再使用,则应该回收。

    封装如下(仅针对setBackgroundXXX做了封装,其他的原理类同):

    /**
     * 给view设置新背景,并回收旧的背景图片<br>
     * <font color=red>注意:需要确定以前的背景不被使用</font>
     * 
     * @param v
     */
    @SuppressWarnings("deprecation")
    public static void setAndRecycleBackground(View v, int resID) {
        // 获得ImageView当前显示的图片
        Bitmap bitmap1 = null;
        if (v.getBackground() != null) {
            try {
                //若是可转成bitmap的背景,手动回收
                bitmap1 = ((BitmapDrawable) v.getBackground()).getBitmap();
            } catch (ClassCastException e) {
                //若无法转成bitmap,则解除引用,确保能被系统GC回收
                v.getBackground().setCallback(null);
            }
        }
        // 根据原始位图和Matrix创建新的图片
        v.setBackgroundResource(resID);
        // bitmap1确认即将不再使用,强制回收,这也是我们经常忽略的地方
        if (bitmap1 != null && !bitmap1.isRecycled()) {
            bitmap1.recycle();
        }
    }
    
    /**
     * 给view设置新背景,并回收旧的背景图片<br>
     * <font color=red>注意:需要确定以前的背景不被使用</font>
     * 
     * @param v
     */
    @SuppressWarnings("deprecation")
    public static void setAndRecycleBackground(View v, BitmapDrawable imageDrawable) {
        // 获得ImageView当前显示的图片
        Bitmap bitmap1 = null;
        if (v.getBackground() != null) {
            try {
                //若是可转成bitmap的背景,手动回收
                bitmap1 = ((BitmapDrawable) v.getBackground()).getBitmap();
            } catch (ClassCastException e) {
                //若无法转成bitmap,则解除引用,确保能被系统GC回收
                v.getBackground().setCallback(null);
            }
        }
        // 根据原始位图和Matrix创建新的图片
        v.setBackgroundDrawable(imageDrawable);
        // bitmap1确认即将不再使用,强制回收,这也是我们经常忽略的地方
        if (bitmap1 != null && !bitmap1.isRecycled()) {
            bitmap1.recycle();
        }
    }
  • 相关阅读:
    Spring Batch 中的 chunk
    群晖(Synology)NAS 安装 MongoDB
    CentOS 上安装 Sonatype Nexus 仓库
    Jenkins pipeline Git 检出的 Step
    Npm 使用 Nexus 仓库的登录时候出现授权的问题
    Jenkins pipeline 如何到子文件中去执行命令
    Sonatype Nexus 管理员初始密码
    关于tkintergui窗体中循环周期性执行某段代码的方法记录
    关于windows服务器修改hosts文件不生效的问题原因分析
    关于Centos8.X操作系统不能使用yum源的解决方法
  • 原文地址:https://www.cnblogs.com/kaima/p/3497525.html
Copyright © 2020-2023  润新知