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是异步加载数据,同时 ...
随机推荐
- Golang在视频直播平台的高性能实践(含PPT下载)
熊猫 TV 是一家视频直播平台,先介绍下我们系统运行的环境,下面这 6 大服务只是我们几十个服务中的一部分,由于并发量与重要性比较高,所以成为 golang 小试牛刀的首批高性能高并发服务. 把大服务 ...
- [Leetcode Week3]Clone Graph
Clone Graph题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/clone-graph/description/ Description Clon ...
- Linux下安装mantis配置指南【转】
转自:http://blog.csdn.net/xabc3000/article/details/6858229 目录(?)[-] Linux下安装mantis配置指南 配置Linux下的Apache ...
- twitter api取出的日期格式化
import pickle import datetime crate_time_list=[] twitter_id_list=[] twitter_url_list=[] twitter_text ...
- mvn常用的构建命令
mvn -v 查看maven版本 mvn compile 编译 mvn test 测试 mvn package 打包 mvn clean 删除target mvn install 安装jar包到本地仓 ...
- Oracle 10g 安装环境配置脚本
#!/bin/bash #Test in RHEL 5.5 for 10g c=`cat /etc/shadow | grep oracle | wc -l`if [ $c != 0 ]then w ...
- ATM+购物车系统
ATM目录 start.py import os,sys from core import src base_path=os.path.dirname(os.path.dirname(__file__ ...
- grep 所有多个关键字
标签(空格分隔): Linux 多个关键字 或 关系 egrep 'CommentManager|getComment' --color catalina.log.2017-03-15 grep -E ...
- MySQL阅读笔记
左连接:包含所有的左边表中的记录甚至是右边表中没有和它匹配的记录.右连接:包含所有的右边表中的记录甚至是左边表中没有和它匹配的记录. select ename,deptname from emp le ...
- hit2739
好题,回路的问题一般都要转化为度数来做若原图的基图不连通,或者存在某个点的入度或出度为0则无解.统计所有点的入度出度之差di对于di>0的点,加边(s,i,di,0):对于di<0的点,加 ...