Android Handler : Handler为什么需要是static的 (一)

Android 内存泄漏的“双子星”:Handler 为何要 static,Context 为何不能 static 在 Android 开发中,有两道经典的“面试送命题”: “Handler 为什么要声明为 static?” “Context 为什么要避免被 static 引用?” 看似两个独立的问题,背后却藏着同一把钥匙——可达性分析与生命周期不一致。 理解这把钥匙,你不仅能轻松应对面试,更能写出让 GC 点赞的优雅代码。 阅读详情

Android Handler : Handler为什么需要是static的

为什么Handler需要是static的

先来看一下代码

public class HandlerTestActivity extends Activity {
    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            // ... do something
        }
    }
}

上面这段代码会引起内存泄漏(Memory Leak)。

为什么会引起Memory Leak

具体的原因如下:

  • 通过Handler发出、处理的Message,都带有Handler的引用,具体的原因稍后说明;
  • 上面例子中,生成的mHandler是通过匿名类生成的,这种匿名类中,带有Context的引用,具体原因稍后说明

这个时候,如果在Activity finish之后,Message仍然存在,那么Handler也仍然存在。如果Handler存在,那么由于Handler中有Context的引用,那么Context也就存在也就存在。也就是说,如果Acitivty finish之后,Message仍然存在,就会造成Context(Activity)被引用而无法释放,从而引起Memory Leak。

那么什么时候会出现,Activity finish,而Message然后存在呢?

  • 由于Android系统中,同一个线程共享一个Looper,那么在Activity finish之前发出延时的Message,在finish之后,是有可能存在的。
  • Message被其他地方引用,而没有释放。

通过上面的说明,上面代码内存泄漏的实质是Handler和Context之间的问题。Handler保存Context,从而造成Memory Leak。

为什么Message中带有Handelr的引用

下面通过Handler的代码来解释下Message中带有Handler的引用的原因

通过Handler发送Message有如下两种方式:

  • 通过sendMessage(Message msg)发送
  • 通过post(Runnable r)发送

通过sendMessage、post发送的,最终会都调用Handler的enqueueMessage函数

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
    msg.target = this;
    if (mAsynchronous) {
        msg.setAsynchronous(true);
    }
    return queue.enqueueMessage(msg, uptimeMillis);
}

可以看到,Handler会把自己(this)赋值给msg.target;

下面通过Looper、MessageQueue、Handler的机制来解释Message带有Handler引用的原因

Looper拿到Message之后,需要将Message分发出去,给到相应的Handler。这个时候Message本身必须带有和它对应的Handler,否则Looper将不知道Message分发给谁。所以Message必须带有Handler的引用。

为什么匿名类会带有Context的引用

上面代码中的匿名类是属于Activity一部分的。匿名类其实是一种特殊的内部类。
而non-static的内部类是保存外部类的引用的。对于non-static的内部类,由于它是外部类的一部分,外面需要用的时候,得通过外部类的实例来new出内部类。也就是说,外面需要访问non-static内部类,得必须通过外部类的实例,这也就说明了,not-static内部类是隐性的保存了外部类的应用。否则的话,外面就可以直接访问non-static内部类了,但是事实上不是这样的。

既然上面代码中的匿名类是Activity的一部分,那么它就持有Context(Activity)的引用。

华为Atlas 300I推理卡驱动安装避坑指南:不同安装方式的选择与优化 本文详细解析华为Atlas 300I推理卡驱动安装的三种主流方式(.run、.rpm和源码编译),提供关键环境检查步骤、安装流程优化建议及常见问题解决方案,帮助开发者高效完成芯片推理卡部署并规避典型安装陷阱。 阅读详情

相关推荐

transformer优化(一)-UNeXt 学习笔记

​它在早期阶段使用卷积,在潜在空间阶段使用 MLP。通过一个标记化的 MLP 块来标记和投影卷积特征,并使用 MLP 对表示进行建模。 ​

PLANTTHESON的博客 2033

android Handler应设为static

android开发中,使用Lint检测时会提示这么一句话 : This Handler class should be static or leaks might occur。意为handler应用static修饰否则容易发生内存泄漏。 ADT20有这么一个变化:Look for handler leaks: This check makes sure that a handler in

Dream It Possible 1万+

Android开发中StateFlow与LiveData的5个关键区别及实战避坑指南

本文深度解析了Android开发中StateFlow与LiveData的5个核心区别,包括设计哲学、生命周期管理、值更新策略、线程模型及协程生态整合。通过实战代码对比,为开发者在现代MVVM架构下的状态管理选型提供清晰的决策指南和避坑建议,帮助构建更健壮、可测试的应用。

weixin_29012677的博客 402

Android解惑之Handler为什么需要是static的

e安教育 2016-12-29 16:17 我们先来看一张Android Studio中的warning截图 handler内存泄漏.png 上面这段代码会引起内存泄漏(Memory Leak)。 为什么会引起内存泄漏? 我们都知道,非static的内部类会持有外部类的引用,举个类子来说,我们经常在一些内部类中显示跳转activity的时候,给Intent赋值的时

u011277123的博客 7349

【LTspice】005 伯德图绘制

目录 1 伯德图介绍 2 LTspice 截止频率验证 3 LTspice中如何添加光标 4 LTspice中如何将 幅频 和 相频曲线分开 1 伯德图介绍 Bode图由对数幅频特性和对数相频特性两张图组成。伯德图_百度百科 (1)对数幅频特性曲线 对数幅频特性是频率特性的对数值L(ω)=20lgA (ω)(dB)与频率ω的关系曲线;对数幅频特性的纵轴采用线性分度,为幅值的分贝数,即 L(ω)=20lgA(ω),A(ω)每增加10倍,L(ω)增加20dB;横坐标采用对数分度,即横轴上的ω取

m0_59642765的博客 1万+

5分钟搞定!用Cursor和.NET 9.0快速搭建串口通讯上位机(附VS Code插件配置)

本文分享了如何利用Cursor AI编程助手与.NET 9.0,在5分钟内快速构建一个功能完整的串口通讯上位机程序。通过自然语言描述需求,AI自动生成WinForms界面和核心代码,极大提升了硬件调试工具的定制开发效率。文章详细介绍了环境配置、AI协作编码、功能实现与调试的全过程。

weixin_28366353的博客 274

【Android】[转] Android Handler应设为static

android开发中,使用Lint检测时会提示这么一句话 : This Handler class should be static or leaks might occur。意为handler应用static修饰否则容易发生内存泄漏。ADT20有这么一个变化:Look for handler leaks: This check makes sure that a handler inner cl...

weixin_30699235的博客 192

TSMaster如何用珠海创芯CAN卡实现高效CAN通信(附完整驱动安装指南)

本文详细介绍了如何使用TSMaster软件与珠海创芯CAN卡实现高效CAN通信,包括驱动安装、系统配置、ControlCAN.dll替换及TSMaster集成配置等关键步骤。通过实战指南和故障排除技巧,帮助工程师快速搭建稳定可靠的CAN通信测试环境,适用于汽车电子和工业控制等领域。

weixin_29201859的博客 479

Android Handler : Handler为什么需要是static的 (二)

怎么解决由于Handler引起的Memory Leak既然知道了,Memory Leak的根本原因是Handler持有Context,导致Context无法释放。那么解决的办法就是断开Handler和Context之间的连接,让Handler不再持有Context的引用。大概的方法有: 将隐性匿名类Handler变成static的内部类,由于static的内部类,使用的使用不需要外部类的实例,所以s

Sunny的小窝 2795

从零搭建企业网络:使用Packet Tracer模拟多区域OSPF组网全过程

本文通过Cisco Packet Tracer模拟,详细演示了从零搭建一个典型企业多区域OSPF网络的完整流程。内容涵盖网络拓扑规划、IP地址设计、多区域划分原理,并提供了从设备初始化、接口配置到OSPF多区域核心配置与验证的详细步骤。文章旨在帮助网络学习者与IT支持人员通过动手实验,将理论知识转化为实际的配置与排障能力。

day7的博客 1030

STM32CubeIDE下载程序报错:Failed to execute MI command: load G:\\Cube_IDE_EXP\\00_FIRST\\Debug\\00...如何解决??

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 2594

Handler使用和内存泄漏解决办法

Handler是Android用于线程间通信的机制,使用方法:  1,在主线程(Activity)中创建Handler对象 public static Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(

wobushizhainan的博客 617

Altium Designer应用技巧13: 四层板的拼版方法

本文介绍在Altium Designer中,进行4层板的拼版方法。Altium Designer有多种拼版方法,本文选择最直观的复制、删帖方法来完成,步骤如下: 1、看一下原始文件,如下图所示,我们要对该板进行拼版操作。 2、通过菜单“报告”-“板子信息”得到板子大小,在这里一般切换为mm比较好操作,我们可以使用快捷键"q"。 3、如果是水平拼版,我们需要关心水平长度;如果是垂直拼版...

snmplink的博客 1万+

This Handler class should be static or leaks might occur (anonymous android.os.Handler) less... (Ctr

android studio最新版本有个很好的功能就是可以自动检测出代码中内存泄漏等问题今天说一下Handler出现内存泄漏的原因,以及解决方法In Android, Handler classes should be static or leaks might occur. Messages enqueued on the application thread's MessageQueue al...

m0_37678565的博客 1万+

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Android Handler应设为static

android开发中,使用Lint检测时会提示这么一句话 : This Handler class should be static or leaks might occur。意为handler应用static修饰否则容易发生内存泄漏。ADT20有这么一个变化:Look for handler leaks: This check makes sure that a handler inner cl

Coding for Android 743

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

This Handler class should be static or leaks may occur (anonymous android.os.Handler)

如果在 Activity 中使用了非静态的匿名 Handler 类,lint 会提示 This Handler class should be static or leaks may occur (anonymous android.os.Handler) 匿名 Handler 类导致内存泄露的原因

banxiali的博客 4018

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

android static实现Service与Activity中Handler通信

用于对static的理解,仅仅用于对static的理解,不喜勿喷 第一种方式:从Service中获取Activity的static变量,调用该静态变量的getHandler()获取Handler进行发送消息 MainActivity: package com.example.test; import android.support.v7.app.ActionBarActivity; imp

Code-lover's Learning Notes 4548

This `Handler` class should be static or leaks might occur (anonymous android.os.Handler)错误

安卓开发使用handler报错:This Handler class should be static or leaks might occur (anonymous android.os.Handler) 1、背景 今天给app写了个欢迎界面,这个需要保持运行2秒,所以使用了handler,代码如下: //WelcomeActivity private final Handler handler1 = new Handler(){ @SuppressLint("HandlerLea

qq_45436365的博客 4337

android static Handler

package com.example.orm; import java.lang.ref.WeakReference; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.v

SmallYellowPeople的博客 675

android --Handler不为static时,内存泄漏

当Handler不为static时,假设Handler里的message没处理完,Activity结束时因为Handler里存在Activity的引用,将无法释放资源.造成内存泄漏. 可以把Handler设为static的时候引用Activity里的资源也设为static,这样Handler和引用的资源都是独立的,就不存在内存泄漏.

qq_36600554的博客 329

android handler的警告Handler Class Should be Static or Leaks Occur

在使用Handler更新UI的时候,我是这样写的: public class SampleActivity extends Activity { private final Handler mLeakyHandler = new Handler() { @Over...

u013728021的博客 331

“This Handler class should be static or leaks might occur (anonymous android.os.Handler)…… "解决内存泄漏问题...

问题: 当使用了非静态的匿名 Handler 类,会提示 This Handler class should be static or leaks may occur (anonymous android.os.Handler)…… 非静态的匿名 Handler 类 解决方法: (官方给的方法) private Handler mHandler...

Jennyni1122的博客 3564
上一篇: Android Service : Service注意的问题
下一篇: Android Handler : Handler为什么需要是static的 (二)
dongjun7357
博客等级 码龄19年 23粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值