`
chenchuangfeng
  • 浏览: 80317 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Android Handler 详细分析

阅读更多

最近项目上用到Handler比较多,遇到不少麻烦,也体会到不少,Handler在Android开发经常会用到,但是很多人包括我都是对他的原理也是一知半解,这里总结一下自己对Handler的学习,欢迎补充和纠正。

 Handler的作用:

  1.   发送和处理消息(Message)
  2.  发送和处理runnable对象

 

Handler涉及到几个概念:

    1.Message:包含了消息id,数据,等信息,由MessageQueue队列控制。

    2.MessageQueue:消息队列,用链表的方式存储Message,按照FIFO(队列先进先出规则)让Looper来   抽取Message,进行处理。

     3.Looper:一个线程只有一个Looper对象,负责不断从MessageQueue 抽取Message进行处理。

         

发送和处理消息(Message)

 

//Message有两种获得方法;
Handler myHandler = new Handler(){

			@Override
			public void handleMessage(Message msg) {
				// TODO Auto-generated method stub
				if(msg.what ==1){
					
				}
				super.handleMessage(msg);
			}
			
		};
// 第一种 调用myHandler.obtainMessage() 获得的Message已经跟myHandler绑定
Message msg1 = myHandler.obtainMessage();
// 直接调用 sendToTarget() 就可以把消息送入队列,等待Handler执行
msg1.sendToTarget();
// 第二种 直接用Message的构造函数
Message msg2 = new Message();
// 调用Handler 实例的 sendMessage()方法把消息送入队列,等待Handler执行
myHandler.sendMessage(msg2);//即时send
myHandler.sendEmptyMessageAtTime(1, uptimeMillis);//在uptimeMillis时间点 send属性what值为what的Message
myHandler.sendEmptyMessage(1);//send属性what值为what的Message
//其他以此类推

 

 

发送和处理消息 Runnable:

 

Runnable runnable = new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub

			}
		};
long time = System.currentTimeMillis();
myHandler.post(runnable);//即使post
myHandler.postAtFrontOfQueue(runnable);//插入队头
myHandler.postAtTime(runnable, time);//在time时间点 post
myHandler.postDelayed(runnable, 3000);//延迟3秒 post
//其他以此类推

 

 

 

 

关于线程问题:

      Android,启动一个应用就会开启一个线程,这个线程是主线程,处理各种UI控件和消息的响应,所以,在这个线程上不要运行耗时的操作,这样会出现UI的停顿,超过5S系统,自动弹出强制关闭窗口,但是所有UI操作都必须在主线程里面进行操作,这时候在进行耗时任务时候,就可以用Handler在子线程里面,发送消息,然后在主线程里面用Handler去处理消息,来改变UI。

 

      例子不自己写了 ,在网上找了一个

 

package com.blueeagle;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class SendMessage extends Activity {
	private TextView textView;
	private MyHandler myHandler;//定义一个自己的Handle类
	private Button button;
	private MyThread m=new MyThread(); //定义一个自己的线程类
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main); 
		textView=(TextView)findViewById(R.id.text);
		button=(Button)findViewById(R.id.startButton); 
		button.setOnClickListener(new View.OnClickListener() { 
		@Override
		public void onClick(View arg0) { 
		myHandler=new MyHandler(); 
		new Thread(m).start(); 
		System.out.println("主线程运行ID:"+Thread.currentThread().getId());
		} 
		});
		}//在对UI进行更新时,执行时所在的线程为主UI线程 
	class MyHandler extends Handler{//继承Handler类时,必须重写handleMessage方法 
		public MyHandler(){
			
		}
		public MyHandler(Looper l){
			super(l);
			}
		@Override
		public void handleMessage(Message msg) {//执行接收到的通知,此时执行的顺序是按照队列进行,即先进先出 
			super.handleMessage(msg);
			Bundle b=msg.getData(); 
			String textStr1=b.getString("textStr");
			SendMessage.this.textView.setText(textStr1);//更改TextView中的值
			} 
		}//该线程将会在单独的线程中运行 
		
		class MyThread implements Runnable{
			int i=1; 
			@Override
			public void run() {
				while(i<11){ 
					System.out.println("当前运行线程ID:"+Thread.currentThread().getId());
					try {
						Thread.sleep(1000);
						}
					catch(InterruptedException e){
						e.printStackTrace(); 
						}
					Message msg=new Message(); 
					Bundle b=new Bundle(); 
					b.putString("textStr", "线程运行"+i+"次"); 
					i++; 
					msg.setData(b);
					SendMessage.this.myHandler.sendMessage(msg);//通过sendMessage向Handler发送更新UI的消息 
					}
				i=1;//下次启动线程时重新计数。
				}
			}
		} 

   

 

 

Handler与线程的关系:

       Handler必须依附线程的Looper.

为什么在子线程创建Handler  会报错,因为子线程没有Looper给Handler使用,这时候有两种方法

 

  1. 在主线程创建Handler

handler = new Handler(Looper.getMainLooper()) ;//这样的Handler跟主线程 实例化的效果一样

 

 

2. 在子线程创建Handler

 

      第一种是在主线程中调用Looper的静态方法Looper.prepare()方法创建Looper对象

 

Looper.prepare();// 创建该线程的Looper对象,用于接收消息,在非主线程中是没有looper的所以在创建handler前一定要使用prepare()创建一个Looper   
       Handler myThreadHandler = new Handler() {      
       public void handleMessage(android.os.Message msg) {   
       Log.d(Constant.TAG, MessageFormat.format("Thread[{0}]--myThreadHandler handleMessage run...",   
       Thread .currentThread().getName()));   
                                }    
       Looper.myLooper().loop();//建立一个消息循环,支持该线程将不会退出,不断进行循环  

  

 

 

    第二种   利用 HandlerThread  创建新线程 ,该线程初始化后就已经有了Looper对象

//生成一个HandlerThread对象     
 HandlerThread handlerThread = new HandlerThread("handler_thread");     
 //在使用HandlerThread的getLooper()方法之前,必须先调用该类的start(),同时开启一个新线程;     
handlerThread.start();   
//将由HandlerThread获取的Looper传递给Handler对象,即由处于另外线程的Looper代替handler初始化时默认绑定的消息队列来处理消息。     
//自定义Handler   
 MyHandler myHandler = new MyHandler(handlerThread.getLooper());     

 

 

 

关于Runnable的使用:

      

        很多人会认为Handler post进去的就是一个线程,这里要纠正一下,Runnable只是个接口,并不是线程,是要配合Thread 的 start() 方法才能开启有一个心线程。

        post进去队列的Runnable实例,当被Looper拿出来执行的时候,只是执行run()方法而已,这里并没有产生新线程,所以Handler是依附UI线程的时候,实现Runnable接口的run()方法的时候,不能进行耗时操作,不然会出现UI卡死。

        还有一点队列是先进先出,如果要不断post多个Runnable进去队列,如果Ruannable   post进去的时间间隔  delay区别太大,会出现一个总是被执行,而另一个被执行的次数大大减小。

1
0
分享到:
评论
2 楼 chenchuangfeng 2013-05-13  
accelater 写道
博主,这个你做过实验么?

“还有一点队列是先进先出,如果要不断post多个Runnable进去队列,如果Ruannable   post进去的时间间隔  delay区别太大,会出现一个总是被执行,而另一个被执行的次数大大减小。”

理论上处理完队列中一个对象,就等待处理下一个了,会出现 一个总是被执行,而另一个被执行的次数大大减小?




会的。。你想一下就知道了。。。同个队列中出现的比例嘛,另一个太大,另一个占的比例就缩小,再说post上去的其实不是一个新的线程,只是执行了runnable中run方法的代码而已,所以,队列中所有的任务都是顺序执行的。
1 楼 accelater 2013-05-12  
博主,这个你做过实验么?

“还有一点队列是先进先出,如果要不断post多个Runnable进去队列,如果Ruannable   post进去的时间间隔  delay区别太大,会出现一个总是被执行,而另一个被执行的次数大大减小。”

理论上处理完队列中一个对象,就等待处理下一个了,会出现 一个总是被执行,而另一个被执行的次数大大减小?

相关推荐

    androidHandler测试的demo

    在“androidHandler测试的demo”中,我们可以预期包含以下内容: 1. 创建自定义`Handler`子类:这个子类可能重写了`handleMessage(Message msg)`方法,根据`msg.what`的值执行不同的操作,比如更新UI元素或执行特定...

    Android Handler机制解析

    下面将对Android Handler机制进行详细的解析。 一、线程概念 在现代操作系统中,进程是资源分配的最小单位,而线城是CPU调度的基本单位。一个进程中最少有一个线程,名叫主线程。进程是程序执行的一个实例,比如说...

    Android Handler消息处理顺序分析

    本文将详细分析Android Handler消息处理的顺序,以及如何利用这些组件进行异步操作。 首先,理解Handler的基本概念。Handler是Android中的一个类,用于发送和处理消息。它通常与Looper和Message配合工作,允许...

    Android Handler解析

    # Android Handler解析 在Android应用开发中,保持应用程序的响应性是至关重要的。为了实现这一目标,我们需要确保UI线程不会被阻塞。通常来说,将耗时的任务(如网络请求、复杂计算等)放到后台线程执行可以提高UI...

    android handler例子

    下面将详细解释`Handler`的工作原理以及如何在实际应用中创建和使用`Handler`来改变图片展示。 首先,让我们理解`Handler`的基本概念。`Handler`是Android中处理消息和执行延迟操作的对象,通常在主线程中创建。它...

    Android Handler 原理分析及实例代码

    在Android开发中,`Handler` 是一个至关重要的组件,它涉及到多线程、UI更新以及消息传递机制。本文将深入探讨 `Handler` 的工作原理,分析其如何在不同线程间进行通信,并通过实例代码来展示其具体用法。 ### ...

    老罗android Handler综合练习 图文混排 服务器端源代码

    【标题】"老罗android Handler综合练习 图文混排 服务器端源代码"涉及的是Android应用开发中的关键知识点,主要集中在Handler机制、图文混排以及服务器端的数据交互。Handler是Android系统中用于线程间通信的重要...

    Android Handler运行原理

    通过以上分析,我们可以看出Android中Handler机制的核心在于利用Looper、MessageQueue和Handler三个核心组件,实现了线程间的通信。其中Looper负责管理MessageQueue,而Handler则是发送和接收消息的媒介。这种设计...

    android handler 机制 源码

    在Android系统中,Handler、Looper和Message构成了一个用于线程间通信的重要机制。这个机制使得UI线程可以处理来自其他线程的消息,从而避免了直接在非UI线程操作UI组件,防止应用出现ANR(Application Not ...

    Android Handler事件分析处理1

    本文将深入解析这些概念及其在Android系统中的应用。 首先,`Handler`是Android中处理消息和调度执行任务的关键类。它允许开发者在主线程(UI线程)或其他线程中发送和处理消息。`Handler`通过`sendMessage()`或`...

    Android-Event-driver.zip_Looper_android_android Handler_event

    在上一篇文章《Android应用程序消息处理机制(Looper、Handler)分析》中,我们分析了Android应用程序的消息处理机制,本文将结合这种消息处理机制来详细分析Android应用程序是如何获得键盘按键消息的。

    Android Handler线程间的调度

    通过分析MessageProject的代码,我们可以更深入地理解Handler、Looper和Message之间的交互,以及如何在实际应用中灵活运用它们来实现线程间的协调和通信。同时,这也有助于提升我们的Android开发技能,尤其是在处理...

    Android利用handler在线程之间传递代码

    通过分析这个示例,你可以更直观地理解Handler的工作机制,并在实际项目中灵活运用。 总结来说,Handler机制是Android多线程编程的关键工具之一,它使得开发者能够方便地在线程间传递信息,实现异步处理,确保UI...

    自己设计的Android简易版本Handler 框架及实现源码,对了解Android Handler原理有一定的参考价值

    下面将详细介绍这个自定义`Handler`框架以及其与Android原生`Handler`的关系。 ### 1. Android Handler 原理概述 `Handler`是用来发送和处理消息的类,通常与`Looper`和`Message`一起工作。在Android系统中,主线...

    android Handler子线程计算斐波那契数列

    在Android应用开发中,Handler是用于处理主线程与子线程之间通信的重要工具。它允许开发者在后台线程执行耗时操作(如计算斐波那契数列),然后通过Message对象将结果回调到主线程更新UI。在这个场景中,我们讨论的...

    Android Handler的原理1

    为了处理这些后台任务并同步更新UI,Android引入了Handler机制。Handler是Android消息传递的核心组件,它与Looper和MessageQueue紧密配合,使得线程间通信变得简单高效。 1. Handler的作用: Handler主要用于在不同...

    Android应用程序消息处理机制(Looper、Handler)分析

    Android 应用程序中,消息处理机制是其异步编程的核心组成部分,主要涉及三个关键组件:Handler、Message和Looper。这种机制使得应用可以有效地管理线程间的通信,避免阻塞主线程,提升用户体验。 首先,我们需要...

Global site tag (gtag.js) - Google Analytics