Android学习笔记4:关于handler以及它已过时的构造函数handler()

Android面试准备之Android基础 一、Handler机制 创建一个Handler //提示已过时 Handler handler = new Handler(); Handler handler = new Handler(Looper.myLooper()); 隐式指定Looper的Handler初始化方法已被Android 11报过时,根据注释,是由于不指定Looper在一些场景下会导致任务丢失或程序崩溃,比如没有Looper的线程。 public static @Nullable Looper myLooper() { re 阅读详情

一.android消息驱动机制

Thread、Looper、Handler这三个是android消息驱动机制的核心对象,让我们先分析并了解一下一个线程拥有消息处理能力的过程:


class LooperThread extends Thread
{
    public Handler mHandler;
    public void run() 
    {
        Looper.prepare();//初始化该线程looper
        mHandler = new Handler()  //创建handler对象的同时,将该hanlder注册到线程looper中
        {
            //消息处理
            public void handleMessage(Message msg) 
            {
                switch(msg.what)
                {
                    case 0:
                        break;
                    //case ....
                    default:
                        break;
                }
            }
        };
        Looper.loop();//进入消息循环
    }
}

线程一但被执行(run函数)首先做的就是通过Looper.prepare()函数初始化线程的looper,接着创建handler,创建的过程中hanlder会自动把自己注册到线程looper中,最后Looper.loop()进入消息循环,将CPU交给内核。

其实activity处理消息也是类似的过程,但activity已经把这些代码隐藏了起来以便让我们只做最关心的事情。那么activity里怎么处理用户自己的消息呢?因为关于looper的事都已经处理好了,所以只要创建handler就OK啦。

二.Handler构造函数过时问题

用户消息在Activity内如何接收处理?实现方法如下代码所示:

public class MainActivity extends ActionBarActivity {
 
	//接收消息处理
	private Handler handler = new Handler() {  
		@Override  
		public void handleMessage(Message msg) {  
			if(msg.what==0)
			{
            }
        }};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	    // ....
	}
}

但现在,这个代码编译时会得到一个警告:“ 警告: [deprecation] Handler中的Handler()已过时” 。下面小编对这个警告以及其解决办法的理解。

先不考虑这个警告的事情,上面的代码存在定的内存泄露风险,那么怎么泄露内存,原理是什么呢?

Handler应认为是属于内核的对象,内核和activity所在线程是异步的,当Activity被销毁时内核可能还在用这个Handler,于是内核不让释放Handler,于是这个Handler没用了,却错过了唯一一次被销毁 的机会,就这样占据着内存,这就是内存泄露。

三.解决办法

以下为小编认为的标准解决办法:

public class MainActivity extends Activity {
    public int m_var; //需要在消息处理中访问的成员变量,一定要声明成public

    MyHandler handler = new MyHandler(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_auto);
    }
 
    //新的handler类要声明成静态类
    static class MyHandler extends Handler{
        WeakReference<MainActivity> mactivity;
         
        //构造函数,传来的是外部类的this
        public MyHandler(MainActivity activity){
            mactivity = new WeakReference<MainActivity>(activity);
        }
 
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);  

            MainActivity nactivity=mactivity.get();
            if(nactivity == null)
                return ;//avtivity都没了还处理个XXX

            switch (msg.what) {
            case 0:   
                //在这里通过nactivity引用外部类
                nactivity.m_var=0;          
                break;              
            default:
                break;
            }
        }
    }

为了防止内存泄露,官方要求将handler声明为静态类,静态就意味着全局,也就是说当app全部被销毁的时候内核不会忘记销毁你这个handler,可内存泄露问题解决了,却引来了另一个很棘手的问题,静态类是无法访问外部类成员的,

访问外部类的成员变量是消息处理代码非常迫切的需求,那怎么办呢?就把外部类的对象引用通过构造函数的参数传递过来不就可以访问了吗,的确是这样,但参数又被WeakReference包装了一下又是什么意思呢?

还是为了解决最初的那个问题,怕的是消息没处理完呢activity被销毁了。在我看来WeakReference就是个具有感知内部对象是否已经被销毁能力的东东。怎么感知?当然是.get()函数啦。最后还要提醒一下,要在handler消息处理中访问的activity成员要声明成public才行,这是java类的一个常识。

那么,到此警告的问题被解决了吗?并没有,这个警告的意思是,handler的隐式传递Looper的构造函数不建议再使用了,上面的代码显然没有解决这个问题。google认为隐式传递的构造函数不合理,所以不建议再使用了,更深的原因小编也说不出一二来,总之,新的代码中应该做的就是handler创建时需要手动指明往哪个Looper注册自己,也就是说创建handler对象时要给构造函数传递当前线程的Looper,修改后的代码如下:

public class MainActivity extends Activity {
    public int m_var; //需要在消息处理中访问的成员变量,一定要声明成public

    MyHandler handler = new MyHandler(Looper.myLooper(),this);//获取Looper并传递

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_auto);
    }
 
    //新的handler类要声明成静态类
    static class MyHandler extends Handler{
        WeakReference<MainActivity> mactivity;
         
        //构造函数,传来的是外部类的this
        public MyHandler(@NonNull Looper looper,MainActivity activity){
            super(looper);//调用父类的显式指明的构造函数
            mactivity = new WeakReference<MainActivity>(activity);
        }
 
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);  

            MainActivity nactivity=mactivity.get();
            if(nactivity == null)
                return ;//avtivity都没了还处理个XXX

            switch (msg.what) {
            case 0:   
                //在这里通过nactivity引用外部类
                nactivity.m_var=0;          
                break;              
            default:
                break;
            }
        }
    }

 

至此警告已被解除。

 

 

 

 

[Android进阶】Handler机制原理解析_android handler的机制和原理 按照国际惯例,给大家分享一套十分好用的Android进阶资料:《全网最全Android开发笔记》。整个笔记一共8大模块、729个知识点,3382页,66万字,可以说覆盖了当下Android开发最前沿的技术点,和阿里、腾讯、字节等等大厂面试看重的技术。因为所包含的内容足够多,所以,这份笔记不仅仅可以用来当学习资料,还可以当工具书用。如果你需要了解某个知识点,不管是Shift+F 搜索,还是按目录进行检索,都能用最快的速度找到你要的内容。 阅读详情

相关推荐

安卓中的消息循环机制Handler及Looper详解

我们知道安卓中的UI线程不是线程安全的,我们不能在UI线程中进行耗时操作,通常我们的做法是开启一个子线程在子线程中处理耗时操作,但是安卓规定不允许在子线程中进行UI的更新操作,通常我们会通过Handler机制来完成该功能,即当子线程中耗时操作完成后,在子线程中通过Handler向主线程发送消息,在主线程中的Handler的handleMessage方法中处理接受到的消息。这就是安卓中的消息机制,安

(* ̄︶ ̄) 7960

【Android】多线程编程、异步消息处理机制以及new Handler()被标记为过时的解决办法,解决Handler内存泄漏问题和AsyncTask的基本用法

Android多线程编程、异步消息处理机制以及new Handler()被标记为过时的解决办法,解决Handler内存泄漏问(当Activity被销毁时,如果其中使用的Handler被持有,并且在外部引用它的对象的生命周期之外保持活动状态,这就可能导致内存泄漏。)、AsyncTask的基本用法

摸鱼小小虫的博客 2407

Android Handler机制-Looper、Handler、MessageQueue、Message的关系

一、概述 Handler是Android中处理异步消息的机制。Looper、Handler、MessageQueue、Message概括来说就是:Looper负责的就是创建一个MessageQueue,然后进入一个无限循环体不断从该MessageQueue中读取消息Message,然后回调相应的消息处理函数,而消息的创建者就是一个或多个Handler,执行完成一个消息后则继续循环。 二、MessageQueue详解 消息队列MessageQueue就是存放消息的队列。那队列中存储的消息是什么呢?.

鸿蒙开发知识记录 983

Handler()过时

handler 方法过时

u010207898的博客 3552

【Android学习笔记】初探Thread、Looper和handler之间的联系

前几天写程序的时候碰到这么一个问题,当时想在子线程中Toast一段话,不废话上代码 new Thread(new Runnable() { @Override public void run() { new Handler(){ @Override ...

b410604224的博客 2535

Innovus快捷键大全:从入门到精通的效率提升指南

本文是Innovus快捷键从入门到精通的效率提升指南,旨在帮助芯片后端设计工程师通过掌握核心快捷键,将重复性鼠标操作转化为高效的肌肉记忆,从而显著提升版图设计、编辑和分析的工作流速度。文章系统讲解了视图导航、对象选择编辑、流程管理等关键快捷键组合,并提供了个性化配置与实战策略,助力工程师突破效率瓶颈,实现人机合一的流畅设计体验。

silver的专栏 797

Android Handler被弃用,那么以后怎么使用Handler,或者类似的功能

该主线程将 UI 事件或消息收集到队列 ( MessageQueue) 中,然后使用Looper类的实例对其进行处理。简要说就是如果在实例化Handler的时候不提供Looper, 可能导致操作丢失(Handler 没有预估到新任务并已退出)、App崩溃的bug(Handler有时候创建一个线程,但没有运行的Looper),亦或者race情况下,造成处理错误。Android API30左右,Android应用在使用传统写法使用Handler类的时候会显示删除线,并提示相关的方法已经被弃用,不建议使用。

hdhhd的博客 1148

HEVC/VVC中R-Lambda码率控制算法原理

文章目录1. 比特分配1.1 GOP级比特分配1.2 帧级比特分配1.3 LCU级比特分配2. 码率控制2.1 λ的计算和更新2.2 参数QP的确定 VVC中码率控制算法沿用了HEVC中经典的R-λ码率控制模型,R-λ由中科大的李斌博士提出(详情参考JCTVC-K0103)。R-λ模型的基础为视频编码中 R(比特 bpp)和 D(失真 MSE)之间的双曲线模型,即 D(R)=CR−KD(R) = ...

Aidoneus_y 6136

安卓新版本handle过期deprecated警告解决方法

更新后使用handle会出现如下警告 ‘Handler()’ is deprecated,看了下别人的博客,似乎为了解决隐式选择Looper的Bug 解决办法 方法一: 忽略警告 可以在类名前加上 @SuppressWarnings(“deprecation”); 方法二: 将代码替换为如下 Handler handler = new Handler(Looper.getMainLooper()){ @SuppressLint("HandlerLeak") @Override pu

qq_45796133的博客 5226

ITIL-IT运维管理-概述

ITIL-IT运维管理-概述 概述 IT服务管理(ITSM)是一套帮助企业对IT系统的规划、研发、实施和运营进行有效管理的方法,是一套方法论。ITSM起源于ITIL(IT Infrastructure Library,IT基础架构标准库),ITIL是CCTA(英国国家电脑局)于1980年开发的一套IT服务管理标准库。它把英国在IT管理方面的方法归纳起来,变成规范,为企业的IT部门提供一套从计划、研发、实施到运维的标准方法。 中文名 IT服务管理 外文名 ITService Management 专家

syjhct的博客 4万+

source tree clone error:fatal remote error: Repository not found

source tree clone error:fatal remote error: Repository not found

Linda的前端开发路 3077

关于handler以及它已过时的构造函数handler()

搬运自:https://blog.youkuaiyun.com/BitFu/article/details/110183184 ,仅作个人学习笔记用 一.android消息驱动机制 Thread、Looper、Handler这三个是android消息驱动机制的核心对象,让我们先分析并了解一下一个线程拥有消息处理能力的过程: class LooperThread extends Thread { public Handler mHandler; public void run() {

Grekit_Sun的博客 2881

项目管理-(补充)七种基本质量工具

七种基本质量工具,用于PDCA循环的架构内 解决与质量相关的问题,分为老七工具和新七工具。 1)老七种:刘英只点劣质茶(流程图、因果图、直方图、散点图、帕累托图、控制图、核查表)2)新七种:锯树联亲测动优(矩阵图、树形图、关联图、亲和图、过程决策程序图、活动网络图、优先矩阵)

weixin_42081167的博客 4603

Android :安卓学习笔记之 Handler机制 的简单理解和使用

Android Handler机制的简单理解和使用1、Handler使用引出2、背景和定义3、作用4、相关概念5、工作流程5.1、对应关系6、基本使用7、参考 1、Handler使用引出 现在作为客户,有这样一个需求,当打开Activity界面时,开始倒计时,倒计时结束后跳转新的界面(思维活跃的朋友可能立马想到如果打开后自动倒计时,就类似于各个APP的欢迎闪屏页面),如下图: 可能觉得直接开启一个包含倒序循环的子线程就ok了,具体实现如下: activity_main <?xml version="

JMW1407的博客 6775

华为OD机试 - 单词倒序(Python/JS/C/C++ 2025 A卷 100分)

华为OD机试 2025A卷题库疯狂收录中,刷题。

学Java,找哪吒 1226

BAT031:按列表名单将路径a下的文件夹批量剪切到路径b

摘要:按列表名单将路径a下的文件夹批量剪切到路径b。

qq_31762031的博客 1218

安卓Handler的学习笔记哦

本文主要是对安卓handler的相关知识做一个小小的总结!

HumanAwake的博客 1192

【永磁同步电机】simulink永磁同步电机PMSM矢量控制【含Matlab源码 7372期】

simulink永磁同步电机PMSM矢量控制 完整的代码,方可运行;可提供运行操作视频!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 1028

安卓的Handler机制

Android Handler机制解析 Handler机制是Android实现线程间通信的核心框架,主要由四个关键组件构成: Handler:消息发送和处理的桥梁,负责发送消息(sendMessage)和处理消息(handleMessage) Message:消息数据结构,包含what、obj、arg1/arg2等字段 MessageQueue:消息队列,负责消息的存储和管理 Looper:消息循环,从队列中取出消息并分发 每个线程只能拥有一个Looper,通过ThreadLocal保证线程隔离。使用Han

weixin_44078411的博客 1169

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Android ‘Handler()‘ is deprecated

Android ‘Handler()‘ is deprecated

notthin的博客 3252

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

在Android Studio中遇到被弃用的函数 --Handler()

继昨天遇上个被弃用的FLAG_FULLSCREEN(参数)之后,今天又又又遇到被弃用的函数,就是Handler。那这个函数是干什么的呢?官方解释是:每个 Handler 实例都与单个线程和该线程的消息队列相关联。当你创建一个新的 Handler 时,它被绑定到一个Looper.它将消息和runnables 传递到该Looper 的消息队列并在该Looper 的线程上执行它们。Handler 有两个主要用途:(1)安排消息和可运行文件在未来某个时间点执行;(2) 将要在与您自己的线程不同的线...

L·lemon·L的博客 4645

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Android-Handler机制

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。上面分享的百度、腾讯、网易、字节跳动、阿里等公司2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。【Android思维脑图(技能树)】知识不体系?

2401_83817843的博客 864

【Android 开发】: Android 消息处理机制之三: Handler 中 sendMessage() 源代码剖析

在前面的两件中我们学习了Handler和Message的基本使用方法[Android消息处理机制之Handler与Message],还有Message中obtain()的几种重载方法的使用方式的不同[Android消息处理机制 Message中 btain()源代码剖析],这一讲我们来学习一下Handler中的sendMessage()的几种重载方法的使用方式的不同以及它们的源代码的剖析

AHuier_Techblog :如果我不在写代码,你就 @me 4万+

安卓消息机制之Handler基础知识

相信大家从网上也看到过Handler的代码解析,下面我将从我个人理解的角度,以尽量通俗易懂的语言带领大家对Handler的用法以及源码设计进行解读。

weixin_39330114的博客 1452

Android问题笔记八:关于‘constructor Handler()‘ is deprecated. Deprecated in Java

这是因为Handler的写法在新版本中已经不同了。是过时的方法,虽然影响不是很大,但是体验上有点别扭。

空名先生 2851

【Android 消息机制】Handler

Android专题学习-Handler总结

studyForMokey的博客 983
上一篇: Android学习笔记3:UDP广播通信程序
下一篇: Android学习笔记5:Android与ASP通过http协议交换数据
芯艺
博客等级 码龄21年 27粉丝 29原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值