android pdf框架-8,图片缓存

这篇具有很好参考价值的文章主要介绍了android pdf框架-8,图片缓存。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

解码会产生很多图片,滑过后不要显示,如果直接回收,会浪费不少资源.

在没有缓存的情况下,会看到gc还是比较频繁的.

有了缓存后,明显gc少了.

目录

常用的缓存

自定义缓存

显示相关的内存缓存

解码缓存池

内存缓存实现:

解码缓存池实现:


常用的缓存

lrucache,这是最常用的,也是android sdk里面有的.就是按访问时间顺序,内部使用linkedhashmap,会记录访问时间.

androidx.core.util.Pools

这是一个接口,实现后可以自己管理池.严格来说,它并不是一个缓存类,是用来构建缓存的基础类.

用lrucache作缓存,有一些不好的点,设置了容量并不是图片的字节总数,是图片的张数.这对于图片大小不一的情况,可能并不是很好.

自定义缓存
显示相关的内存缓存

需要string作缓存key,能读取,且能根据容量把最早未访问的清除出缓存队列.

解码缓存池

当需要解码时,从池里面找到bitmap,对于高版本的系统,解码可以使用比当前高宽大的图片来处理.那么当图片从上面的内存缓存中清除,不是调用recycle(),而是将它放入解码缓存池.这对于解码来说,会明显减少gc.

内存缓存实现:

既然lru这么好用,就参与它,把源码拿来修改下.有了自动清除最早访问的位图功能,又有根据总字节数去管理缓存.

private static final int mMaxPoolSizeInBytes = 100 * 1024 * 1024;

    private int mPoolSizeInBytes = 0;
定义了最大缓存100m, 这个值可以根据系统内存大小去调整,这里先固定.
private final LinkedHashMap<String, Bitmap> map = new LinkedHashMap<>(16, 0.75f, true);
默认先设16
获取图片,不需要去创建,如果为空就返回空.这与lru不一样的.
public final Bitmap getBitmap(@NonNull String key) {
        if (key == null) {
            throw new NullPointerException("key == null");
        }

        Bitmap mapValue;
        synchronized (this) {
            mapValue = map.get(key);
            if (mapValue != null) {
                hitCount++;
                return mapValue;
            }
            missCount++;
        }

        return null;
    }

//添加图片,
public final Bitmap addBitmap(@NonNull String key, @NonNull Bitmap value) {
        if (key == null || value == null) {
            throw new NullPointerException("key == null || value == null");
        }
//添加前先判断是否总容量已经达到限定的值,如果是就清除,直到总容量符合要求,然后再添加.如果总容量设置很小,那么这里的效率会比较低.
        while (mPoolSizeInBytes > mMaxPoolSizeInBytes) {
            removeLast();
        }

        mPoolSizeInBytes += value.getByteCount();

        Bitmap previous;
        synchronized (this) {
            putCount++;
            previous = map.put(key, value);
            if (previous != null) { //对于移除的要把容量减去它的大小.
                mPoolSizeInBytes -= previous.getByteCount();
            }
        }
        //System.out.println(String.format("put.size:%s, key:%s, val:%s, size:%s", map.size(), key, value, mPoolSizeInBytes));

        if (previous != null) {
            entryRemoved(false, key, previous, value);
        }

        return previous;
    }

//与lrucache差不多,记得容量的计算
private void removeLast() {
        String key;
        Bitmap value;
        synchronized (this) {
            if (map.isEmpty()) {
                return;
            }

            Map.Entry<String, Bitmap> toEvict = map.entrySet().iterator().next();
            key = toEvict.getKey();
            value = toEvict.getValue();
            map.remove(key);
            mPoolSizeInBytes -= value.getByteCount();
            evictionCount++;
        }
        //System.out.println(String.format("removeLast.size:%s, key:%s,val:%s, size:%s", map.size(), key, value, mPoolSizeInBytes));

        entryRemoved(true, key, value, null);
    }

public final Bitmap remove(@NonNull String key) {
        if (key == null) {
            throw new NullPointerException("key == null");
        }

        Bitmap previous;
        synchronized (this) {
            previous = map.remove(key);
            if (previous != null) {
                mPoolSizeInBytes -= previous.getByteCount();
            }
        }

        if (previous != null) {
            entryRemoved(false, key, previous, null);
        }

        return previous;
    }

当关闭页面时,建议清除所有的数据
public final void clear() {
        int size = map.size();
        for (int i = 0; i < size; i++) {
            removeLast();
        }
    }

这是内存缓存类,可以设置为单例.

解码缓存池实现:

BitmapPool,也设置单例.

public static class FixedSimplePool<T> implements Pools.Pool<T> {
        private final Object[] mPool;

        private int mPoolSize;

        /**
         * Creates a new instance.
         *
         * @param maxPoolSize The max pool size.
         * @throws IllegalArgumentException If the max pool size is less than zero.
         */
        public FixedSimplePool(int maxPoolSize) {
            if (maxPoolSize <= 0) {
                throw new IllegalArgumentException("The max pool size must be > 0");
            }
            mPool = new Object[maxPoolSize];
        }

        @Override
        @SuppressWarnings("unchecked")
        public T acquire() {
            if (mPoolSize > 0) {
                final int lastPooledIndex = mPoolSize - 1;
                T instance = (T) mPool[lastPooledIndex];
                mPool[lastPooledIndex] = null;
                mPoolSize--;
                return instance;
            }
            return null;
        }

        @Override
        public boolean release(@NonNull T instance) {
            if (isInPool(instance)) {
                return false;
            }
            if (mPoolSize < mPool.length) {
                mPool[mPoolSize] = instance;
                mPoolSize++;
                return true;
            }
            return false;
        }

        private boolean isInPool(@NonNull T instance) {
            for (int i = 0; i < mPoolSize; i++) {
                if (mPool[i] == instance) {
                    return true;
                }
            }
            return false;
        }
    }

这段代码好像是sdk里面有的.忘了是不是了.就是实现了 pools接口,然后用数组去存储数据

整个pool向外提供两个方法,aquried,release.

public Bitmap acquire(int width, int height) {
        Bitmap b = simplePool.acquire();
        if (null == b) {
            b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        } else {
            if (b.getHeight() == height && b.getWidth() == width) {
                //Log.d("TAG", String.format("use cache:%s-%s-%s%n", width, height, simplePool.mPoolSize));
                b.eraseColor(0);
            } else {
                b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            }
        }
        return b;
    }

    public void release(Bitmap bitmap) {
        boolean isRelease = simplePool.release(bitmap);
        if (!isRelease) {
            System.out.println("recycle bitmap:" + bitmap);
            bitmap.recycle();
        }
    }

解码时的bitmap从这个单例里面取.而不是新建

val bm = BitmapPool.getInstance().acquire(width, height)

// val page = mupdfDocument?.loadPage(pageSize.index) ?: return null

至于什么时候release对象,这需要在确定不用bitmap时,把它加入到BitmapPool中.文章来源地址https://www.toymoban.com/news/detail-840784.html

到了这里,关于android pdf框架-8,图片缓存的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android之Glide图片框架分析

    使用简单,链式调用,API简洁。with、load、into三步走就可以加载图片 生命周期自动绑定,根据绑定的Activity或者Fragment生命周期管理图片请求 高效处理Bitmap。支持bitmap的复用和主动回收,减少系统回收压力。 占用内存小(使用RGB565的格式),RGB8888每个像素占的字节会比RGB5

    2024年02月13日
    浏览(40)
  • android项目实战之使用框架 集成多图片、视频的上传

    效果图  实现方式,本功能使用PictureSelector 第三方库  。作者项目地址:https://github.com/LuckSiege/PictureSelector 1. builder.gradle 增加 2. XML布局 3. 适配器,这里对GridImageAdapter进行了改进。 5. 点击增加弹框布局 6. 弹框页面初始化 7.  弹框页面监听初始化 8. 增加拍照回调,不加这

    2024年01月23日
    浏览(36)
  • 若依框架中使用FreeMarker使用word动态模板生成pdf给前端展示(模板中并没用使用到图片,所以没有图片的方法,只用了表格展示数据,模板里面只涉及到了循环判断和日期格式)

    首先使用word创建动态模板  下方两组信息是通过循环展示的,在生成模板时注意,如果不点击里面表格,选择居中表格打印出来可能还有偏差,两边距离页面拒了可能不一样 存储需要的模板时注意      存成这个格式,如果不是2003可能会有坑,找到你生成的.xml文件,把后缀改成ftl  

    2024年02月04日
    浏览(41)
  • PDF转图片pdf转换图片,线程池

    然后用的时候:

    2024年02月11日
    浏览(44)
  • Java Word转PDF(直接转和以图片形式转)、PDF转图片、图片转PDF

    在淘宝上找了一家写代码的店铺写了一个工具类,再参考网上的代码,改了改 用到的类库: 工具类代码:

    2024年02月12日
    浏览(40)
  • 电脑如何pdf转图片?pdf转图片工具介绍

    无论是为了共享、展示、编辑、安全保护、印刷出版、学术研究还是教育目的,使用电脑pdf转图片都是一种非常实用的工具和技术,它提供了更多的灵活性、可视化效果和安全性,适用于各种日常使用场景,那么有没有好用的pdf转图片工具推荐呢?当然有啦,小编今天分享的

    2024年01月23日
    浏览(35)
  • pdf如何导出为图片?分享三个方法PDF转图片!

    将PDF文件转换为图片是在许多场景下都非常有用的操作,不仅能够保留原始文档的内容,还方便在各种平台上共享和展示。在本文中,我们将介绍三种简便的方法,帮助您将PDF文件快速转换为图片格式。 方法一:使用记灵在线工具 记灵在线工具是一个受信任的在线转换平台

    2024年02月12日
    浏览(43)
  • 在线图片怎么转换成PDF?在线图片转换成PDF步骤介绍

    文件格式要转化不知道怎么办?想要网上下载文件格式转换软件,但是却不知道下载哪个好?今天小编小编就给大家分享一下靠谱的小圆象PDF转换器工具,想知道这款软件好不好用?在线图片怎么转换成PDF?那就进来看看吧。 在线图片怎么转换成PDF 小圆象PDF转换器可以实现几十种

    2024年02月11日
    浏览(40)
  • 怎么把PDF转成图片格式?分享一个PDF转图片的方法

    在数字时代,PDF文件已经成为我们日常工作中不可或缺的一部分。然而,有时候我们需要将PDF文件中的内容转换为图片格式,这涉及到将PDF转图片的需求。PDF转图片的需求来源于不同的应用场景。在某些情况下,我们需要将PDF文件中的内容以图片的形式进行展示,例如在幻灯

    2024年02月02日
    浏览(57)
  • Python怎么将pdf转为图片?Python如何实现pdf文件转图片

    而pdf则是用来保存一些内容已经确定好的数据,因为pdf是无法直接修改内容的,所以也会经常将pdf转为图片来保存。本文就将会来介绍一下pdf转图片的方法,往下看看吧。 1.pdf转图片的话主要实现所需要的模块叫做PyMuPDF,它就是用来操作pdf文件的,通过pip工具下载安装即可。

    2024年02月11日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包