从现实生活中理解线程消息机制
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 的线程机制。实现代码如下:
<!--<br/ />
<br/ />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />
http://www.CodeHighlighter.com/<br/ />
<br/ />
-->privateThreadthread;
privateTextViewtv_call_no;
protectedstaticRunnableRunablerun=null;
privateHandlerhandler;
privateinttextLength=0;
privatebooleanisStop=true;
首先将要使用的数据类型声明在头部,将会使用到 java 的 Thread 和Android Handler 对象,首先实现Runable 对象,代码如下:
<!--<br/ />
<br/ />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />
http://www.CodeHighlighter.com/<br/ />
<br/ />
-->Runablerun=newRunnable(){
@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
}
}
};
上面代码还可以如此写法:
<!--<br/ />
<br/ />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />
http://www.CodeHighlighter.com/<br/ />
<br/ />
-->Messagemsg=newMessage();
msg.arg1=i;
handler.sendMessage(msg);
第一种写法是message 从handler 类获取,从而可以直接向该handler 对象发送消息,第二种写法是直接调用 handler 的发送消息方法发送消息。不过不管是第一种方法好还是第二种方法好,都要在同样的handler 接收消息,否则会报异常。下面实现handler 对象,代码如下:
<!--<br/ />
<br/ />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />
http://www.CodeHighlighter.com/<br/ />
<br/ />
-->/**
*启动线程
*
*@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 事件,使其在弹出时停止递减:
<!--<br/ />
<br/ />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />
http://www.CodeHighlighter.com/<br/ />
<br/ />
-->/**
*点击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 异步消息机制的例子,详细讲解请看http://bbs.droidstouch.com/thread-70-1-1.html
Android中多线程的Handler的工作原理,其中涉及到MessageQueue和Looper。详情可以参见博客:http://www.cnblogs.com/plokmju/p/android_Looper.html
android多线程机制教程 android多线程机制 android多线程机制 android多线程机制
android 线程之间通过Handler发送消息实例
主要对handler 、message机制进行了详解,如果想了解更多android相关知识,可以去我博客看看
Android多线程及异步任务消息处理机制 一 Handler的使用博文源代码 想要学习更多有关于Android的知识 请关注博客http: blog csdn net yegongheng
使用处理程序延迟主线程上的工作;...我们看到,一个Message经由Handler的发送,MessageQueue的入队,Looper的抽取,又再一次地回到Handler的怀抱中。而绕的这一圈,也正好帮助我们将同步操作变成了异步操作。
NULL 博文链接:https://dingran.iteye.com/blog/1930178
这个demo介绍了通过Handler在线程之间传递消息,demo中一个三个线程,主线程,发送消息的分线程,接收消息的分线程。发送消息的分线程会通知主线程更改标签文字,同时会通知接收消息的分线程更改进度条的进度。
实现进度条自动滚动实例,使用到了Handler,thread,toast,消息队列,事务队列等方法,通过按钮控制进度条的运行,使用toast来提示当前状态信息。
NULL 博文链接:https://18767136122.iteye.com/blog/1988524
博客http://blog.csdn.net/two_water/article/details/49945525里面的Demo.
一个Android handler机制的Demo
android线程消息机制主要由Handler,Looper,Message和MessageQuene四个部分组成。平常在开发中,我们常用来在子线程中通知主线程来更新,其实整个安卓生命周期的驱动都是通过Handler(ActivityThread.H)来实现的。 ...
Android 的Handler消息传递机制.pdf 学习资料 复习资料 教学资源
程序功能说明:点击“开始”按钮后,文本框中的数字每隔1秒钟自动加1,当增加到100时就停止。 (Handler消息传递机制)
【Android开发入门】Android线程之Handler
Handler消息处理机制+面试说.md
在Android中使用AsyncTask和Handler线程间交互的方式,详情参见博客:http://www.cnblogs.com/plokmju/p/android_AsyncTask.html和http://www.cnblogs.com/plokmju/p/android_Handler.html