android pdf框架-9,解码优化

mupdf不支持直接的多线程.multithread.c我也没看明白,android直接调用多线程就会莫名其妙的事,要么崩溃,要么渲染出的页面不对.

pdfium倒是可以直接多线程.但是解码速度要慢不少.

解码优化

解码优化有好多方面可以做;

队列优化,把当前显示中间的项,优先进行解码.

如果有缩略图,要优化解码.

解码前判断是否可见,因为队列是单线程的,当轮到它解码时,可能页面已经滑动过去

队列优化

用recyclerview实现的页面,不需要这么复杂,直接切边,然后解码页面,甚至不需要缩略图,滑动起来效果还是不错的,前提是把额外空间设置一个页面的高度,利用它的预加载能力.

recyelerview已经处理了页面的布局,可见性,回收,预加载等操作,而自定义的view是没有这些的.

定义两个队列,一个是解码缩略图的.另一个解码具体node的.

private final LinkedHashMap<String, DecodeTask> nodeTasks = new LinkedHashMap<>(32, 0.75f, false);
private final LinkedHashMap<String, DecodeTask> pageTasks = new LinkedHashMap<>(32, 0.75f, false);

使用handlerthread来处理,因为单线程,所以也不开线程池了.

具体的消息调度:

public boolean handleMessage(Message msg) {int what = msg.what;if (what == MSG_DECODE_START) {addDecodeTask(msg);} else if (what == MSG_DECODE_SELECT) {selectDecodeTask(msg);} else if (what == MSG_DECODE_CANCEL) {cancelDecodeTask(msg);}return true;}

外部调用:

public void decodePage(String decodeKey, PageTreeNode node, int pageNumber, final DecodeCallback decodeCallback, float zoom, RectF pageSliceBounds, String thumbKey) {final DecodeTask decodeTask = new DecodeTask(node, pageNumber, decodeCallback, zoom, decodeKey, pageSliceBounds, thumbKey);Message message = Message.obtain();message.obj = decodeTask;message.what = MSG_DECODE_START;mHandler.sendMessage(message);}

这样就把任务添加进队列了.然后就是队列的循环去判断是否有缩略图的任务

添加任务的方法比较简单,就是判断有没有任务在.

private void addDecodeTask(Message msg) {final DecodeTask decodeTask = (DecodeTask) msg.obj;if (decodeTask.type == DecodeTask.TYPE_PAGE) {DecodeTask old = pageTasks.put(decodeTask.thumbKey, decodeTask);if (old != null) {Log.d(TAG, String.format("old page task:%s-%s", pageTasks.size(), old));}} else {DecodeTask old = nodeTasks.put(decodeTask.decodeKey, decodeTask);if (old != null) {Log.d(TAG, String.format("old node task:%s-%s", nodeTasks.size(), old));}}mHandler.sendEmptyMessage(MSG_DECODE_SELECT);}

选任务:

private void selectDecodeTask(Message msg) {if (isRecycled) {return;}DecodeTask selectTask = null;if (!pageTasks.isEmpty()) {selectTask = pageTasks.entrySet().iterator().next().getValue();pageTasks.remove(selectTask.thumbKey);}if (selectTask == null) {if (!nodeTasks.isEmpty()) {selectTask = nodeTasks.entrySet().iterator().next().getValue();nodeTasks.remove(selectTask.decodeKey);}}if (selectTask == null) {//mHandler.sendEmptyMessageDelayed(MSG_DECODE_SELECT, 5000L);Log.d(TAG, String.format("no task:%s-%s", pageTasks.size(), nodeTasks.size()));} else {Log.d(TAG, String.format("add task:%s-%s", selectTask.pageNumber, selectTask.type));try {performDecode(selectTask);} catch (IOException e) {Log.e(TAG, String.format("decode error:%s-%s", selectTask.pageNumber, selectTask.node));} finally {mHandler.sendEmptyMessage(MSG_DECODE_SELECT);}}}

先判断缩略图的队列,如果不为空,则运行它,如果为空,判断node队列.最后都要发消息去进行下一轮选择.

原来的任务是否死亡的判断就要修改了:

private boolean isTaskDead(DecodeTask task) {boolean isPage = false;if (task.node == null) {isPage = true;}if (skipInvisible(task, isPage)) {return true;}return false;}
缩略图优化

涉及到体验,如果图片未解码,显示的是黑白色,看画布的颜色了.这体验是不好的.

所以优先设置一张缩略图,然后把这图先放上去,每一块解码时,把这些填充上,就会有一个渐变的过程,从模糊到清晰的过程,这种体验比较好.尤其在缩放值比较大的时候.比如放大3倍了.滑动的时候,每一块解码耗时都不小.

设置缩略图.就要先解析缩略图.

所以当node进行解码时,先判断有没有缩略图.没有的话,先解码缩略图.然后放入缓存中,再画出来.在vudroid的page中去画.pagetreenode中的decode,添加进参数.缩略图的key生成一个与page相关的唯一值.

绘制缩略图

protected String getKey() {

return String.format("%s-%s", index, documentView.decodeService);

}

这时的draw就要修改了

public void draw(Canvas canvas) {if (!isVisible()) {return;}//canvas.drawRect(bounds, fillPaint);Bitmap thumb = BitmapCache.getInstance().getBitmap(getKey());Log.d("", String.format("index:%s,%s, %s", index, getKey(), thumb));if (null != thumb) {Rect src = new Rect(0, 0, thumb.getWidth(), thumb.getHeight());Rect dst = new Rect((int) bounds.left, (int) bounds.top, (int) bounds.right, (int) bounds.bottom);canvas.drawBitmap(thumb, src, dst, null);} else {canvas.drawText("Page:" + (index + 1), bounds.centerX(), bounds.centerY(), textPaint);}node.draw(canvas);canvas.drawLine(bounds.left, bounds.bottom, bounds.right / 5, bounds.bottom, strokePaint);drawPageLinks(canvas);}
把小图画到大的范围,drawbitmap

通常有两种方法,一种是matrix,一种就是drawbitmap(bmp,src,dst,paint)

src取bitmap的大小生成一个框,dst就是目标的区域.这里使用的是第二种画法,比较简单.如果高宽比不对,图片会变形.

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

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

相关文章

隐语笔记3 —— 隐语架构

隐语架构一览 隐语产品层 定位&#xff1a; 通过可视化产品&#xff0c;降低终端用户的体验和演示成本。通过模块化API降低技术集成商的研发成本。 人群画像&#xff1a; 隐私保护计算集成商&#xff0c;产品人员&#xff0c;隐私保护计算需求方&#xff0c;开发人员&#xff…

Flutter-仿携程首页类型切换

效果 唠叨 闲来无事&#xff0c;不小心下载了携程app&#xff0c;还幻想可以去旅游一番&#xff0c;奈何自己运气不好&#xff0c;自从高考时第一次吹空调导致自己拉肚子考试&#xff0c;物理&#xff0c;数学考了一半就交卷&#xff0c;英语2B铅笔除了问题&#xff0c;导致原…

基于modbus TCP实现EPICS与西门子S7 1200系列1215C PLC的通信

PLC介绍 西门子系列PLC在国内的市场占比第一&#xff0c;1200系列中小型PLC&#xff0c;因其众多的产品序列、强大的通讯功能和丰富扩展模块&#xff0c;被使用在工业生产、自动化生产线、智能制造、机器人等各行各业。根据CPU的供电电源的型号和数字量输出的类型&#xff0c;…

专业130+总分410+西南交通大学924信号与系统考研经验西南交大电子信息通信工程,真题,大纲,参考书。

初试分数出来&#xff0c;专业课924信号与系统130&#xff0c;总分410&#xff0c;整体上发挥正常&#xff0c;但是还有遗憾&#xff0c;其实自己可以做的更好&#xff0c;总结一下经验&#xff0c;希望对大家有所帮助。专业课&#xff1a;&#xff08;130&#xff09; 西南交…

【技术栈】Spring Cache 简化 Redis 缓存使用

​ SueWakeup 个人主页&#xff1a;SueWakeup 系列专栏&#xff1a;学习技术栈 个性签名&#xff1a;保留赤子之心也许是种幸运吧 ​ 本文封面由 凯楠&#x1f4f8; 友情提供 目录 本栏传送门 1. Spring Cache 介绍 2. Spring Cache 常用注解 注&#xff1a;手机端浏览本文章…

DS-红黑树(RBTree)

一.红黑树 1.1 红黑树的起源 当对对AVL树做一些结构修改的操作时候&#xff0c;性能较为低下&#xff0c;比如&#xff1a;插入时要维护其绝对平衡&#xff0c;旋转的次数比较多&#xff0c;更差的是在删除时&#xff0c;有可能一直要让旋转持续到根的位置。 因此1972年Rudolf…

YOLOv8独家改进:backbone改进 | 视觉新主干!RMT:RetNet遇见视觉Transformer | CVPR2024

💡💡💡本文独家改进:RMT:一种强大的视觉Backbone,灵活地将显式空间先验集成到具有线性复杂度的视觉主干中,在多个下游任务(分类/检测/分割)上性能表现出色! 💡💡💡Transformer 在各个领域验证了可行性,在多个数据集下能够实现涨点 改进结构图如下: 收录 …

Canine IP-10/CXCL 10 ELISA试剂盒上新

科研用Canine IP-10/CXCL 10 ELISA试剂盒重磅来袭&#xff0c;将在免疫学、癌症研究与神经科学等多个领域助力各位老师们的研究&#xff01; 图1&#xff1a;犬IP-10/CXCL10结构预测&#xff08;图片来源&#xff1a;UniProt&#xff09; C-X-C基序趋化因子(C-X-C motif chemok…

pytorch中的gather函数的定义和作用是什么?

在PyTorch中&#xff0c;gather函数是一个用于从张量&#xff08;tensor&#xff09;中收集特定索引位置上的元素的函数。它主要用于高级索引和从张量中提取特定信息。 定义&#xff08;python&#xff09; gather函数的基本定义如下&#xff1a; torch.gather(input, dim, i…

4.2 RK3399项目开发实录-案例开发之OpenCV 编译和安装(wulianjishu666)

★嵌入式ARM开发全套案例代码&#xff1a;https://pan.baidu.com/s/1ksCQN__jD8ZrJhw8sWzhwQ?pwdvvfz 3.3. OpenCV 编译和安装 不少客户遇到OpenCV的问题多集中在如何获取mipi摄像头的数据。因为OpenCV使用的V4l2协议和Rockchip编写的mipi摄像头驱动协议不同&#xff0c;所以…

算法-排序,查找

1.排序 常用的排序算法有快速排序&#xff0c;归并排序&#xff0e; (1). 快速排序 以下是快速排序的基本步骤&#xff1a; a. 选择一个基准元素&#xff1a;通常选择序列的第一个元素作为基准元素。 b. 划分过程&#xff1a;将待排序的序列重新排序&#xff0c;所有比基准元素…

从零开始搭建游戏服务器 第六节 合理使用自定义注解+反射 简化开发流程

自定义注解 前言正文创建注解创建类扫描工具创建ProtoDispatcher类初始化Dispatcher协议的逻辑分发dispatcher使用注解标记方法测试 结语 前言 在前面几节我们将Login服的大体架构搭建了起来&#xff0c; 具体流程是这样的&#xff1a; 客户端上传protobuf协议到LoginServerL…

基于飞凌嵌入式i.MX6ULL核心板的电梯智能物联网关方案

电梯是现代社会中不可或缺的基础性设施&#xff0c;为人们的生产生活提供了很大的便捷。我国目前正处于城镇化的快速发展阶段&#xff0c;由此带动的城市基础设施建设、楼宇建设、老破小改造等需求也让我国的电梯行业处在了一个高速增长期。截至2023年年底&#xff0c;中国电梯…

「Linux系列」Shell echo命令/printf命令/test命令

文章目录 一、Shell echo命令二、Shell printf命令三、Shell test命令四、相关链接 一、Shell echo命令 echo 是 Unix 和 Linux 系统中常用的一个命令&#xff0c;用于在终端输出字符串或变量的值。这个命令非常基础且常用&#xff0c;通常用于脚本编写、命令行操作等场合。 …

UE5 GameMode C++函数 学习

已经尝试&#xff0c;确实能重启游戏 类描述符加了noplaceable过后即使是Actor也不能放到场景中了&#xff0c;关卡蓝图&#xff0c;GameMode&#xff0c;GameState这些就不能放场景中了 UFUNCTION(exec)

ruoyi-nbcio-plus基于vue3的flowable增加开始节点的表单绑定修改

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a…

Android Studio Gradle设置查看全部task

如果你在 Android Studio 的 Gradle 窗口中看不到所有的任务&#xff0c;你可以尝试以下步骤来解决这个问题 android studio 版本&#xff1a; Android Studio Iguana | 2023.2.1 Build #AI-232.10227.8.2321.11479570, built on February 22, 2024 打开 Android Studio 的设置…

行业官网:律师行业官网解决方案和案例

hello&#xff0c;我是大千UI工厂&#xff0c;从此篇开始介绍各行业官网建设的解决方案 和经典案例&#xff0c;本期介绍律师行业&#xff0c;欢迎老铁们关注、评论、如有设计需求可以私信我们。 一、高大上律师官网有什么作用 高大上官网对律师行业的作用主要体现在以下几个…

eNSP学习——GVRP基础配置

目录 一、什么是GVRP 二、实验内容 三、实验目的 四、实验步骤 五、实验拓扑 六、实验编址 七、实验步骤 7.1、基本配置 7.2、配置GVRP单向注册 7.3、配置GVRP双向注册 7.4、配置GVRP的Fixed模式 7.5、配置GVRP的Forbidden模式 需要完整的配置命令大全的可以点击链…

传输线和串扰(一):串扰的叠加以及耦合的起源

串扰是六大信号完整性问题之一。它是将不需要的信号从一个网络传输到相邻网络&#xff0c;并且发生在每对网络之间。网络包括信号路径和返回路径&#xff0c;它连接系统中的一个或多个节点。我们通常将具有噪声源的网络称为主动网络或攻击网络。产生噪声的网络称为安静网络或受…