文档章节

Handler系列之内存泄漏

枫TI
 枫TI
发布于 2017/01/08 14:12
字数 851
阅读 20
收藏 0

什么是内存泄漏?大白话讲就是分配出去的内存,回收不回来。严重会导致内存不足OOM。下面来看一下造成内存泄漏的代码:

复制代码

public class MemoryLeakActivity extends Activity {

    private MyHandler mHandler;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);

        mHandler = new MyHandler();
        mHandler.sendEmptyMessage(1);
    }

    private class MyHandler extends Handler{
        
        public MyHandler(){
        }
        
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    }
}

复制代码

上面的代码我们不用管发送消息、接受消息,因为之前已经详细讲过了,不是本篇的重点。本篇我想说上面的代码会造成内存泄漏,什么意思?Handler持有MemoryLeakActivity引用,为什么?如果不持有当前类的引用,我怎么更改当前类的ui或其他逻辑???或者我们知道内部类持有外部类引用也行。那么怎么解决那?

  解决办法:将内部类改为静态内部类,因为静态内部类不持有外部类引用。由于Handler不再持有外部类引用,导致程序不允许你在Handler中操作Activity中的对象了。所以你还需要在Handler中增加一个对Activity的弱引用(使用弱引用的好处在于:activity一旦被置为null,他就会被立刻回收)。上面持有的引用属于强引用,强引用的特点就是当当前类被回收的时候,如果它被强引用所持有,那么当前类是不会被回收的!!!所以我们改成软引用持有当前类对象,这样在GC回收时会忽略掉弱引用,即就算有弱引用指向某对象,该对象也会在被GC检查到时回收掉。

复制代码

public class MemoryLeakActivity extends Activity {

    private MyHandler myHandler;

    private static final int ACTION_GOTO_MAIN = 1001;
    private static final int GOTO_MAIN_TIMER = 2 * 1000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);
        myHandler = new MyHandler(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (myHandler != null) {
            myHandler.sendEmptyMessageDelayed(ACTION_GOTO_MAIN, GOTO_MAIN_TIMER);
        }

    }

    @Override
    protected void onPause() {
        super.onPause();
        if (myHandler != null && myHandler.hasMessages(ACTION_GOTO_MAIN)) {
            myHandler.removeMessages(ACTION_GOTO_MAIN);
        }

    }

    protected static class MyHandler extends Handler {
        private WeakReference<MemoryLeakActivity> mActivity;

        public MyHandler(MemoryLeakActivity activity) {
            mActivity = new WeakReference<MemoryLeakActivity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            MemoryLeakActivity activity = mActivity.get();
            if (activity == null)
                return;
            if (msg.what == ACTION_GOTO_MAIN) {
                //处理逻辑
            }
        }
    }
}

复制代码

上面代码很好的解决了内存泄漏的问题。但是这段代码可能会在很多界面都会遇到,难道每个界面都需要这样写吗?重复的工作啊,所以干脆我们抽取成一个基类,将来创建Handler的时候继承这个基类就好。

复制代码

public abstract class WeakHandler<T> extends Handler {

    protected WeakReference<T> reference;

    //创建子线程Handler使用的构造器
    public WeakHandler(Looper looper, T reference) {
        super(looper);
        this.reference = new WeakReference<>(reference);
    }

    //创建主线程Handler使用的构造器
    public WeakHandler(T reference) {
        this.reference = new WeakReference<>(reference);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        T t = reference.get();
        if (t == null)
            return;
        handleMessage(t, msg);
    }

    protected abstract void handleMessage(T t, Message message);

}

复制代码

上述代码,我们使用了泛型,这个泛型就是我们之前说的当前类,同时提供了两种构造器,这样不管我们是创建主线程还是非主线程Handler对象时,都不会造成内存泄漏了。

  至此,Handelr系列讲解到此结束,大多数都是参数慕课网的《Android面试常客Handler详解》,我这里只是将视频中的内容加上自己的理解纪录下来,希望对大家有所帮助。

原文:http://www.cnblogs.com/lang-yu/p/6230368.html

本文转载自:http://www.cnblogs.com/lang-yu/p/6230368.html

枫TI
粉丝 14
博文 111
码字总数 66620
作品 2
东城
私信 提问
Android常见内存泄漏简单处理

本篇文章主要说一下项目结束时简单的内存泄漏检查与处理。 什么是内存泄漏? 内存泄漏(memory leak):是指应用在申请资源(内存)后,资源(内存)没有得到及时的释放。 区别: 内存溢出(out...

深情不及酒伴
2017/09/07
0
0
要点提炼|开发艺术之性能优化

本篇重点是性能优化,包括内容: 布局优化 绘制优化 内存泄漏优化 MAT工具 响应速度优化 ListView优化 Bitmap优化 线程优化 其他 1.布局优化 a.核心思想:尽量减少布局文件的层级。 b.方式:...

minmin_1123
2017/12/30
0
0
Android内存优化(三)避免可控的内存泄漏

相关文章 Android性能优化系列 Java虚拟机系列 前言 内存泄漏向来都是内存优化的重点,它如同幽灵一般存于我们的应用当中,有时它不会现身,但一旦现身就会让你头疼不已。因此,如何避免、发...

刘望舒
2017/06/26
0
0
Android深入浅出

Handler 源码注释翻译 让你无缝了解 Handler~ Android:这是一份很详细的 Socket 使用攻略 所有关于 Android Socket 的使用都在这里了 由Message,Handler,MessageQueue和Looper引发的思考?...

掘金官方
2018/01/04
0
0
Android内存泄漏以及解决办法

Android程序开发中,如果一个对象已经不需要被使用了,本该被回收时,而这时另一个对象还在持有对该对象的引用,这样就会导致无法被GC回收,就会出现内存泄漏的情况。 内存泄漏时Android程序...

lanyu96
2018/11/09
23
1

没有更多内容

加载失败,请刷新页面

加载更多

nginx学习笔记

中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯。 是连接两个独立应用程序或独立系统的软件。 web请求通过中间件可以直接调用操作系统,也可以经过中间件把请求分发到多...

码农实战
今天
5
0
Spring Security 实战干货:玩转自定义登录

1. 前言 前面的关于 Spring Security 相关的文章只是一个预热。为了接下来更好的实战,如果你错过了请从 Spring Security 实战系列 开始。安全访问的第一步就是认证(Authentication),认证...

码农小胖哥
今天
11
0
JAVA 实现雪花算法生成唯一订单号工具类

import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;import java.util.Calendar;/** * Default distributed primary key generator. * * <p> * Use snowflake......

huangkejie
昨天
12
0
PhotoShop 色调:RGB/CMYK 颜色模式

一·、 RGB : 三原色:红绿蓝 1.通道:通道中的红绿蓝通道分别对应的是红绿蓝三种原色(RGB)的显示范围 1.差值模式能模拟三种原色叠加之后的效果 2.添加-颜色曲线:调整图像RGB颜色----R色增强...

东方墨天
昨天
11
1
将博客搬至CSDN

将博客搬至CSDN

算法与编程之美
昨天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部