Android的消息处理机制,handler,message,looper(一)
当应用程序启动时,Android首先会开启一个主线程(也就是UI线程),主线程为管理界面中的UI控件。在程序开发时,对于比较耗时的操作,通常会为其开辟一个单独的线程来执行,以尽可能减少用户的等待时间。在Android中,默认情况下,所有的操作都是在主线程中进行的,主线程负责与UI相关的事件。而在自己新建的线程中,不能对UI进行操作。因此Android提供了消息处理传递机制来解决这一问题。
一、几个概念:
Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。Message是线程之间传递信息的载体,包含了对消息的描述和任意的数据对象。Message中包含了两个额外的 int字段和一个object字段,这样在大部分情况下,使用者就不需要再做内存分配工作了。虽然Message的构造函数是public的,但是最好是使用Message.obtain( )或Handler.obtainMessage( )函数来获取Message对象,因为Message的实现中包含了回收再利用的机制,可以提供效率。
MessageQueue:简单的说就是用来存放Message,但是Message是由Looper来分发的,Message不能直接添加到MessageQueue中,而是要通过与Looper关联的Handler去添加。其中的Message是由Looper来分发的,Message不能直接添加到MessageQueue中,而是要通过与Looper关联的Handler去添加。
Looper:用来循环读取存放于MessageQueue中的消息。一个线程对应一个Looper,一个Looper对象对应一个MessageQueue。Android中新增的线程是没有开启消息循环的,需要在线程中调用perpare函数,然后调用loop去处理消息。主线程除外。系统自动为主线程创建Looper对象。
Handler:实现消息的发送以及处理,负责发送用户消息以及调用用户注册的callback或接口进行消息处理。因此每个消息肯定有一个对应的handler,否则消息无法被发送/处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。
二、消息机制的原理:
现Message机制需要Handler、Message、Looper三个之间的互相作用来实现;当线程A需要发消息给线程B的时候,线程B要用自己的Looper实例化Handler类,就是构造handler对象时,把当前线程的Looper传给Handler构造函数,handler本身会保存对Looper的引用,handler构造好以后,就可以用handler的obtainMessage方法实例化Message对象,只要把要传的数据给Handler,Handler就会构造Message对象,并且把Message对象添加到消息队列里面。然后就可以调用handler的sendMessage方法把Message对象发送出去,Looper就把消息放到消息队列中;最后当Looper知道消息队列不为空时候,就会循环的从消息队列中取消息,取出消息就会调用刚才实例化好的Handler对象的handleMessage方法取处理消息,整个Message过程就是这样。
三、第一个例子:
UI上两个button,点击不同button的时候显示不同的文本:
MainActivity.java
package com.zdx.messagetest; import java.security.spec.MGF1ParameterSpec; import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; public class MainActivity extends Activity {
public boolean clickIF,threadBoolean=false;
private Button bt_success,bt_failed;
private TextView tv_textShow; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_textShow = (TextView) findViewById(R.id.tv_show);
}
public void showSuccess(View v){
threadBoolean=false;
clickIF=true;
Log.i("zdx", "clickIF为true");
LoThread loThread = new LoThread();
Thread mThread = new Thread(loThread);
mThread.start(); }
public void showFailed(View v){
threadBoolean=false;
clickIF=false;
Log.i("zdx", "clickIF为false");
LoThread loThread = new LoThread();
Thread mThread = new Thread(loThread);
mThread.start(); } private Handler mHandler = new Handler(){ @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch(msg.what){
case 0:
tv_textShow.setText(String.valueOf(msg.obj));
threadBoolean=true;
break;
case 1:
tv_textShow.setText(String.valueOf(msg.obj));
threadBoolean=true;
break;
}
}
};
private class LoThread implements Runnable{ @Override
public void run() {
// TODO Auto-generated method stub
while(!threadBoolean){
Looper.prepare();
if(clickIF)
{
String successful = "成功";
Message messages = mHandler.obtainMessage(0, successful);
messages.sendToTarget();
Log.i("zdx", "成功");
}
else
{
String failure = "失败";
Message messages = mHandler.obtainMessage(1, failure);
messages.sendToTarget();
Log.i("zdx", "失败");
}
if (threadBoolean) {
Thread.currentThread().interrupt();
}
Looper.loop();
}
}
}
}
activity_main.xml
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.zdx.messagetest.MainActivity" > <LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" > <Button
android:id="@+id/bt_success"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="@string/s_successful"
android:onClick="showSuccess"/> <Button
android:id="@+id/bt_failed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="@string/s_failure"
android:onClick="showFailed"/>
</LinearLayout> <TextView
android:id="@+id/tv_show"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentLeft="true"
android:layout_below="@+id/linearLayout1"
android:layout_marginTop="17dp"/> </RelativeLayout>
Android的消息处理机制,handler,message,looper(一)的更多相关文章
- (转)Android消息处理机制(Handler、Looper、MessageQueue与Message)
转自 http://www.cnblogs.com/angeldevil/p/3340644.html Android消息处理机制(Handler.Looper.MessageQueue与Messag ...
- Android消息处理机制(Handler、Looper、MessageQueue与Message)
Android是消息驱动的,实现消息驱动有几个要素: 消息的表示:Message 消息队列:MessageQueue 消息循环,用于循环取出消息进行处理:Looper 消息处理,消息循环从消息队列中取 ...
- 转 Android的消息处理机制(图+源码分析)——Looper,Handler,Message
作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习google大牛们的设计思想.android源码中包含了大量的设计模式,除此以外,android sdk还精心为我们设计了各种 ...
- 【转】android的消息处理机制(图+源码分析)——Looper,Handler,Message
原文地址:http://www.cnblogs.com/codingmyworld/archive/2011/09/12/2174255.html#!comments 作为一个大三的预备程序员,我学习 ...
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
android源码中包含了大量的设计模式,除此以外,android sdk还精心为我们设计了各种helper类,对于和我一样渴望水平得到进阶的人来说,都太值得一读了.这不,前几天为了了解android ...
- 从Handler+Message+Looper源代码带你分析Android系统的消息处理机制
PS一句:不得不说CSDN同步做的非常烂.还得我花了近1个小时恢复这篇博客. 引言 [转载请注明出处:http://blog.csdn.net/feiduclear_up CSDN 废墟的树] 作为A ...
- Android之消息机制Handler,Looper,Message解析
PS:由于感冒原因,本篇写的有点没有主干,大家凑合看吧.. 学习内容: 1.MessageQueue,Looper,MessageQueue的作用. 2.子线程向主线程中发送消息 3.主线程向子线程中 ...
- Android Handler处理机制 ( 一 )(图+源码分析)——Handler,Message,Looper,MessageQueue
android的消息处理机制(图+源码分析)——Looper,Handler,Message 作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习 google大牛们的设计思想. ...
- 《Android进阶》之第三篇 深入理解android的消息处理机制
Android 异步消息处理机制 让你深入理解 Looper.Handler.Message三者关系 android的消息处理机制(图+源码分析)——Looper,Handler,Message an ...
- Android异步消息处理机制(多线程)
当我们需要执行一些耗时操作,比如说发起一条网络请求时,考虑到网速等其他原因,服务器未必会立刻响应我们的请求,如果不将这类操作放在子线程里去执行,就会导致主线程被阻塞住,从而影响用户对软件的正常使用. ...
随机推荐
- 【jmeter】ANT批量执行Jmeter脚本
一.环境准备: 1.Jdk1.6或以上:命令行输入:java -version,出现如下提示说明安装成功 2.ANT下载:http://ant.apache.org/bindownload.cgi 命 ...
- visual studio 编译时 出现 Files 的值 乱码
参考了:http://blog.163.com/jiang_tao_2010/blog/static/121126890201031031337332/ 最近在做程序时,在生成解决方法过程中,电脑出现 ...
- LintCode "Binary Representation"
Not hard to think of a solution. But the key is all details. class Solution { public: /** *@param n: ...
- bzoj1346: [Baltic2006]Coin
Description 有一个国家,流通着N种面值的硬币,其中包括了1分硬币.另外,有一种面值为K分的纸币,它超过了所有硬币的面值. 有一位硬币收藏家,他想收集每一种面值的硬币样本.他家里已经有一些硬 ...
- android学习笔记12——ListView、ListActivity
ListView.ListActivity ==> ListView以垂直列表的形式显示所有列表项. 创建ListView的方式: 1.直接使用ListView创建 2.Activity继承Li ...
- working copy locked 问题
解法 1 : 右键svn-->clean up 解法 2 : 被lock的文件夹进入控制台 del lock /q/s [转载解法] SVN 本地更新时,由于一些操作中断更新,如磁盘空间不够 ...
- C#托管代码与C++非托管代码互相调用
http://www.cnblogs.com/Jianchidaodi/archive/2009/03/11/1407270.html#1473515 http://www.cnblogs.com/J ...
- Workflow_如何处理标准异常和自定义异常(案例)
2014-05-31 Created By BaoXinjian
- POJ 3162 Walking Race 树形DP+线段树
给出一棵树,编号为1~n,给出数m 漂亮mm连续n天锻炼身体,每天会以节点i为起点,走到离i最远距离的节点 走了n天之后,mm想到知道自己这n天的锻炼效果 于是mm把这n天每一天走的距离记录在一起,成 ...
- linux命令(4):top 命令(性能分析工具)
linux 的top命令详解 简介 top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器. top显示系统当前的进程和其他状况,是一个 ...