android - 为什么定义一个static ImageView会导致内存泄露?
问题描述
提示说:不要把「Do not place android context classes in static fields, this is a memory leak.」
我知道activity context 不应该被放到static fields里面因为它在app生命周期内一直存在,而且如果它通过构造函数传递给其他class的话,其他class也会一直不被回收。
但为什么ImageView不能是static(我发现SwipeRefreshLayout也不行)?是因为ImageView包含context?Button和TextView之类的view就没有这种问题。
问题解答
回答1:在Activity中填充布局,可以通过如下方式:
1.view view = View.inflate(context, R.layout.test,null );2.View view = LayoutInflater.from(context).inflate(R.layout.test,null);
可以发现,无论哪种方式,填充后的View都是持有context的引用的,也就是Activity的引用.如果此时填充的view是static修饰,那么静态的对象将持续持有Activity的引用,导致Activity无法销毁,Activity中所有的控件也都将无法彻底销毁和回收.最终造成内存泄露.
PS:为什么要使用静态View的方式?有什么特殊的业务需求?
回答2:static变量在内存中是单独存在于内存块中的,控件(你的问题中指的是ImageView)是持有Activity的引用的,这种情况下,Activity是没法被彻底销毁的,因为在内存中一直有一个引用(指针理解),导致Activity也无法被回收,自然就会内存泄漏了!建议,在Android中不要使用static修饰控件!
回答3:View需要持有Context (否则无法实现 setXXX(int resid)类的功能)
我也不知道Button/TextView为什么不警告
回答4:static变量无法被自动回收啊你将某个view设为静态量,而view又持有activity的引用,这下连activity也泄露了
回答5:IPC说: static对于Android四大组件来说, 简直就是大杀器
回答6:因为static的生命周期很长比当前activity长
回答7:这么说吧,这是java基础.静态变量在类文件编译成字节码后,载入方法区的时候,就会初始化静态变量,而且静态变量会一直存在,而没有static修饰的activity,会在new的时候,在堆中申请空间,当activity没用的时候,gc会按照gc-root遍历此activity有没有被引用,由于activity的context被持有,ImageView view = LayoutInflater.from(context).inflate(R.layout.test,null);,所以,gc不能回收,造成内存泄漏,,当直到虚拟机结束进程(也就是app停止),
相关文章:
1. docker-machine添加一个已有的docker主机问题2. dockerfile - 我用docker build的时候出现下边问题 麻烦帮我看一下3. angular.js - angularjs的自定义过滤器如何给文字加颜色?4. java编程思想第4版中文版的几处谬误?5. 请问怎么改变超链接字体的颜色?6. docker内创建jenkins访问另一个容器下的服务器问题7. java - 做数据库向手机端的推送要系统地学习哪些知识?求大神指点,谢谢!8. 关docker hub上有些镜像的tag被标记““This image has vulnerabilities””9. python - 内容审核(图片鉴别)回调无数据?10. python - django queryset自定义排序问题
![docker-machine添加一个已有的docker主机问题](http://www.haobala.com/attached/image/news/202311/1028320972.png)