Android 常见的几种内存泄漏
来源:互联网 发布:怎样注册一个域名 编辑:程序博客网 时间:2024/05/22 18:23
Handler的使用造成的内存泄漏问题应该说最为常见了,平时在处理网络任务或者封装一些请求回调等api都应该会借助Handler来处理,对于Handler的使用代码编写一不规范即有可能造成内存泄漏,如下示例:
public class MainActivity extends AppCompatActivity { private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { //... } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); loadData(); } private void loadData(){ //...request Message message = Message.obtain(); mHandler.sendMessage(message); }}
这种创建Handler的方式会造成内存泄漏,由于mHandler是Handler的匿名内部类的实例,所以它持有外部类Activity的引用,我们知道消息队列是在一个Looper线程中不断轮询处理消息,那么当这个Activity退出时消息队列中还有未处理的消息或者正在处理消息,而消息message持有mHandler实例的引用,mHandler又持有Activity的引用,所以导致该Activity的内存资源无法及时回收,引发内存泄漏。
那怎么样才可以避免这中问题呢,这里提供两个解决方案。这个问题是由于当Activity被销毁时发现引用它的Handler还在,从而导致了GC无法回收Activity。那么最简单最直接的方法是在Activity的OnDestory方法中移除所有的消息和回调即清空队列,MessageQueue被释放 从而使Handler得到释放,这时GC就能正常回收被销毁的Activity了。所以这种解决方案方法如下:
@Override protected void onDestroy() { super.onDestroy(); mHandler.removeCallbacksAndMessages(null); }
这个解决方案我们忽略了消息队列的作用。由于Handler对于Activity的引用导致GC无法回收Activity,我们直接暴力的把消息队列清空了,那如果需要这些处理消息队列中的消息呢?这就需要用到我们第二个解决方案:弱引用。其原理就是让所有在handler里面使用的对象都变成弱引用,目的就是为了可以在Android回收内存的时候,可以直接回收掉。
public class MainActivity extends AppCompatActivity { private MyHandler mHandler = new MyHandler(this); private TextView mTextView ; private static class MyHandler extends Handler { private WeakReference<Context> reference; public MyHandler(Context context) { reference = new WeakReference<>(context); } @Override public void handleMessage(Message msg) { MainActivity activity = (MainActivity) reference.get(); if(activity != null){ activity.mTextView.setText(""); } } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView)findViewById(R.id.textview); loadData(); } private void loadData() { //...request Message message = Message.obtain(); mHandler.sendMessage(message); }}
- Android几种常见的内存泄漏
- Android 常见的几种内存泄漏
- Android 常见的几种内存泄漏
- Android 几种常见的内存泄漏
- Android常见的几种内存泄漏小结
- Android内存泄漏的几种可能
- Android 常见的内存泄漏
- android常见的内存泄漏
- [Android]常见的内存泄漏
- android 常见的内存泄漏
- android 常见的内存泄漏
- 内存泄漏的检测、几种常见场景及解决方法
- Android常见内存泄漏
- android常见内存泄漏主要有以下几类:
- 再谈android内存泄漏—常见的八种导致 APP 内存泄漏的问题
- Android下常见的内存泄漏
- Android 常见内存泄漏的解决方案
- Android中常见的内存泄漏汇总
- gitlab解决#<Unicorn::HttpServer:0x007f854b8b8ad0>: worker (pid: 29607) exceeds memory limit
- 细说ftp服务器的搭建部署及权限管理
- Android静默拍照(无感知拍照)
- CentOS7安装mysql
- CSS line-height与行内框
- Android 常见的几种内存泄漏
- ES6构建彩票项目
- 【OpenCV入门指南】第一篇 安装OpenCV
- 【Java并发】- volatile详解
- JAVA向oracle 发送sql执行语句
- 第1章 Linux-Centos7.2安装Docker
- Centos 7防火墙firewalld开放80端口
- Android Studio 如何设置logcat(控制台)的缓存大小,增加logcat控制台条数
- 零基础入门深度学习(2)