安卓开发-Handler学习

 

从上面的解释可以看出来,Handler的作用是与一个线程绑定,之后就可以发消息给线程的消息队列来执行动作。
有两个主要的用途:

1、安排在不同事件执行什么动作。比如说我们要每隔几秒钟刷新一下Activity的title。

2、给另外线程发消息。

可以说,Handler是Runnable和Activity之间的桥梁。

下面看例子,这个例子中,每隔1s刷新一次title。

package com.example.testhandler;

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

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;

public class MainActivity extends Activity {

	private static int count = 0;
	private final Handler myHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch (msg.what) {
			case 1:
				updateTitle();
				break;
			default:
				break;
			}
		}

	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		Timer t = new Timer();
		t.scheduleAtFixedRate(new MTask(), 1000, 1000);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

	private void updateTitle() {
		this.setTitle("welcome " + count++);
	}

	class MTask extends TimerTask {

		@Override
		public void run() {
			Message m = new Message();
			m.what = 1;
			myHandler.sendMessage(m);
		}
	}
}

Message中what参数的解释如下:

 /**
     * User-defined message code so that the recipient can identify 
     * what this message is about. Each {@link Handler} has its own name-space
     * for message codes, so you do not need to worry about yours conflicting
     * with other handlers.
     */
    public int what;
用户用这个字段来区分发送过来的消息是什么消息,从而调用不同的方法来处理消息。

在上面的例子中就是根据发送过来的what是不是1,来决定是否调用updateTitile方法。

---------------------------

再看下post方法:


post方法给关联的线程发送了一个Runable对象,加到其消息队列中。

看看下面的官方解释:

Scheduling messages is accomplished with the post(Runnable)postAtTime(Runnable, long)postDelayed(Runnable, long)sendEmptyMessage(int)sendMessage(Message)sendMessageAtTime(Message, long), andsendMessageDelayed(Message, long) methods. The post versions allow you to enqueue Runnable objects to be called by the message queue when they are received; the sendMessage versions allow you to enqueue a Message object containing a bundle of data that will be processed by the Handler's handleMessage(Message) method (requiring that you implement a subclass of Handler).

从上面的解释看到,post***方法给消息队列添加Runnable对象。而sendMessage则可以消息队列发送一些数据。sendMessage发送的消息经由handler的handleMessage方法来处理。

所以,上面用sendMessgae来实现的例子,也可以用post方法来实现:

package com.example.testhandler;

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

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;

public class MainActivity extends Activity {

	private int count = 0;

	private Handler mHandler = new Handler();

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		Timer t = new Timer();
		t.scheduleAtFixedRate(new MyTask(), 1000, 1000);
	}

	private class MyTask extends TimerTask {
		@Override
		public void run() {
			mHandler.post(new Runnable() {

				@Override
				public void run() {
					updateTitle();
				}
			});
		}
	}

	public void updateTitle() {
		setTitle("Welcome " + count++);
	}
}
只不过,post方法直接发送一个runnable对象给消息队列。不能带一些参数过去。而sendMessage可以做到这一点。
----------------------

当然,post()方法还有一些变体,比如postDelayed()、postAtTime()分别用来延迟发送、定时发送

---------------------------------

除了Handler,View也是有post方法的。

看下面的例子:

package com.example.posttest;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		final TextView view = (TextView) findViewById(R.id.text);

		Button b = (Button) findViewById(R.id.button1);
		b.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Log.e("mason", "go");
				view.post(new Runnable() {

					@Override
					public void run() {
						// TODO Auto-generated method stub
						Log.e("mason", "here");
						view.setText("you great");
						view.refreshDrawableState();
					}
				});
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

例子中,有一个TextView和一个Button。点击button的时候,textview发出一个消息,在消息中,开启一个线程更新textview的内容。

下面分析下View的post函数:


函数把参数runnable添加到UI线程的事件队列中。与Handler的作用一致。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值