android pdf框架-8,图片缓存

news/2024/5/30 17:02:29/文章来源:https://blog.csdn.net/archko/article/details/136675535

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

在没有缓存的情况下,会看到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;}@Overridepublic 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中.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_1006044.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

目标跟踪SORT算法原理浅析

SORT算法 Simple Online and Realtime Tracking(SORT)是一个非常简单、有效、实用的多目标跟踪算法。在SORT中&#xff0c;仅仅通过IOU来进行匹配虽然速度非常快&#xff0c;但是ID switch依然非常严重。 SORT最大特点是基于Faster RCNN的目标检测方法&#xff0c;并利用卡尔…

2024 年 2 月公链行业研报

作者&#xff1a;stellafootprint.network 数据来源&#xff1a;Footprint Analytics 公链研究页面 二月份&#xff0c;加密货币市场展现出强劲的上涨势头&#xff0c;这主要得益于比特币和以太坊的价值大幅上涨超过 45%。这一乐观态势也影响到其他代币&#xff0c;前十大代币…

【Ubuntu-20.04】OpenCV-3.4.16的安装并对图片与视频处理

【Ubuntu-20.04】OpenCV-3.4.16的安装并对图片与视频处理 一、安装OpenCV-3.4.161.下载OpenCV-3.4.16安装包2.将安装包放到/home&#xff0c;并解压3.使用 cmake 安装 opencv4.配置环境5.查看 opencv 的版本信息 二、处理图片&#xff08;一&#xff09;创建文件夹 code &#…

Llama-3公布基础训练设施,使用49000个H100

3月13日&#xff0c;社交、科技巨头Meta在官网公布了两个全新的24K H100 GPU集群&#xff08;49,152个&#xff09;&#xff0c;专门用于训练大模型Llama-3。 此外&#xff0c;Llama-3使用了RoCEv2网络&#xff0c;基于Tectonic/Hammerspace的NFS/FUSE网络存储&#xff0c;继续…

探索轻量级 Java 开发利器 - Spring 框架

CSDN-个人主页&#xff1a;17_Kevin-CSDN博客 收录专栏&#xff1a;《Java》 目录 一、引言 二、Spring 框架的起源与发展 三、Spring 框架的核心特性 四、Spring 框架的应用场景 五、Spring 框架的优点 六、Spring 框架的学习曲线 七、Spring 框架的生态系统 八、总结…

[算法] 牛课题霸 - DP6 连续子数组最大和 - 动态规划

文章目录 题目链接解题过程思路一思路二 题目链接 DP6 连续子数组最大和 解题过程 思路一 两个for循环&#xff0c;遍历。 因为每个元素都要遍历两遍&#xff0c;所以时间复杂度O(n^2)。 简单的测试用例可以通过&#xff0c;但是提交时&#xff0c;一个巨大的数组用例&…

[云原生] Prometheus理论知识及系统搭建

promethues是一个开源的系统监控和报警系统&#xff0c;现在已经加入到CNCF基金会&#xff0c;成为继k8s之后第二个在CNCF托管的项目&#xff0c;在kubernetes容器管理系统中&#xff0c;通常会搭配prometheus进行监控&#xff0c;同时也支持多种exporter采集数据&#xff0c;还…

学c还行,学Python很累,还有其他语言适合我吗?

学c还行&#xff0c;学Python很累&#xff0c;还有其他语言适合我吗&#xff1f; 在开始前我分享下我的经历&#xff0c;我刚入行时遇到一个好公司和师父&#xff0c;给了我机会&#xff0c;一年时间从3k薪资涨到18k的&#xff0c; 我师父给了一些 电气工程师学习方法和资料&a…

微信小程序小案例实战

.wxml: <view class "title">狂飙经典语录 </view> <view class"out"><block wx:if"{{listArr.length}}"> <!-- bloock不会影响排版--><view class"list"><view class"row" wx:…

数字人基础 | 3D手部参数化模型2017-2023

楔子: 2017年年底的泰国曼谷, SIGGRAPH Asia会议上, 来自马普所的 Javier Romero, Dimitrios Tzionas(两人都是 Michael J. Black的学生)发布了事实性的手部参数化模型标准: MANO [1]。 MANO的诞生意味着 Michael J. Black团队在继人体参数化模型 SMPL后, 事实性的将能够表达人…

移除元素

文章目录 移除元素删除有序数组中的重复项移动零比较含退格的字符串有序数组的平方 移除元素 双指针 删除指定项且不改变顺序 def removeElement(nums: list[int], val: int) -> int:fast slow 0while fast < len(nums):if nums[fast] ! val:nums[slow] nums[fast]sl…

报错:Nginx 部署后刷新页面 404 问题

文章目录 问题分析解决 问题 在部署完项目后 刷新页面&#xff0c;页面进入了404 分析 加载单页应用后路由改变均由浏览器处理&#xff0c;而刷新时将会请求当前的链接&#xff0c;而Nginx无法找到对应的页面 关键代码try_files,剩下俩如果其他地方配置了则可以省略。 在这…

Windows-WSL2-VSCode+Docker配置C++开发环境

Windows-WSL2-VSCodeDocker配置C开发环境 写在前面 因为在学习工作中&#xff0c;需要不同的编码环境&#xff0c;若将这些不同的开发环境都状态一台设备上&#xff0c;很容易出问题&#xff0c;而且迁移性差&#xff0c;于是计划把不同的开发环境用docker隔离开来&#xff0…

vscode通过多个跳板机连接目标机(两种方案亲测成功)

1、ProxyJump&#xff08;推荐使用&#xff09; 需要OpenSSH 7.3以上版本才可使用&#xff0c;可用下列命令查看&#xff1a; ssh -V ProxyJump命令行使用方法 ssh -J [email protected]:port1,[email protected]:port2 一层跳板机&#xff1a; ssh dst_usernamedst_ip -…

IDEA中导入eclipse运行的java项目

本篇文章主要的内容是在IDEA中导入eclipse运行的java项目&#xff0c;亲测有效。 话不多说&#xff0c;直接开整。 前提&#xff1a;先打开idea软件&#xff0c;界面如下&#xff1a; 开始按下方步骤依次走即可。 1、file --> new --> Project from Existing Sources..…

大模型学习笔记(一):部署ChatGLM模型以及stable-diffusion模型

大模型学习笔记&#xff08;一&#xff09;&#xff1a;部署ChatGLM模型以及stable-diffusion模型 注册算力平台&#xff08;驱动云平台&#xff09;1.平台注册2.查看算力3.进入平台中心 部署ChatGLM3-6B模型1.创建项目2.配置环境设置镜像源、克隆项目修改requirements 3.修改w…

汽车租赁系统|基于SpringBoot+ Mysql+Java+B/S结构的汽车租赁系统设计与实现(可运行源码+数据库+设计文档+部署说明+视频演示)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 前台功能效果图 管理员功能登录前台功能效果图 ​编辑 用户功能模块 系统功能设计 数据库E-R图设计 …

buuctf warmup 超详细

目录 1.代码审计&#xff1a; 2.逻辑分析 3.总结分析 4.分析记录 5.疑点解答 1.代码审计&#xff1a; <?phphighlight_file(__FILE__);class emmm //定义了一个类{public static function checkFile(&$page) 类里面又申明创建…

Arduino IDE的下载和安装

一、Arduino的介绍 Arduino是一款开源电子原型平台&#xff0c;主要包含两部分&#xff1a;硬件&#xff08;各种型号的Arduino板&#xff09;和软件&#xff08;Arduino IDE&#xff09;。这个平台由意大利的Massimo Banzi、David Cuartielles等人共同开发设计&#xff0c;并于…

express+mysql+vue,从零搭建一个商城管理系统11--使用Sequelize

提示&#xff1a;学习express&#xff0c;搭建管理系统 文章目录 前言一、安装sequelize和mysql2二、修改config/db.js三、修改models/user.js&#xff0c;models/shop.js&#xff0c;models/goods.js四、新建dao/user.js&#xff0c;dao/shop.js&#xff0c;dao/goods.js五、修…