Android之TypedArray 为什么需要调用recycle()

转自:http://blog.csdn.net/Monicabg/article/details/45014327

在 Android 自定义 View 的时候,需要使用 TypedArray 来获取 XML layout 中的属性值,使用完之后,需要调用 recyle() 方法将 TypedArray 回收。

那么问题来了,这个TypedArray是个什么东西?为什么需要回收呢?TypedArray并没有占用IO,线程,它仅仅是一个变量而已,为什么需要 recycle? 
为了解开这个谜,首先去找官网的 Documentation,到找 TypedArray 方法,得到下面一个简短的回答:


简单翻译下来,就是说:回收 TypedArray,用于后续调用时可复用之。当调用该方法后,不能再操作该变量。

同样是一个简洁的答复,但没有解开我们心中的疑惑,这个TypedArray背后,到底隐藏着怎样的秘密……

求之不得,辗转反侧,于是我们决定深入源码,一探其究竟……

首先,是 TypedArray 的常规使用方法:

TypedArray array = context.getTheme().obtainStyledAttributes(attrs,R.styleable.PieChart,0,0);
try {mShowText = array.getBoolean(R.styleable.PieChart_showText,false);mTextPos = array.getInteger(R.styleable.PieChart_labelPosition,0);
}finally {array.recycle();
}
可见,TypedArray不是我们new出来的,而是调用了 obtainStyledAttributes 方法得到的对象,该方法实现如下:

public TypedArray obtainStyledAttributes(AttributeSet set,int[] attrs, int defStyleAttr, int defStyleRes) {final int len = attrs.length;final TypedArray array = TypedArray.obtain(Resources.this, len);// other code .....return array;
}
我们只关注当前待解决的问题,其他的代码忽略不看。从上面的代码片段得知,TypedArray也不是它实例化的,而是调用了TypedArray的一个静态方法,得到一个实例,再做一些处理,最后返回这个实例。看到这里,我们似乎知道了什么,,,带着猜测,我们进一步查看该静态方法的内部实现:

/*** Container for an array of values that were retrieved with* {@link Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)}* or {@link Resources#obtainAttributes}.  Be* sure to call {@link #recycle} when done with them.** The indices used to retrieve values from this structure correspond to* the positions of the attributes given to obtainStyledAttributes.*/
public class TypedArray {static TypedArray obtain(Resources res, int len) {final TypedArray attrs = res.mTypedArrayPool.acquire();if (attrs != null) {attrs.mLength = len;attrs.mRecycled = false;final int fullLen = len * AssetManager.STYLE_NUM_ENTRIES;if (attrs.mData.length >= fullLen) {return attrs;}attrs.mData = new int[fullLen];attrs.mIndices = new int[1 + len];return attrs;}return new TypedArray(res,new int[len*AssetManager.STYLE_NUM_ENTRIES],new int[1+len], len);}// Other members ......
}

仔细看一下这个方法的实现,我想大部分人都明了了,该类没有公共的构造函数,只提供静态方法获取实例,显然是一个典型的单例模式。在代码片段的第 13 行,很清晰的表达了这个 array 是从一个 array pool的池中获取的。

因此,我们得出结论:

程序在运行时维护了一个 TypedArray的池,程序调用时,会向该池中请求一个实例,用完之后,调用 recycle() 方法来释放该实例,从而使其可被其他模块复用。

那为什么要使用这种模式呢?答案也很简单,TypedArray的使用场景之一,就是上述的自定义View,会随着 Activity的每一次Create而Create,因此,需要系统频繁的创建array,对内存和性能是一个不小的开销,如果不使用池模式,每次都让GC来回收,很可能就会造成OutOfMemory。

这就是使用池+单例模式的原因,这也就是为什么官方文档一再的强调:使用完之后一定 recycle,recycle,recycle。




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

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

相关文章

APP开发者到期续费说明

几步搞明白APP开发者续费,不再苦恼。1、APP开发者账号快满一年时,注册邮箱会收到一封提醒续费的邮件。主题类似5 days left to renew your iOS Developer Program membership.。 2、点击该邮件中的renew today 按钮,根据提示一路点到底。 3、…

什么就像谈恋爱一样?

1 向这只猫学习!我的妈耶,这撩人的眼神,这小手,以后这大兄die的女朋友还要跟一只猫吃醋,默默先心疼一下2 善良的人最可爱了!3 妈妈救我,马路牙子不让我去找你4 这是童年的回忆呀5 一位网友收到老…

.NET Regular Expressions

HTML去空白回车换行 private static readonly Regex REGEX_LINE_BREAKS new Regex("\n\s*", RegexOptions.Compiled); private static readonly Regex REGEX_LINE_SPACE new Regex("\n\s*\r", RegexOptions.Compiled); private static readonly Regex R…

如何在 Entity Framework 中计算 时间差 ?

咨询区 ison我的项目中有一个需求,需要使用 Entity Framework 实现 日期差 的计算逻辑,参考如下代码:var now DateTime.UtcNow;db.Items.OrderBy(x > x.SomeInteger (x.Date - now).Days);但很奇怪,上面的代码会抛下面的错误…

java外键实体类_java – 在Embeddable类中的外键映射

我正在使用eclipselink进行JPA.我有一个实体,它有一个由两个字段组成的复合键.以下是我的Embeddable主键类的字段(成员).Embeddablepublic class LeavePK {ManyToOne(optional false)JoinColumn(name "staffId",nullable false)private Staff staff;Temporal(Temp…

练习微笑

所谓练习微笑,不是机械地挪动你的面部表情,而是努力地改变你的心态,调节你的心情。学会平静地接受现实,学会对自己说声顺其自然,学会坦然地面对厄运,学会积极地看待人生,学会凡事都往好处想。这…

lost connection to MySQL server at waiting for initial communication packet,system error:o

1 可以先测试mysql本地连接石否正常 2 正常的话查看远程连接的IP在mysql中是否有权限 GRANT ALL PRIVILEGES ON *.* TO root% IDENTIFIED BY 123123 WITH GRANT OPTION; note:(记得修改IP抵制和密码)转载于:https://www.cnblogs.com/yaohai…

Android之Activity的4种加载模式

一个Task可以理解成一个Activtiy栈,可以装载一个或者多个Activity,回退和打开的顺序逻辑和基本的数据结构栈是一致的。下面的这段话非常关键:那就是,一个Application如果有N个Activity,这些Activity分布在M个Task中,那么Application的回退栈会遵循这样的原则,首先从当前…

他拥有当今世界最高智商,从出生就一路开挂,然而,获得数学最高奖的他却说自己只是个热爱数学的普通人...

全世界只有3.14 % 的人关注了爆炸吧知识今天就讲讲这位平易近人的顶级天才吧。1975年,陶哲轩出生在澳大利亚,父母均毕业于香港大学,父亲陶象国是一名儿科医生,母亲梁蕙兰是物理和数学专业的高材生,曾当过中学数学教师。…

Win11用户增长迅速!你升了吗?

近日,AdDuplex 发布了 2021 年 11 月微软现代 Windows 操作系统的市场报告。现代 Windows 操作系统的统计只包括 Windows 11 和 Windows 10。Windows 11在 11 月,Windows 11 操作系统的市场份额达到 8.9%,其中包括 8.6% 运行 Windows 11 正式…

Tomcat一步步实现反向代理、负载均衡、内存复制

Tomcat是一个开源的Java EE服务器,想弄明白其中原理还有很长路要走,但是对于有Apache,Nginx经验的我们来说部署它还是没有问题的,下面我们来一步步的构建这些基本的功能吧。 实验环境:rhel 5.8,SElinux已经关闭 一.构建一个基本的…

mysql学时用什么类型_MYSQL数据库学习----MYSQL数据类型

一切数据在计算中都是以二进制形式存储,而8位二进制数就表示1个字节。通常我们说一种数据类型占多少字节,就是说这种数据类型可以表示多少位的二进制数,同时二进制数可以转换为十进制数,进而得到这种数据类型可以表示多大的十进制…

豆瓣9分,颠覆世界观的好书,每读一章就感叹一次:原来如此!(免费领)

全世界只有3.14 % 的人关注了爆炸吧知识聪明人的投资直击本质股神巴菲特曾在2019股东大会上,遇到了一位来自美国旧金山的年轻人提问:“要想成为一个好的投资者,最好的方法是什么?”巴菲特毫不犹豫回答道:“阅读”。5岁…

centos7.0搭建svn服务器

---恢复内容开始--- 在windows上搭建SVN很简单,但是效能却不高,这当然是和linux相比了.然而在linux上搭建SVN却非常繁琐,这篇文章就来一步一步教您如何在Centos上搭建SVN 源码目录:/home/svn/project 工程名:project 工程目录:/home/svn/proj…

Android之常见面试题

http://blog.sina.com.cn/s/blog_4f1d20f30100v23r.html 最近想找找工作看,没想到第一次去面试ANDROID开发工程师就碰壁了,虽然说做了两年的手机开发了,可哥却没参加过一次ANDROID的面试,所以这次一定要汲取教训,面试h…

C# WPF MVVM开发框架Caliburn.Micro Screens, Conductors 和 Composition⑦

01—Screens, Conductors and CompositionActions, Coroutines and Conventions往往最能吸引Caliburn.Micro的注意力,但如果你想让你的UI设计得更好,那么了解屏幕和导体可能是最重要的。如果您想利用合成,这一点尤其重要。杰里米米勒最近在为…

【原创】mysql数据库异常:data truncate for column “*” at row *;data too long *。原因,及解决。...

数据库异常 1.data truncate for column “*” at row *: 就是数据被截断,类似时间被截短(字段属性为date,要存储的数据为timestamp),精度下降。 将数据库的字段属性调整合适,或者将要存储的数据…

正则表达式匹配汉字

纯汉字:^[\u4E00-\u9FA5]$ 2E80~33FFh:中日韩符号区。收容康熙字典部首、中日韩辅助部首、注音符号、日本假名、韩文音符,中日韩的符号、标点、带圈或带括符文数字、月份,以及日本的假名组合、单位、年号、月份、日期、…

如此生猛的纪录片,背后是难以置信的故事!

全世界只有3.14 % 的人关注了爆炸吧知识美国纪录片大师阿尔伯特梅索斯所言:“制作一部电影不是为一个问题寻求答案,而是尝试去捕捉生活本身。”从赵忠祥那句大名鼎鼎的“春天到了,又到了动物交配的季节”开始,纪录片看似没有像影视…

java 字符串 日期格式化_java字符串转换为时间类型以及时间的格式化实例

java字符串转换为时间类型以及时间的格式化实例。时间的应用几乎是每个项目都要接触到的,也是每个java程序员所熟知的,但是不记得怎么使用也是无所谓的,我们可以查一下java api文档嘛!或者直接百度一下就可以了。下面就是时间类型…