【麦子学院】Android TextView 预渲染
更新时间:2023-05-02 15:31:01 阅读量: 实用文档 文档下载
- 麦子学院第一版推荐度:
- 相关推荐
IT在线教育平台———麦子学院:c776cc620975f46526d3e177
【麦子学院】Android TextView 预渲染
TextView是什么?
TextView是Android开发的framework中最复杂的控件之一,主要负责Android中显示文本的工作。
正是由于TextView在Android开发中有着举足轻重的作用,所以其内部实现也相当复杂,单论代码行数来说,android- 22中TextView有足足9509行。另外,TextView中许
多操作都非常繁重,例如setText操作,需要设置 SpanWatcher,或者需要重现创建一个SpannableString,还需要根据情况重新创建Text Layout,这些操作加起来之后令一次setText操作非常耗时。为了提升TextView的渲染效率,我们需要对TextView进行预渲染处理,下面我们就来看看具体的处理方法吧。
TextView渲染原理
首先我们从渲染的原理出发,TextView中负责渲染文字的主要是这三个类:
1、BoringLayout
主要负责显示单行文本,并提供了isBoring方法来判断是否满足单行文本的条件。
2、DynamicLayout
当文本为Spannable的时候,TextView就会使用它来负责文本的显示,在内部设置了SpanWatcher,当检测到span改变的时候,会进行reflow,重新计算布局。
3、StaticLayout
当文本为非单行文本,且非Spannable的时候,就会使用StaticLayout,内部并不会
监听span的变化,因此效率上会比 DynamicLayout高,只需一次布局的创建即可,但其
实内部也能显示SpannableString,只是不能在span变化之后重新进行布局而已。
另外,由于以上三个类都继承于Layout类,因此在此类中会统一负责文本的具体绘制,在Layout.draw方法中,会对文本一行一行的进行渲染:
TextLine tl = TextLine.obtain();
// Draw the lines, one at a time.
// The baseline is the top of the following line minus the current line's descent.
IT在线教育平台———麦子学院:c776cc620975f46526d3e177
for (int i = firstLine; i <= lastLine; i++) {
....
Directions directions = getLineDirections(i);
if (directions == DIRS_ALL_LEFT_TO_RIGHT && !mSpannedText
&& !hasTabOrEmoji) {
// XXX: assumes there's nothing additional to be done
canvas.drawText(buf, start, end, x, lbaseline, paint);
} else {
tl.set(paint, buf, start, end, dir, directions, hasTabOrEmoji, tabStops);
tl.draw(canvas, x, ltop, lbaseline, lbottom);
}
}
TextLine.recycle(tl);
可以看出来对于Spannble,或者包含emoji的文本,实际渲染操作是交给了TextLine 去绘制,否则直接使用canvas.drawText,TextLine负责单行复杂文本的绘制,其中Spannable, Emoji之类的绘制逻辑都包含在里面,TextLine的绘制逻辑也并非十分高效。
TextLayoutCache
Canvas在drawText的时候,如果需要每次都计算字体的大小,边距等之类的话,就
会非常耗时,导致 drawText时间会拉的很长,为了提高效率,android在4.0之后引入了TextLayoutCache,使用LRU Cache缓存了字形,边距等数据,提升了drawText的速度。在4.4中,这个cache的大小是0.5M,全局使用,并且会在Activity的configurationChanged,onResume,lowMemory,updateVisibility等时机,会调用
Canvas.freeTextLayoutCache来释放这部分内存。由于这部分的cache是系统底层控制的,我们无法做具体的控制。
TextView的预渲染优化
从TextView的渲染原理来看,如果只是单纯的显示文本,根本不需要另外设置SpanWatcher来监听span的变化,因此可以直接使用BoringLayout或者StaticLayout来直接显示文本内容,但是BoringLayout只能显示单行文本,因此这里最好的选择是直接
用StaticLayout。
IT在线教育平台———麦子学院:c776cc620975f46526d3e177
我们选择了自定义View,并希望最终有这样的一个接口:
public class StaticLayoutView extends View {
private Layout layout = null;
public void setLayout(Layout layout) {
c776cc620975f46526d3e177yout = layout;
requestLayout();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
if (layout != null) {
layout.draw(canvas, null, null, 0);
}
canvas.restore();
}
}
我们可以直接通过设置这个view的Layout来绘制文本,并在onDraw方法中直接使用这个Layout对象来绘制文本。在这里我们摒弃了setText方法,直接通过Layout来绘制文本,而这里的Layout对象,我们可以通过预先创建之后才设置进去(这里可以放到单独的一个线程中创建),这样对比起普通TextView的setText方法,减少了setText中的许多消耗,可以大幅度的提升效率。
StaticLayout的创建非常简单,只需要给定文本,宽度等就能直接创建。另外,为了预先填充TextLayoutCache,我们也可以在创建完StaticLayout对象之后,预先在一个dummy canvas中draw出来:
IT在线教育平台———麦子学院:c776cc620975f46526d3e177
StaticLayout layout = new StaticLayout(TestSpan.getSpanString(i), textPaint, hardCodeWidth, alignment, 1.0f, 0f, true);
layout.draw(dummyCanvas);
性能对比
讲完原理、缓存和优化以后,接下来我们可以测试一下具体的性能,这里的testcase 放到了Github上:StaticLayoutView
testcase的内容为,在一个ListView中,显示300个Item,每个item都是一段纯文本,里面全都是包含有大量 ImageSpan的SpannableString,进行两边的对比,一边是直
接使用StaticLayout,一边是使用普通的TextView,并且这300段文本不全相同,长度不同,随机生成,在StaticLayout的testcase中,StaticLayout都是预先在另外一个线程创
建好之后才设置进去的, SpannableString也是预先生成好的。
另外,在这里为了模拟真实app繁重的后台工作,另创建了3个线程,不停在做浮点预算以尝试抢占CPU资源。
测量性能的指标为,ListView连续向下滚动,测量其平均帧率为多少,分别测量五次,计算其平均值,最终性能测试结果如下:
IT在线教育平台———麦子学院:c776cc620975f46526d3e177
注:这里测试的机器是MX3,左侧是直接使用StaticLayout的方案,右侧是系统的默认方案,Y轴是FPS,可以看出来,使用优化之后的方案,帧率提升了许多。
以上就是从TextView预渲染原理、缓存、优化及性能方面,对Android开发TextView的预渲染进行了详细的介绍,如果你想提升TextView的渲染效率,那就赶紧使用预渲染吧。
正在阅读:
【麦子学院】Android TextView 预渲染05-02
市场营销多选题05-20
委托书(最新5篇)03-26
公司车辆年检委托书02-20
财务授权委托书08-13
个人公证委托书模板08-22
学校安全工作月报表、消防安全排查表、消防隐患排查台账09-17
优雅的请假条09-29
党员承诺书02-23
- 教学能力大赛决赛获奖-教学实施报告-(完整图文版)
- 互联网+数据中心行业分析报告
- 2017上海杨浦区高三一模数学试题及答案
- 招商部差旅接待管理制度(4-25)
- 学生游玩安全注意事项
- 学生信息管理系统(文档模板供参考)
- 叉车门架有限元分析及系统设计
- 2014帮助残疾人志愿者服务情况记录
- 叶绿体中色素的提取和分离实验
- 中国食物成分表2020年最新权威完整改进版
- 推动国土资源领域生态文明建设
- 给水管道冲洗和消毒记录
- 计算机软件专业自我评价
- 高中数学必修1-5知识点归纳
- 2018-2022年中国第五代移动通信技术(5G)产业深度分析及发展前景研究报告发展趋势(目录)
- 生产车间巡查制度
- 2018版中国光热发电行业深度研究报告目录
- (通用)2019年中考数学总复习 第一章 第四节 数的开方与二次根式课件
- 2017_2018学年高中语文第二单元第4课说数课件粤教版
- 上市新药Lumateperone(卢美哌隆)合成检索总结报告
- 麦子
- 渲染
- TextView
- Android
- 学院
- 华南理工大学《电工与电子技术》往年考试题型及范围模拟试题
- gbt77142015参考文献标准
- 景观照明工程施工详细方案70327
- 幼儿园小班户外游戏教案
- Windows2008服务器安全加固方案
- 上海市20XX年度公务员招考简章(B类).doc
- 浦发银行公司网上银行使用手册教程文件
- 2019年南京林业大学理学院824有机化学考研冲刺五套模拟题
- 毕业论文 设计 封面
- 三年级英语下册 Unit 2 My family教案 人教PEP(标准版)
- 【全】2020专业技术人员心理健康与心理调适测试试题及答案2
- 华兰生物工程股份有限公司2009-2011年度奖励基金实施计划
- 媒体发布会记者提问0419
- 煤矿事故案例分析修订版
- 最新版的单间房屋租赁合同
- 标准日本语初级上下册超详细总结笔记打印版
- 林业碳汇项目风险及防范机制-最新范文
- 闻声识人课后测试答案
- 坯布质量检验标准美标四分制
- 经济师《中级民航运输专业》:第十三章.11