热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ViewPager里Bitmap主动回收资源的另一种思路

原创文章,欢迎转载,转载请注明:fishcode.cn作者:JaydenZhou  Android是个资源吃紧的系统,虽然现在的手机运存越来越大,但是由于手机屏幕越来越大,加载的图片越

原创文章,欢迎转载,转载请注明:fishcode.cn
作者:JaydenZhou

  Android是个资源吃紧的系统,虽然现在的手机运存越来越大,但是由于手机屏幕越来越大,加载的图片越来越大,加载后换算成内存占用也就越来越大,特别是用Bitmap直接不做任何压缩处理就加载显示的话,占用更大。因此我要分享其中的一种场景,我们可以主动去释放掉Bitmap资源,从而减轻内存占用。

场景:启动轮播图加载和释放优化

1.采用ViewPager + 多张图片来展示,加载数据的Adapter用继承于PagerAdapter的StaticPagerAdapter,类似参考FragmentStatePagerAdapter,是为了将所有要看的图片都加载到内存里面,这样用户左右滑动起来,就不会再触发初始化和销毁,这样就感觉很流畅,缺点就是占用内存大。
2.若采用类似FragmentPagerAdapter的话,就会默认销毁索引间距超过1的对象,这样内存不会占用过大,但是由于重复初始化,会造成低端手机滑动卡顿。
3.为了保持数据一致,所有图片加载显示时候都没有经过压缩处理。

传统的解决方法:

  在PagerAdapter里面复写 destroyItem 方法,然后主动回收图片:

public void releaseImageViewResouce(ImageView imageView) {  
    if (imageView == null) return;  
    Drawable drawable = imageView.getDrawable();  
    if (drawable != null && drawable instanceof BitmapDrawable) {  
        BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;  
        Bitmap bitmap = bitmapDrawable.getBitmap();  
        if (bitmap != null && !bitmap.isRecycled()) {  
            bitmap.recycle();  
            bitmap=null;  
        }  
    }  
    System.gc();  
}

但是缺点也就是跟用FragmentPagerAdapter的一样,用户重新左滑回来的话,就又会出现重新初始化卡顿的情况。

新的解决方法:

  原则是我们需要保证滑动时候的顺畅,以及不需要的时候及时回收。所以在PagerAdapter相关继承类里面写一个方法,然后当不需要展示时候,从外部调用,进行整体的释放。

/** * 手动释放轮播引导图资源,不然内存会过非常久才可能会被gc回收 * 从图像类里面获取,其中mViewList是静态Adapter里面存储的View集合。 * */
 public void releaseAllImageRes() {
   for(View view : mViewList) {
       if(view instanceof ImageView) {
           ImageView imageView = (ImageView)view;
           imageView.setImageBitmap(null);
           BitmapUtil.releaseImageViewResouce(imageView);
         }
     }
 }
    /** * 释放图片资源 * @param imageView */
    public static void releaseImageViewResouce(ImageView imageView) {
        if (imageView == null) return;
        Drawable drawable = imageView.getDrawable();
        if (drawable != null && drawable instanceof BitmapDrawable) {
            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
            Bitmap bitmap = bitmapDrawable.getBitmap();
            if (bitmap != null && !bitmap.isRecycled()) {
                bitmap.recycle();
                bitmap=null;
            }
        }
        System.gc();
    }

  如此这样一来,我们可以主动触发recycle和gc,这样据我实测,1080P手机下的5张引导图,主动回收的话可以回收掉60M左右内存,如下图所示:

  但是有一点要注意,recycle这个不能随便用,你得确认后续app内不会再用这个资源时候才能主动这么调用,否则有可能出现你要再次使用的时候,报错。如源码里面的解释:

/**
 * Free the native object associated with this bitmap, and clear the
 * reference to the pixel data. This will not free the pixel data synchronously;
 * it simply allows it to be garbage collected if there are no other references.
 * The bitmap is marked as "dead", meaning it will throw an exception if
 * getPixels() or setPixels() is called, and will draw nothing. This operation
 * cannot be reversed, so it should only be called if you are sure there are no
 * further uses for the bitmap. This is an advanced call, and normally need
 * not be called, since the normal GC process will free up this memory when
 * there are no more references to this bitmap.
 */

参考文章:http://blog.csdn.net/bobxie520/article/details/51167957


推荐阅读
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 怀疑是每次都在新建文件,具体代码如下 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • HTML学习02 图像标签的使用和属性
    本文介绍了HTML中图像标签的使用和属性,包括定义图像、定义图像地图、使用源属性和替换文本属性。同时提供了相关实例和注意事项,帮助读者更好地理解和应用图像标签。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • 本文介绍了在Python中使用zlib模块进行字符串的压缩与解压缩的方法,并探讨了其在内存优化方面的应用。通过压缩存储URL等长字符串,可以大大降低内存消耗,虽然处理时间会增加,但是整体效果显著。同时,给出了参考链接,供进一步学习和应用。 ... [详细]
  • Week04面向对象设计与继承学习总结及作业要求
    本文总结了Week04面向对象设计与继承的重要知识点,包括对象、类、封装性、静态属性、静态方法、重载、继承和多态等。同时,还介绍了私有构造函数在类外部无法被调用、static不能访问非静态属性以及该类实例可以共享类里的static属性等内容。此外,还提到了作业要求,包括讲述一个在网上商城购物或在班级博客进行学习的故事,并使用Markdown的加粗标记和语句块标记标注关键名词和动词。最后,还提到了参考资料中关于UML类图如何绘制的范例。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 本文介绍了响应式页面的概念和实现方式,包括针对不同终端制作特定页面和制作一个页面适应不同终端的显示。分析了两种实现方式的优缺点,提出了选择方案的建议。同时,对于响应式页面的需求和背景进行了讨论,解释了为什么需要响应式页面。 ... [详细]
  • 本文介绍了Android中的assets目录和raw目录的共同点和区别,包括获取资源的方法、目录结构的限制以及列出资源的能力。同时,还解释了raw目录中资源文件生成的ID,并说明了这些目录的使用方法。 ... [详细]
author-avatar
龙love猫
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有