Android Handler,Loop,HandlerThread消息处理
博客标题也不知道写什么好,仅仅是近期有时候发现Handler,Loop,HandlerThread非常easy混淆,所以做了简单的笔记处理:
第一种 : 大概的意思给出说明图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
上面图中的模型,就平时非经常见的当须要更新UI时,通过Handler发送一个Message事件出去,可是Message事件的路径是先入了主线程的MessageQueue队列(通常是FIFO模式)中,
然后Looper就像一个永恒的发动机一样,不断的"循环"的去查询MessageQueue队列中是否有Message消息,假设查询存在,就会然其出队列来处理,因为这个消息队列是共用主线程中的(这句话非常重要)MessageQueue,所以它能够更新UI显示或者做一些其它的事情,主要还是更新UI较多(在主线程中).
另外一种:以下这一种事实上更具有普遍性
为什么说更具有普遍性,事实上能够想一想Activity事实上也相当于一个线程对象/或者封装了线程对象,我看了mMainThread等里面的消息循环,大致这么理解的.将理论非常难理解,
比方说,开发人员要向一个对象依次按顺序发送N个消息,第N-a个消息不能够在N-a-1个消息未运行完毕就開始,即保证前面一个消息运行完毕了,才干够运行下一个消息,平时开发中这种情况非经常见,可是要注意,假设我们在Activity中新建一个Thread线程,那就相当于独立于主线程之外,所以在这个线程中不能够处理更新UI等事情,可是却能够做非常多其它逻辑处理,并且它不会影响主线程的,它仅仅会在它自己的线程中按着顺序一个一个的运行.
第三种: 另一个HandlerThread,看了非常多例子,既然在Thread单词前面加上Handler,就和Handler扯上了关系,可是这个我自己还须要研究研究它正真的机制,仅仅知道这个东西新建以后,让其start,开发人员做一些更新UI或者其它事情,系统会安排在后台"慢慢"的帮开发人员完毕,即使事情里面加了延时也不用当心,他不会去堵塞主线程的.
以下给出一个測试程序验证一下:
<1> : 新建一个Androidproject:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
<2> : DurianMainActivity.java
package com.durian.handlerthread; import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast; public class DurianMainActivity extends Activity { private final static String TAG = "DurianMainActivity";
private TextView mTextView;
private TextView mTextViewA;
private TextView mTextViewB;
private TextView mTextViewC; private Button mButton;
private Button mButtonA;
private Button mButtonB;
private Button mButtonC; private HandlerThread mHandlerThread;
private HandlerThread mHandlerThreadA; private Handler mUIHandler;
private Handler mUIHandlerA = new Handler() { @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg); mNumCount++;
mTextViewA.setText("mNumCount : " + mNumCount); } }; private Handler mUIHandlerB=new Handler(){ @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg); try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} mTextViewB.setText("Number : "+mNumber++); Log.i(TAG,"Number : "+mNumber); } }; private int mLooperNum=0; private class LooperThread extends Thread{ public Handler mLooperHandler;
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
Looper.prepare();
mLooperHandler=new Handler(){ @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg); try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} Log.i(TAG,"mLooperNum : "+mLooperNum++);
//here is not UI thread
// mTextViewC.setText("mLooperNum : "+mLooperNum); } }; Looper.loop(); } } private LooperThread mLooperThread; private Handler mBackgroundHandler;
private Handler mBackgroundHandlerA; private int mCount = 0;
private int mNumCount = 0;
private int mNumber=0; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.durian_main); mTextView = (TextView) findViewById(R.id.durianview);
mTextView.setText("ui count : " + mCount); mTextViewA = (TextView) findViewById(R.id.durianaview); mTextViewB = (TextView) findViewById(R.id.durianbview); mTextViewC=(TextView)findViewById(R.id.duriancview); mLooperThread=new LooperThread();
mLooperThread.start(); mButtonC=(Button)findViewById(R.id.buttonC);
mButtonC.setOnClickListener(new OnClickListener(){ @Override
public void onClick(View v) {
// TODO Auto-generated method stub
Message msg=new Message();
msg.what=1;
mLooperThread.mLooperHandler.sendMessage(msg); } }); mButtonB=(Button)findViewById(R.id.buttonB);
mButtonB.setOnClickListener(new OnClickListener(){ @Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Thread(){ @Override
public void run() {
// TODO Auto-generated method stub
super.run();
Looper.prepare(); Message msg=new Message();
msg.what=100;
mUIHandlerB.sendMessage(msg); Looper.loop(); } }.start();
} }); mButtonA = (Button) findViewById(R.id.buttonA);
mButtonA.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub mBackgroundHandlerA.post(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
Message msg = new Message();
msg.what = 100;
mUIHandlerA.sendMessage(msg); } }); } }); mButton = (Button) findViewById(R.id.button);
mButton.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub mBackgroundHandler.post(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub for (int i = 0; i < 1; i++) { mUIHandler.post(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
mCount++;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mTextView.setText("ui count : " + mCount);
Log.i(TAG, "ui count : " + mCount); } }); } } }); } }); mHandlerThread = new HandlerThread("backgroun_thread_post");
mHandlerThread.start(); mHandlerThreadA = new HandlerThread("backgroun_thread_send");
mHandlerThreadA.start(); mBackgroundHandler = new Handler(mHandlerThread.getLooper()); mBackgroundHandlerA = new Handler(mHandlerThreadA.getLooper()); mUIHandler = new Handler(); } @Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy(); mHandlerThread.getLooper().quit(); } }
durian_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".DurianMainActivity" > <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/durianview"
android:text="@string/hello_world" /> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="start"
android:id="@+id/button"/> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/durianaview"
android:text="@string/hello_world" /> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="startA"
android:id="@+id/buttonA"/> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/durianbview"
android:text="@string/hello_world" /> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="startB"
android:id="@+id/buttonB"/> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/duriancview"
android:text="@string/hello_world" /> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="startC"
android:id="@+id/buttonC"/> </LinearLayout>
程序非常简答,运行点击相应的按钮,就能够測试上面的结论了.
另外看一下按钮StartB和StartC两个的差别,哪一个会产生并线操作的问题,哪个才是真正合理的.
Android Handler,Loop,HandlerThread消息处理的更多相关文章
- Android开发之异步消息处理机制Handler
更加详细的介绍Handler的博文-http://blog.csdn.net/guolin_blog/article/details/9991569 Android中的异步消息处理主要有四个部分组成, ...
- Android线程之异步消息处理机制(二)——Message、Handler、MessageQueue和Looper
异步消息处理机制解析 Android中的异步消息处理主要有四个部分组成,Message.Handler.MessageQueue和Looper. 1.Message Message是在线程之间传递的消 ...
- Android Handler消息处理顺序分析
看到Handler中的消息处理函数: public void dispatchMessage(Message msg){...} 这个函数是在Looper的执行消息循环loop()的时候取出Messa ...
- 【Android】IntentService & HandlerThread源码解析
一.前言 在学习Service的时候,我们一定会知道IntentService:官方文档不止一次强调,Service本身是运行在主线程中的(详见:[Android]Service),而主线程中是不适合 ...
- Android Handler处理机制 ( 二 ) ——Handler,Message,Looper,MessageQueue
Android是消息驱动的,实现消息驱动有几个要素: 消息的表示:Message 消息队列:MessageQueue 消息循环,用于循环取出消息进行处理:Looper 消息处理,消息循环从消息队列中取 ...
- 深入理解之 Android Handler
深入理解之 Android Handler 一,相关概念 在Android中如果通过用户界面(如button)来来启动线程,然后再线程中的执行代码将状态信息输出到用户界面(如文本框),这时候就会抛 ...
- Android Handler 机制总结
写 Handler 原理的文章很多,就不重复写了,写不出啥新花样.这篇文章的主要是对 handler 原理的总结. 1.Android消息机制是什么? Android消息机制 主要指 Handler ...
- Android handler 详解(面试百分之100问到)
handler在Android中被称为“消息处理者”,在多线程中比较常用. handler内部实现原理 handler实现机制:1,Message对象,表示要传递的一个消息,内部使用链表数据结构实现一 ...
- [Android]Handler的消息机制
最经面试中,技术面试中有一个是Handler的消息机制,细细想想,我经常用到的Handler无非是在主线程(或者说Activity)新建一个Handler对象,另外一个Thread是异步加载数据,同时 ...
随机推荐
- Linux音频编程
1. 背景 在<Jasper语音助理介绍>中, 介绍了Linux音频系统, 本文主要介绍了Linux下音频编程相关内容. 音频编程主要包括播放(Playback)和录制(Record), ...
- 用js和jQuery做轮播图
Javascript或jQuery做轮播图 css样式 <style> a{ text-decoration:none; } .naver{ width: 100%; position:r ...
- 【 Tomcat 】tomcat8.0 基本参数调优配置
1.优化内核及TCP连接: fs.file-max = # 系统文件描述符总量 net.ipv4.ip_local_port_range = # 打开端口范围 net.ipv4.tcp_max_tw_ ...
- Delphi New,Getmem,ReallocMem联系与区别
来自:http://www.cnblogs.com/jsrgren/archive/2011/10/31/2270353.html ---------------------------------- ...
- EA(Enterprise Architect) UML 建模之活动图
一.活动图的概念作用 活动图本质上是一种流程图,它描述活动的序列,即系统从一个活动到另一个活动的控制流. 活动图的作用:描述用例 . 描述类的操作.描述算法(单独使用) 二. 活动图的基本符号 ...
- mysql 游标的使用
游标是什么?? 游标是一个存储在MySQL服务器上的数据库查询,它不是一条select语句,而是被该语句所检索出来的结果集. 使用游标 在介绍如何创建游标之前,先说明下如何使用游标. 使用游标涉及几个 ...
- MySQL 使用硬链接配合truncate 删除2.2T的表
1 创建tmp 表并 rename 表 mysql> rename table ep to ep_bak; Query OK, 0 rows affected (0.07 sec) mysql& ...
- UESTC 30.最短路-最短路(Floyd or Spfa(链式前向星存图))
最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同 ...
- mysql 查看表结构方法
留给自己备查: mysql 导出为 csv 文件时如果直接使用导出命令是无法导出表结构的, 因此我们需要能够查询表结构的方法: 方法如下: 1.desc(描述)命令 desc tablename;de ...
- 【LeetCode刷题】SQL-Combine Two Tables
Table: Person +-------------+---------+ | Column Name | Type | +-------------+---------+ | PersonId ...