Handler是整个消息系统的核心,是Handler向MessageQueue发送的Message,最后Looper也是把消息通知给Handler,所以就从Handler讲起。

一、Handler

Handler的构造函数有很多,但本质差不多:

public Handler() {
this(null, false);
}

  

public Handler(Callback callback, boolean async) {
//自动绑定当前线程的looper
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");//从这可以看出,创建Handler必须有Looper
}
mQueue = mLooper.mQueue; //Looper的MessageQueue
mCallback = callback; //一个回掉接口
mAsynchronous = async;
}

这个是创建给定Looper的Handler  :

public Handler(Looper looper, Callback callback, boolean async) {    
       mLooper = looper;  
       mQueue = looper.mQueue;  
       mCallback = callback;  
       mAsynchronous = async;  
   }

二、Looper的源代码:

public static Looper myLooper() {
return sThreadLocal.get();
}

  在一个子线程中创建Looper的一般步骤:(这是我自己写的,不是源代码)

class MyThread extends Thread{
public Handler handler;
public Looper looper;
public void run() {
Looper.prepare();//创建一个looper
looper = Looper.myLooper();
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
System.out.println("currentThread->"+Thread.currentThread());
}
};
Looper.loop();//让消息循环起来
}
}

  下面就看看Looper.prepare,Looper.loop方法:

public static void prepare() {
prepare(true);
} private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {//sThreadLocal使得线程能够保持各自独立的一个对象。
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}

  Looper.prepare():

public static void loop() {
final Looper me = myLooper();
if (me == null) { //如果Looper为空
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue; 。。。。
for (;;) {
Message msg = queue.next(); // 循环下一个
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
} 。。。。 msg.target.dispatchMessage(msg); //分发消息,msg.target就是Handler if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
。。。。 msg.recycle(); //回收msg到msgPool
}
}

  从这些代码可以看出Looper不断检查MessagePool是否有《==Message,有的话就通过Handler的dispatchMessage(msg)发送出去,利用Handler与外界交互。

3.Message的源代码:

public static Message obtain() {   //得到Message对象
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
sPoolSize--;
return m;
}
}
return new Message(); //没有就新建
}

  handler.obtainMessage()方法:

public final Message obtainMessage()
{
return Message.obtain(this); //通过Message的obtain方法
}

  

public static Message obtain(Handler h) {  //就是这个方法
Message m = obtain(); //最终调用的还是obtain方法
m.target = h; //target是handler return m;
}

  看了上边的源代码,相信你一定对Handler,message,Looper有了一定了解,对编程中常遇到的方法,知道是怎么用的啦。其实学android一定要常看源码,源码很有用。

4.下边就是上代码,实例分析:

<pre name="code" class="java">package com.example.handler_01;  

import android.Manifest.permission;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener{ private TextView textView;
private Button button; private Handler handler = new Handler(new Callback() {//拦截消息 public boolean handleMessage(Message msg) { //截获handler的发送的消息 Toast.makeText(getApplicationContext(), ""+1, 1).show();
//return false;
return false;//若返回true,则证明截获,下面的handleMessage就不会执行!
}
}){
public void handleMessage(Message msg) {
Toast.makeText(getApplicationContext(), ""+2, 1).show();
Person person = (Person)msg.obj;
System.out.println(person.toString());
}
}; private MyRunnable myRunnable=new MyRunnable(); private ImageView imageView; private int images[]={R.drawable.a1,R.drawable.a2,R.drawable.a3};
private int index; class MyRunnable implements Runnable{ //不断的更新图片,3张轮换 @Override
public void run() {
index++;
index=index%3; //不断循环
imageView.setImageResource(images[index]);
handler.postDelayed(myRunnable, 1000); //每隔一段时间执行myRunnable
System.out.println("MyRunnable中的线程:"+Thread.currentThread());//运行在当前主线程!
} }
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textview);
imageView = (ImageView) findViewById(R.id.imageView1);
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(this);
new Thread(){
@Override
public void run() {
try {
Thread.sleep(2000);
/*Message message = new Message();
message.arg1=88;*/
Message message = handler.obtainMessage(); Person person = new Person();
person.age=20;
person.name="chaochao";
message.obj=person;
handler.sendMessage(message);//在子线程中向主线程发消息。
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}.start();
handler.postDelayed(myRunnable, 1000);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
handler.removeCallbacks(myRunnable);
//handler.sendEmptyMessage(1);
break; default:
break;
} } class Person{
public int age;
public String name; public String toString() {
return "name="+name+" age="+age;
}
}
}

  布局很简单,就不上代码啦。

运行结果:

图片自己可以随便能一个。。。。

在后边再详细解析Handler的用法。。

转发请注明出处:http://www.cnblogs.com/jycboy/p/handlerjx.html

结合源代码详解android消息模型的更多相关文章

  1. 图文详解 Android Binder跨进程通信机制 原理

    图文详解 Android Binder跨进程通信机制 原理 目录 目录 1. Binder到底是什么? 中文即 粘合剂,意思为粘合了两个不同的进程 网上有很多对Binder的定义,但都说不清楚:Bin ...

  2. 详解Android首选项框架ListPreference

    详解Android首选项框架ListPreference 原文地址 探索首选项框架 在深入探讨Android的首选项框架之前,首先构想一个需要使用首选项的场景,然后分析如何实现这一场景.假设你正在编写 ...

  3. 详解android:scaleType属性

    详解android:scaleType属性 转自:http://blog.csdn.net/encienqi/article/details/7913262    http://juliaailse. ...

  4. adb shell 命令详解,android

    http://www.miui.com/article-275-1.html http://noobjava.iteye.com/blog/1914348 adb shell 命令详解,android ...

  5. 详解Android Activity---启动模式

    相关的基本概念: 1.任务栈(Task)   若干个Activity的集合的栈表示一个Task.   栈不仅仅只包含自身程序的Activity,它也可以跨应用包含其他应用的Activity,这样有利于 ...

  6. Android Binder IPC详解-Android学习之旅(96)

    linux内存空间与BInder Driver Android进程和linux进程一样,他们只运行在进程固有的虚拟空间中.一个4GB的虚拟地址空间,其中3GB是用户空间,1GB是内核空间 ,用户空间是 ...

  7. 详解Android中的四大组件之一:Activity详解

    activity的生命周期 activity的四种状态 running:正在运行,处于活动状态,用户可以点击屏幕,是将activity处于栈顶的状态. paused:暂停,处于失去焦点的时候,处于pa ...

  8. adb shell 命令详解,android, adb logcat

    http://www.miui.com/article-275-1.html http://noobjava.iteye.com/blog/1914348 adb shell 命令详解,android ...

  9. [转]Hadoop集群_WordCount运行详解--MapReduce编程模型

    Hadoop集群_WordCount运行详解--MapReduce编程模型 下面这篇文章写得非常好,有利于初学mapreduce的入门 http://www.nosqldb.cn/1369099810 ...

随机推荐

  1. ActionBarSherlock SlidingMenu整合,解决SlidingMenu example的getSupportActionBar()方法不能用问题

    今天下载了SlidingMenu来研究,发现里面那个自带的example不能使用,总是提示BaseActivity 里面找不到getSupportActionBar()方法,到Github上面一查果然 ...

  2. linux2.6.24内核源代码分析(2)——扒一扒网络数据包在链路层的流向路径之一

    在2.6.24内核中链路层接收网络数据包出现了两种方法,第一种是传统方法,利用中断来接收网络数据包,适用于低速设备:第二种是New Api(简称NAPI)方法,利用了中断+轮询的方法来接收网络数据包, ...

  3. codeforces D. Design Tutorial: Inverse the Problem

    题意:给定一个矩阵,表示每两个节点之间的权值距离,问是否可以对应生成一棵树, 使得这棵树中的任意两点之间的距离和矩阵中的对应两点的距离相等! 思路:我们将给定的矩阵看成是一个图,a 到 b会有多条路径 ...

  4. DDD:使用EntityFramework的话,如果只为聚合根设计仓储,其它实体如何处理?

    背景 DDD中只有聚合根可以有仓储,仓储负责整个聚合持久化的相关生命周期,在不使用工作单元或POCO的情况下,我们可以让Order内部直接调用DAL操作OrderItem.我们也可以让Order跟踪所 ...

  5. [python]新手写爬虫v2.5(使用代理的异步爬虫)

    开始 开篇:爬代理ip v2.0(未完待续),实现了获取代理ips,并把这些代理持久化(存在本地).同时使用的是tornado的HTTPClient的库爬取内容. 中篇:开篇主要是获取代理ip:中篇打 ...

  6. Vue基础---->VueJS的使用(二)

    组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能.今天我们就来学习一 ...

  7. 工作流数据库表设计-ASP.NET

    公司准备开发一套工作流引擎,以前没有什么OA开发经验,也是第一次设计工作流引擎,我把我的一些思路分享一下,希望得到些帮助或者能帮助到一些人. 产品的定位: 1.能够做到前后端分离 2.可以做到项目的分 ...

  8. Java魔法堂:Date与日期时间格式化

    一.前言                                                                                       日期时间的获取.显 ...

  9. Mysql创建用户的三种基本方法

    1.采用create user e.g.  create user 'username'@'host' identified by 'password'; 2.采用grant语句 e.g.  gran ...

  10. [Solution] 一步一步WCF(1) 快速入门

    Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Windows 通讯开发平台.整合了原有的windows通讯的 .n ...