图解 Android Handler 线程消息机制
从现实生活中理解线程消息机制
android 有一种叫消息队列的说法,这里我们可以这样理解:假如一个隧道就是一个消息队列,那么里面的每一部汽车就是一个一个消息,这里我们先忽略掉超车等种种因素,只那么先进隧道的车将会先出,这个机制跟我们android 的消息机制是一样的。
Android 的线程消息机制
android 在设计的时候引入了 wince 的消息机制,即将每一个消息发送到队列里面,遵循先进先出原则。发送消息并不会阻塞线程,而接收线程会阻塞线程,这是因为 Android 的Handler 机制,当Handler 处理完一个 Message 对象才会接着去取下面一个消息进行处理,如下图:
这里记住:Android里并没有Global的Message Queue数据结构,例如,不同APK里的对象不能透过Massage Queue来交换讯息(Message)。例如:线程A的Handler对象可以传递消息给别的线程,让别的线程B或C等能送消息来给线程A(存于A的Message Queue里)。线程A的Message Queue里的讯息,只有线程A所属的对象可以处理。
案例分析:
经典的歌词同步,这时我们不仅要听到优质的歌曲,还要可以有歌词同步,这时另开一条线程来处理歌词的同步是比较好的解决办法,你可以根据自己的定义,抓取歌曲的duration 在线程中处理歌词的前进或者后退。。。
Demo 分析:
下面我们来实现一个Iphone 上的一个通过按数字后,数字过多消除的按钮事件。事件的原理如下,事件要的效果是这样的,当长按消除按钮后,数字会慢慢消除,过会消除速度会增快,那么实现这个效果我们就需要自己做一个小键盘,我做的键盘效果如下:
我们通过点击来达到这个效果,使用的是android 的线程机制。实现代码如下:
privateTextViewtv_call_no;
protectedstaticRunnableRunablerun=null;
privateHandlerhandler;
privateinttextLength=0;
privatebooleanisStop=true;
首先将要使用的数据类型声明在头部,将会使用到 java 的 Thread 和Android Handler 对象,首先实现Runable 对象,代码如下:
@Override
publicvoidrun(){
//TODOAuto-generatedmethodstub
try{
inti=0;
do{
i++;
Thread.sleep(i>15?20:100);
Messagemsg=handler.obtainMessage();
msg.arg1=i;
msg.sendToTarget();
if(i==textLength){
isStop=false;
}
}while(isStop);
}catch(Exceptione){
//TODO:handleexception
}
}
};
上面代码还可以如此写法:
msg.arg1=i;
handler.sendMessage(msg);
第一种写法是message 从handler 类获取,从而可以直接向该handler 对象发送消息,第二种写法是直接调用 handler 的发送消息方法发送消息。不过不管是第一种方法好还是第二种方法好,都要在同样的handler 接收消息,否则会报异常。下面实现handler 对象,代码如下:
*启动线程
*
*@paramtv
*@paramtext
*@return
*/
publicHandlergetHandler(finalTextViewtv,finalStringtext){
Handlerhand=newHandler(){
publicvoidhandleMessage(Messagemsg){
tv.setText(text.substring(0,text.length()-msg.arg1));
super.handleMessage(msg);
};
};
returnhand;
}
这里返回一个handler 对象,实际上是返回去给上面我们的handler 对象使用,这里我把它封装成一个方法,可以让它在每次接收到消息后去使用消息处理文本每次减1
设置的 onTouch 事件,使其在弹出时停止递减:
*点击back删除之前的数据,跳出就停止删除
*/
OnTouchListenerontouch=newOnTouchListener(){
@Override
publicbooleanonTouch(Viewv,MotionEventevent){
//TODOAuto-generatedmethodstub
Stringtext=tv_call_no.getText().toString();
if(text.length()==0){
isStop=false;
returnfalse;
}
switch(event.getAction()){
caseMotionEvent.ACTION_DOWN:
isStop=true;
textLength=tv_call_no.getText().length();
handler=getHandler(tv_call_no,text);
thread=newThread(Runablerun);
thread.start();
break;
caseMotionEvent.ACTION_UP:
isStop=false;
break;
}
returnfalse;
}
};
小结:
- 1、向哪个Handler 发送消息,就必须在哪个handler 里面接收;
- 2、直接使用JAVA 的 Thread 是无法更新Android UI的,因为Android View 在设计的时线程是不完全的,不过Android 提供了几种供开发者在线程中更新UI的方法,如下:
- Activity.runOnUiThread( Runnable )
View.post( Runnable ) View.postDelayed( Runnable, long ) Hanlder 3、直接使用hanlder .post 等方法是在当前主线程里面做操作,而不是另外新建线程,建议使用Thread 线程直接新建另外一个线程或者使用HandlerThread类也可以。 4、记住消息队列的先进先出原则。
图解 Android Handler 线程消息机制相关推荐
- [Android]Handler的消息机制
最经面试中,技术面试中有一个是Handler的消息机制,细细想想,我经常用到的Handler无非是在主线程(或者说Activity)新建一个Handler对象,另外一个Thread是异步加载数据,同时 ...
- Android:Handler的消息机制
前言 Android 的消息机制原理是Android进阶必学知识点之一,在Android面试也是常问问题之一.在Android中,子线程是不能直接操作View,需要切换到主线程进行.那么这个切换动作就 ...
- 浅析Android中的消息机制
在分析Android消息机制之前,我们先来看一段代码: [java] view plaincopy public class MainActivity extends Activity impleme ...
- Android中的消息机制
Android 中的消息机制其实就是指的是 Handler 消息机制以及附带的 Looper 和 MessageQueue 的工作流程. 1.Android 为什么提供Handler? 解决子线程不能 ...
- 重温Android中的消息机制
引入: 提到Android中的消息机制,大家应该都不陌生,我们在开发中不可避免的要和它打交道.从我们开发的角度来看,Handler是Android消息机制的上层接口.我们在平时的开发中只需要和Hand ...
- android return 如何跳出两个循环_关于不得不学的Android知识之消息机制
概述 相信不管是出入Android,还是已开发多年的老司机们,肯定都对Android的Handler不会陌生,而它就是今天要介绍的Android消息机制中的一部分.在Android系统中,有两大特色利 ...
- Android Handler 异步消息处理机制的妙用 创建强大的图片载入类
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38476887 ,本文出自[张鸿洋的博客] 近期创建了一个群.方便大家交流,群号: ...
- Android中的消息机制:Handler消息传递机制
参考<疯狂android讲义>第2版3.5 P214 一.背景 出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为 ...
- Android中使用Handler(消息机制)造成内存泄露的分析和解决
问题描述: Handler 内部类持有 外部类Activity的引用,如果Activity退出而Handler还有延迟处理的消息没有处理完,会导致Activity不能回收,反复如此会导致内存泄露. 解 ...
最新文章
- threshold 二值化的实现
- sql的四种连接 用mysql的语句写_170221、浅谈mysql的SQL的四种连接
- linux自学笔记——RAID级别特性以及软RAID的实现
- 匿名发差评被判赔3272元,北京研究生遭遇冲上热搜,涉事机构回应:暂不澄清...
- gaokao--选择开发什么项目
- 织入业务代码-LogAspect
- 程序员千万不要做舔狗啊!
- 使用Nacos搭建微服务注册中心和配置中心(二)
- ZooKeeper 数据模型
- centos中mysql启动失败,解决CentOS下mysql启动失败
- mongo 字段重命名
- do while 执行1次
- 常用触摸屏485通讯引脚及下载口
- 重庆市计算机考试题库,重庆市计算机一级题库
- 每日哲学与编程练习3——无重复数字(Python实现)
- mysql计算工作日函数_SQL实现工作日计算_MySQL
- 如何用python画爱心型线_如何用python画爱心
- 悲剧!Google华裔“网红”炫耀公司福利,突然被裁了!
- Web前端持续集成方案(四)
- 网络安全宣传月安全团队需要知道的关于PKI的九件事
热门文章
- 《区块链开发指南》一一导读
- 萨纳斯耿文强:光伏管控智能化亟待统一标准
- DiskFileItemFactory类的使用
- javabean实体类对象转为Map类型对象的方法
- ArchLinux借助Winetricks-zh安裝WineQQ8.1
- Oracle PLSQL Demo - 04.数字FOR LOOP循环[NUMBERABLE (FOR) LOOP]
- struts2入门操作
- 【转】Galileo伽利略项目-- 数字城市规划和基础设施建模
- 工厂方法(FactoryMethod)模式
- 如何查看单元测试的结果 以及异常处理