当应用程序启动时,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. 转: ExtJS中xtype一览

    转: ExtJS中xtype一览 基本组件: xtype Class 描述 button Ext.Button 按钮 splitbutton Ext.SplitButton 带下拉菜单的按钮 cycl ...

  2. RSA加密工具包

    主要参考: http://www.blogjava.net/icewee/archive/2012/05/19/378570.html http://snowolf.iteye.com/ 基于以上代码 ...

  3. CryptoAPI与openssl数字签名与验证交互

    昨天写过了RSA非对称加密解密的交互方式, 其实数字签名也是RSA非对称加密,只不过用私钥加密的,再加上个hash摘要 CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDI ...

  4. java 反射机制01

    // */ // ]]>   java反射机制01 Table of Contents 1 反射机制 2 反射成员 2.1 java.lang.Class 2.2 Constructor 2.3 ...

  5. 【initrd】向虚拟文件系统initrd.img中添加驱动

    虚拟文件系统:initrd-2.6.18-194.el5.img 希望添加网卡或SCSI等驱动 步骤: 解压initrd-2.6.18-194.el5.img: 添加*.ko文件,并修改init可执行 ...

  6. 我们如何学好java

    转载:http://www.zhihu.com/question/19945685 马士兵有一篇文章,我觉得写得很好,原文转载如下,希望题主可以好好读读. ---------------------- ...

  7. ubuntu修改grub界面默认开机顺序

    终端输入: sudo gedit /etc/default/grub GRUB_DEFAULT代表的就是启动项的顺序,从数字0开始 修改成默认的第几个,就赋值成几就好(顺序从数字0开始) 然后别忘了运 ...

  8. BestCoder Round #84 Aaronson

    Aaronson 题意: 给个中文链接:戳戳戳 题解: 这题一看给的公式就是二进制,之后马上就能想到当m大于等于二进制的位数时,输出n的二进制的1的个数就好了.之后就是m小于二进制的位数时,只要加上2 ...

  9. int long long范围

    unsigned   int   0-4294967295   int   2147483648-2147483647 unsigned long 0-4294967295long   2147483 ...

  10. 转__Android Studio ,基于intellij idea

    看到论坛里一些关于Android Studio的帖子,基本上是停留在使用教程上.在此做一些功能性的分析和测评 下载地址 :http://developer.android.com/index.html ...