Android菜鸟的成长笔记(12)——Handler、Loop、MessageQueue

  当一个程序第一次启动时,Android会启动一条主线程(Main Thread),主线程主要负责处理与UI相关的事件,如按键事件、触屏事件、绘图事件,主线程也被称为UI线程。
UI的操作只能是通过主线程来操作,为了解决多线程操作UI的问题,就用到了Handler类。
一、Handler类
Handler类的作用有两个:
1、在新启动的线程中发送消息。
2、在主线程中获取、处理消息。
例如:
package com.example.testlistener;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {
	EditText txt;
	final Handler hander = new Handler(){
		public void handleMessage(android.os.Message msg) {
			if(msg.what == 0x1234){
				Toast.makeText(MainActivity.this, msg.arg1 + "", 1000).show();
			}
		};
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		new Timer().schedule(new TimerTask() {
			int i = 0;
			@Override
			public void run() {
				i++;
				Message msg = new Message();
				msg.what = 0x1234;
				msg.arg1 = i;
				hander.sendMessage(msg);
			}
		}, 0, 2000);
	}
	
}
Message是Hander接收和处理的消息对象。通过向Message中添加消息,将消息放入消息队列MessageQueue,然后通过Looper方法读取MessageQueue。
打开Android系统源码可以看到:
    private Looper() {
        mQueue = new MessageQueue();
        mRun = true;
        mThread = Thread.currentThread();
    }
程序创建时Looper会在它的构造器中创建MessageQueue对象。
handlerMessage方法位于主线程,可以处理UI.
二、Handler、Looper、MessageQueue的工作原理
Looper:每个线程只有一个Looper,负责管理MessageQueue,会不断地从MessageQueue中取出消息,并将消息分给对应的Handler处理。
MessageQueue:由Looper负责管理,采用先进先出的方式管理Message(消息队列).
Handler:把消息发送给Looper管理的MessageQueue并负责处理Looper分给它的消息。
为了保证当前线程中有Looper对象,有如下两种情况:
1、主UI线程中,系统已经初始化了一个Looper对象,因此程序直接创建Handler即可。
2、自己定义的子线程,必须先创建一个Looper对象,并启动它。
例如:将上面的例子加以修改
package com.example.testlistener;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {
	EditText txt;
	Button bt;
	TestThread testThread;
	int j = 0;
	final Handler hander = new Handler(){
		public void handleMessage(android.os.Message msg) {
			if(msg.what == 0x1234){
				Toast.makeText(MainActivity.this, msg.arg1 + "", 1000).show();
			}
		};
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		txt = (EditText) findViewById(R.id.txt);
		bt = (Button) findViewById(R.id.bn);
		testThread = new TestThread();
		testThread.start();
		bt.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				j++;
				Message msg = new Message();
				msg.what = 0x1000;
				msg.arg1 = j;
				testThread.thander.sendMessage(msg);
			}
		});
		
		new Timer().schedule(new TimerTask() {
			int i = 0;
			@Override
			public void run() {
				i++;
				Message msg = new Message();
				msg.what = 0x1234;
				msg.arg1 = i;
				hander.sendMessage(msg);
			}
		}, 0, 2000);
	}
	
	//自定义子线程
	class TestThread extends Thread{
		public Handler thander;
		@Override
		public void run() {
			//创建一个Looper对象
			Looper.prepare();
			thander = new Handler(){
				@Override
				public void handleMessage(Message msg) {
					if(msg.what == 0x1000){
						System.out.println("j = " + msg.arg1);
						//txt.setText(msg.arg1 + "");
					}
				}
			};
			//启动Looper
			Looper.loop();
		}
	}
	
}
运行结果:







郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。