有些两三年工作经验的同学对于handler还处在滥用的状态,所以写这篇文章总结一下handler的几点。
首先强调,handler不是线程,很多初学者甚至有点经验的都把handler当成线程来看待,以为用上handler就开启线程操作了,这是不对的。还有一种用法是,用上handler就以为一定是在UI线程中操作了,也不太对。

那么Handler是什么?
Handler是一个事件操作的处理对象,在命令模式中是充当命令处理者的角色。它是一个任务的执行者,依附在线程中进行具体的任务处理。它是一个普通的Object对象,在指定的线程中执行它的handleMessage方法而已,跟线程其实并没有太多关系,只是任何方法都需要在线程中运行。

Hanlder不一定在UI线程中执行:
一般Handler都是用来做UI操作的,但并不代表用上Handler就表示一定可以进行UI操作。你可能在非Activity的类的方法中写了这样一句代码:

public void xxx(){new Handler().post(new Runnable(){public void run(){textView.setText("abc");}});
}

如果你一不小心在工作线程中调用了xxx()方法,你的app可能会产生崩溃。这里有两个问题,一是创建的handler并无绑定的looper对象或者未开启loop()方法,报错如下:

 java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

二是该handler的创建是在工作线程中,即使looper对象是prepared且开启了loop循环,该处代码也会因为loop()方法(也即handler处理消息)不是执行在UI线程中却进行UI操作而报错。如果需要保证在UI线程中执行,handler的创建需在主线程中,或者主动传入主线程的looper对象:

new Hanlder(Looper.getMainLooper())

Hanlder使用场景
Handler常见用途有两种:
一是异步线程通知回调主线程事件;
二是发起延时的UI操作任务;
Handler为异步而生,但在一个成熟的app中,应当有独立的异步处理的工具类,这个工具类应是有线程池操作的,而不是随意的使用new thread + handler post方式来进行异步操作,无论从代码整洁性还是可能带来的其它性能问题方面考虑。

Handler的内存泄露问题
这个是android4.0开始,当你使用handler时adt会自动发出可能引起内存泄露的警告。原因是如果你使用handler发送了延迟的消息或者因其它原因导致的handleMessage执行开始之前,activity已经执行了finish()方法,这个时候会由于handler持有外部类activity的引用而导致acitivty无法被GC回收引起内存泄露。你需要在ondestroy()中调用下面这句代码:

mHandler.removeCallbacksAndMessages(null);

当然这句代码可能会忘记添加,所以我更推荐直接使用WeakHandler,它使用弱引用来规避了内存泄露的的问题:https://github.com/badoo/android-weak-handler

由Handler创建消息对象的正确方法
平时创建消息Message可能是直接new message()

官方提示:

the preferred way to get a Message is to call {@link #obtain() Message.obtain()

推荐使用

handler.obtainMessage()
or
Message.obtain()

Message类中使用了Recycle机制 ,它的obtain方法会复用仓库中暂时无用的message对象,避免重新创建新的对象而造成更多的性能消耗。

Android Hanlder综合相关推荐

  1. 移动开发技术(Android)——综合实验

    移动开发技术(Android)--综合实验 一.MainActivity的设计 1.activity_main布局文件显示效果如下图所示: 2.MainActivity实现的功能,要求如下: 二.De ...

  2. 安卓Android校园综合服务系统校园帮app

    校园综合服务系统是一个学校学生生活中不可缺少的一部分,给学校的学生日常生活能够带来方便.随着互联网的不断发展网上服务系统的更趋向于成熟化,系统应该为用户提供更加方便的日常服务方式.而计算机的不可移动性 ...

  3. Android初学者综合应用——猜拳游戏

    我是一个技术爱好者,不光是移动开发,还是画简单的插画,都与专业人士不相上下.这次我专门利用业余时间,借鉴参考书上的代码,自己编写了电脑猜拳游戏,以飨Android移动开发初学者. 猜拳游戏的界面如下图 ...

  4. Android Hanlder的理解

    Handler 中有四个关键类 Message Handler MessageQueue Looper 介绍一下这四个类的作用 Message Meaage实现了Parcelable接口,从这里就可以 ...

  5. 关于 Android 进程保活,你所需要知道的一切

    早前,我在知乎上回答了这样一个问题:怎么让 Android 程序一直后台运行,像 QQ 一样不被杀死?.关于 Android 平台的进程保活这一块,想必是所有 Android 开发者瞩目的内容之一.你 ...

  6. 九个角度分析对比 Android、iOS开发区别

    对于创业的人来讲,选择Android还是iOS是一个棘手的问题.有数据显示Android 的市场份额突破80%.有不少人会觉得开发者在两个平台之间的选择就更加容易,毕竟市场决定利润.但事实上并非如此. ...

  7. github上万颗star的21个JAVA(19个Android相关)开发框架,知道多少,用过多少

    相关阅读: 吊炸天!74款APP完整源码! 2016移动端Android新技术综合预览--好文不多,这一篇就足够 移动端App开发的三种开发技术对比 Java和Android架构 欢迎关注我们,一起讨 ...

  8. android的自我评价,2021年ANDROID软件工程师的自我评价

    <2021年ANDROID软件工程师的自我评价>由会员分享,可在线阅读,更多相关<2021年ANDROID软件工程师的自我评价(4页珍藏版)>请在人人文库网上搜索. 1.and ...

  9. Android 源码

    自:http://www.juapk.com/thread-496-1-1.html  巨卓网开发论坛 费了九牛二虎之力才整理完.亲!如对您有用的话就收藏吧!!(欢迎转载) Android 代码仓库目 ...

最新文章

  1. 使用Ubuntu的公用文件夹轻松地在计算机之间共享文件
  2. 掌握java_如何才算掌握Java,大家都掌握到什么程度
  3. Android 使用控件自定义背景实例
  4. linux+free参数类型,linux的free命令
  5. oracle 日期 加一秒,Leap Second (闰秒) 在ORACLE环境的影响
  6. redhat7.3 启动系统报,A start job is running for Apply Kernel Variables的处理
  7. python 获取参数模块_Python中获取启动程序时后面跟的参数的方法(optparse模块)【冰斌棒】...
  8. Flask 框架 是 Python 中最流行的 Web 框架之一
  9. delphi 多个线程 多个进度条_Python 进阶知识全篇-多线程
  10. 端到端车道线检测_弱监督对象检测-端到端培训管道
  11. AT指令集及其通信测试方式
  12. d3d示例程序_3D打印改变我们现实的10个示例
  13. linux 下载工具
  14. 机械原理c语言程序,机械原理课程设计心得体会范文
  15. PHP与ECMP,2019 NECMP东北音乐产业发展论坛在沈举行
  16. java常见单词汇总3(非常使用哦)
  17. 啊哈添柴挑战Java1222. 输出菱形
  18. Sklearn实现非线性回归
  19. 【视觉高级篇】23 # 如何模拟光照让3D场景更逼真?(上)
  20. PTA拼题A2023跨年挑战赛

热门文章

  1. 5.Ubuntu下的GIF录制软件peek安装
  2. React组件继承的由来
  3. [CQOI2011]动态逆序对
  4. 使用 markdown-it 解析 markdown 代码(读 VuePress 三)
  5. defensive-bash-programming
  6. 图形上下文的栈操作(保存和恢复)
  7. PostgreSQL9.5:pg_rewind 快速恢复备节点
  8. 解决ERROR 2003 (HY000): Can't connect to MySQL server on
  9. iOS开发CoreAnimation解读之四——Layer层动画内容
  10. GSM协议编号及其内容