Handler的简单实用和介绍
来源:互联网 发布:2017剑灵人男捏脸数据 编辑:程序博客网 时间:2024/06/03 15:15
前奏:
在Android开发中,我们常常会使用单独的线程来完成某些操作,比如用一个线程来完成从网络上下载图片然后显示到一个ImageView中,但是我们往往会遇到以下的经典的错误提示:
Only the original thread that created a view hierarchy can touch its views.错误信息 //只有原始的创建他的线程才能去更新ui
也就出现了在多线程操作时,Android必须保证以下两点:
- 1、不要阻塞UI线程
- 2、不要在UI线程之外访问Android UI工具包(禁止非UI线程更新UI)
那么这个时候我们就可以通过一个轻量级的Handler来解决我们的这个问题了哈。怎么解决呢,这个地方我们先上一段解决方案,具体的介绍在说。(这里有个隐患,先留着,如果你已经知道了,那么很厉害哈,我也是刚知道怎么回事呢)
@Override public void onClick(View v) { new Thread(new Runnable() { @Override public void run() { while (true) { try { //这里我们只是简单的模拟一下下载3000秒后通知刷新ui Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } break; } mHandler.sendEmptyMessage(100); //这里我建议大家去看下官网handler的介绍,发送消息有很多方法呢,延迟,直接发送。在这里只是简单的使用了一种发送空消息 } }.start();
通过以上的简单的代码逻辑,我们就可以完成我们在UI线程中更新UI了。是不是挺方便的。
好了接下来,就来看下什么是Handler和和Handler有关的几个类吧。
Handler实现机制:
**Android启动程序的时候会在UI线程创建一个MessageQueue。**
我们来看下他们几个的图形相关信息:
在来看下他们几个的关系;
- 1、message 消息对象,内部使用链表结果实现一个消息池,用于重复利用,避免大量的创建消息,造成内存浪费
- 2、handler 消息处理着,通过该对象把消息存入消息队列中,并且最后通过handlerMessage方法来处理消息
- 3、MessageQueue 消息队列,用于存储Message消息对象的数据结构,先进先出
- 4、Looper 消息轮寻器,用于循环检查消息队列中是否有消息,如果有消息就取出来,然后传递给handlerMessage方法中等待处理
想必这个时候,大家应该对于handler机制有了一定的了解,不过建议大家可以去看下源码,把他们的流程走一下,应该会有不错的认识。这里就不带着走源码了。
背景颜色引发的内存泄露问题:
想必大家在刚开始看的时候,已经发下了我所说的,这一段代码有点问题吧,我刚开始使用也不知道,想着是故意这样的呢,也就没太注意,有的时候看其他人写的blog,有介绍的,当时也没有太注意,只是知道是内存泄露(今天关于内存泄露不过多说(我也不是很明白的哈)望谅解),但是昨天同学问我的时候,我也只是说了句内存泄露,但是并不能很好的解释,给他找了资料,让他自己研究去了,有幸今天我有点空,就来研究一下。我们先来看下图:
这个地方是不是颜色和其他地方不一样呢,我们把鼠标放到handlerMessage上面按下ctrl + f1(win) ,出现以下解释:
大概的意思就是handler定义一个内部类的时候,对于这个外部类来说,造成了引用,来阻止外部类被回收,如果handler使用了Looper或者MessageQueue在子线程而非main线程,那么久没有问题,但是如果是在main线程中,你就要做出如下的改变了,声明为静态的,然后在外部类中实例化WeakReference 的外部类,然后在实例化这个处理程序的时候,传入这个引用对象。
这个时候我们就要了解一java的四种引用了,在这推荐一篇
http://blog.csdn.net/coding_or_coded/article/details/6603549
那么既然这样提示了,我们就来修改吧。
Handler内存泄露的问题:
内部类会持有外部类的引用,也就是handler会获取到当前类的引用,内部类的对象要依赖于外部类的额对象,如果要退出activity,那么这个对象就要销毁,但是handler还在工作,获取到引用,那么这个时候就不能退出(我的handler还在工作(必须等待handler处理完成))。
- 1、定义一个内部类的时候,会默认拥有外部类对象的引用,所以建议使用内部类的时候,最好定义为一个
- 2、需要用到弱引用 强引用》》软引用》》弱引用
好了,我们看下最后的修改的代码,为了直观看到解决问题,我这里截图来看下,是不是没有暗黄色背景了哈。(代码风格统一,处女座的热爱(我不是哈))
我们来看下怎么使用吧。
//这个时候我们就可以使用handler里面的各种暴漏的方法了哈 //使用handler延迟执行一个runnable(10分钟) mMyHandler.postDelayed(new Runnable() { @Override public void run() { Log.d("Main2Activity", "handler"); } }, 1000 * 60 * 10);
好了,今天就到这了哈,有问题可以讨论哈。
- Handler的简单实用和介绍
- Handler的简单介绍和使用
- 简单的介绍handler
- Android Handler的简单介绍
- Handler的简单使用介绍
- Handler的介绍和使用方法
- AsyncTask 和 handler的介绍
- Android基础--Handler的使用简单介绍
- Handler的介绍及简单使用
- 安卓学习之路之Handler的简单实用
- xheditor文本编辑器的简单实用介绍
- 15_android-WebView的简单实用介绍
- protocol的介绍与简单实用
- category的介绍与简单实用
- CocosPod 简单实用介绍
- iOS设计模式之KVO Key-Value Observing 键值观察者模式的简单实用和介绍
- 关于Handler存在的理由和简单的Handler机制!
- android学习笔记之handler简单实用
- Xcode-快捷键
- 常规阻抗控制只能是10%的偏差(二)
- 选择排序法
- SpringMVC与Struts2的比较
- RxJava 过滤操作符 skip,skipLast,task,takeLast
- Handler的简单实用和介绍
- 使用FreeImage来进行Qt图片的读入
- java String.split 传入参数为正则表达式
- 网页布局基础浅谈
- 新页面的的建立
- Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系
- 计算机视觉:让冰冷的机器看懂多彩的世界
- 给虚拟表添加id(给视图加个id)
- 杂文_语录