当应用程序启动时,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(一)的更多相关文章

  1. (转)Android消息处理机制(Handler、Looper、MessageQueue与Message)

    转自 http://www.cnblogs.com/angeldevil/p/3340644.html Android消息处理机制(Handler.Looper.MessageQueue与Messag ...

  2. Android消息处理机制(Handler、Looper、MessageQueue与Message)

    Android是消息驱动的,实现消息驱动有几个要素: 消息的表示:Message 消息队列:MessageQueue 消息循环,用于循环取出消息进行处理:Looper 消息处理,消息循环从消息队列中取 ...

  3. 转 Android的消息处理机制(图+源码分析)——Looper,Handler,Message

    作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习google大牛们的设计思想.android源码中包含了大量的设计模式,除此以外,android sdk还精心为我们设计了各种 ...

  4. 【转】android的消息处理机制(图+源码分析)——Looper,Handler,Message

    原文地址:http://www.cnblogs.com/codingmyworld/archive/2011/09/12/2174255.html#!comments 作为一个大三的预备程序员,我学习 ...

  5. android的消息处理机制(图+源码分析)——Looper,Handler,Message

    android源码中包含了大量的设计模式,除此以外,android sdk还精心为我们设计了各种helper类,对于和我一样渴望水平得到进阶的人来说,都太值得一读了.这不,前几天为了了解android ...

  6. 从Handler+Message+Looper源代码带你分析Android系统的消息处理机制

    PS一句:不得不说CSDN同步做的非常烂.还得我花了近1个小时恢复这篇博客. 引言 [转载请注明出处:http://blog.csdn.net/feiduclear_up CSDN 废墟的树] 作为A ...

  7. Android之消息机制Handler,Looper,Message解析

    PS:由于感冒原因,本篇写的有点没有主干,大家凑合看吧.. 学习内容: 1.MessageQueue,Looper,MessageQueue的作用. 2.子线程向主线程中发送消息 3.主线程向子线程中 ...

  8. Android Handler处理机制 ( 一 )(图+源码分析)——Handler,Message,Looper,MessageQueue

    android的消息处理机制(图+源码分析)——Looper,Handler,Message 作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习 google大牛们的设计思想. ...

  9. 《Android进阶》之第三篇 深入理解android的消息处理机制

    Android 异步消息处理机制 让你深入理解 Looper.Handler.Message三者关系 android的消息处理机制(图+源码分析)——Looper,Handler,Message an ...

  10. Android异步消息处理机制(多线程)

    当我们需要执行一些耗时操作,比如说发起一条网络请求时,考虑到网速等其他原因,服务器未必会立刻响应我们的请求,如果不将这类操作放在子线程里去执行,就会导致主线程被阻塞住,从而影响用户对软件的正常使用. ...

随机推荐

  1. DEBUG测试

    这几天看一个ros软路由的的API借口的C++实现看到一个关于DEBUG的测试,第一次见,感觉挺实用的,记录一下: #include<iostream> #include <stdi ...

  2. HackerRank "Dorsey Thief"

    A variation to 0-1 Knapsack. (No Python code got fully AC. Python is too slow for this problem) #inc ...

  3. php计算字符串长度:utf8编码,包含中文

    php计算字符串长度:utf8编码 中文当作1个字符处理(strlen默认当作两个字符) 上函数: /** * 计算 UTF-8 字符串长度 * * @param string $str * @ret ...

  4. python主要用来做什么

    python这门编程语言在国外极受欢迎,但在国内使用还不是极普遍. 由于python编程效率极高,现在国内的使用者也开始变得越来越多. python主要用来做什么?这个语言到底有哪些作用呢? 下面主是 ...

  5. for name in loop Shell

    for NAME in joe jane juliedoADDRESS="$NAME@example.com"MESSAGE='Projects are due today!'ec ...

  6. SVN并行开发管理策略

    总的原则:trunk保证相对稳定.分支合并到主干时将冲突降至最低. (1)       trunk用于集成.测试.发布,可以提交fixbug代码,但不允许直接提交新特性. (2)       特性在分 ...

  7. makefile中的shell语法

    在Makefile中写shell代码有点诡异,和不同的shell语法不太一样,如果不了解,看Makefile会莫名其妙.下面总结了一些. 1:尽在Makefile文件的目标项冒号后的另起一行的代码才是 ...

  8. Sublime text2用户自定义配置

    [{ "keys": ["ctrl+d"], "command": "run_macro_file", "ar ...

  9. C# ASP.NET 开发指引简要

    推荐学习交流社区:博客园http://www.cnblogs.com/ 里面有很多技术.职业圈子等信息的分享,新手必逛社区. 电子书等资源下载:csdn下载 http://download.csdn. ...

  10. DG_Oracle DataGuard Failover主备节点切换(案例)

    2014-03-09 Created By BaoXinjian Thanks and Regards