在看这篇博客之前,最好看看《Anroid异步消息机制(Handler、Looper、Message、MessageQueue)以及ThreadLocal运用》了解Handler原理。
Handler使用,主要有以下几种方式:
Thread+Handler、Timer+TimerTask+Handler、Handler.postXXX(Runnable r,...)、Handler.sendXXX()、AsyncTask。
1、activity_handler.xml
<LinearLayout 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:orientation="vertical"
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=".MainActivity" >
<TextView
android:id="@+id/handler_post_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="handler.post()" />
<TextView
android:id="@+id/timer_handler_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Timer+TimerTask+Handler" />
<TextView
android:id="@+id/thread_handler_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="thread+handler" />
<TextView
android:id="@+id/asyncTask_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="asyncTask" />
<Button
android:id="@+id/thread_handler_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="thread+handler" />
<Button
android:id="@+id/asyncTask_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="asyncTask" />
</LinearLayout>
2、HandlerExample.java
import java.lang.ref.WeakReference;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class HandlerExample extends Activity {
private TextView handler_post_text = null;
private TextView timer_handler_text = null;
private TextView thread_handler_text = null;
private TextView asyncTask_text = null;
private Button thread_handler_button = null;
private Button asyncTask_button =null;
private Handler handler;
private Timer timer;
private AsyncTask asyncTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler);
//WeakReference<Handler> wf = new WeakReference<Handler>(new MyHandler());
//handler = (wf != null) ? wf.get() : null;
handler = new MyHandler();
timer = new Timer();
timer.schedule(new MyTimer(), 1, 5000);
handler_post_text = (TextView) findViewById(R.id.handler_post_text);
timer_handler_text = (TextView) findViewById(R.id.timer_handler_text);
thread_handler_text = (TextView) findViewById(R.id.thread_handler_text);
asyncTask_text = (TextView) findViewById(R.id.asyncTask_text);
thread_handler_button = (Button) findViewById(R.id.thread_handler_button);
asyncTask_button = (Button) findViewById(R.id.asyncTask_button);
thread_handler_button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
new Thread(new Runnable() {
@Override
public void run() {
Message message = new Message();
message.what = 2;
handler.sendMessage(message);
// handler.sendEmptyMessage(int what);
// handler.sendEmptyMessageAtTime(int what, long uptimeMillis);//什么时间执行发送消息
// handler.sendEmptyMessageDelayed(int what, long delayMillis);//延迟多少执行发送消息
// handler.sendMessageAtTime(Message msg, long uptimeMillis);//什么时间执行发送消息
// handler.sendMessageDelayed(Message msg, long uptimeMillis);//延迟多少执行发送消息
}
}).start();
}
});
asyncTask_button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
asyncTask = new MyAsyncTask();//需要在UI线程中进行
asyncTask.execute("hello world");//需要在UI线程中进行
//asyncTask.execute(Runnable runnable);
//asyncTask.execute(Object o);
//asyncTask.execute(Object... params);
}
});
handler.postAtTime(new Runnable() {
@Override
public void run() {
handler_post_text.setText("MainActivity.handler_post."
+ Thread.currentThread().getName() + "-"
+ Thread.currentThread().getId());
}
}, handler_post_text, SystemClock.uptimeMillis() + 4000);// 默认Message
// handler.post(Runnable r);
// handler.postAtTime(Runnable r, long uptimeMillis);//什么时间执行发送消息
// handler.postDelayed(Runnable r, long uptimeMillis);//延迟多少执行发送消息
}
@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;
}
// 设置定时器任务
class MyTimer extends TimerTask {
@Override
public void run() {
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
}
//onPreExecute->doInBackground->onProgressUpdate(需要doInBackground调用了publishProgress才能通过Handler触发)->onPostExecute(可无)
//第一个参数是execute方法、doInBackground方法参数类型;
//第二个参数是onProgressUpdate方法的参数类型;
//第三个参数是onPostExecute方法的参数类型以及doInBackground返回参数类型
class MyAsyncTask extends AsyncTask<Object, Integer, String>{
@Override
protected void onPreExecute(){//可以ui更新
asyncTask_text.setText("MainActivity.asyncTask."
+ Thread.currentThread().getName() + "-"
+ Thread.currentThread().getId());
}
@Override
protected String doInBackground(Object... arg0) {//可以执行耗时的任务,因而不能执行ui更新
return "AsyncTask";
}
@Override
protected void onProgressUpdate(Integer... progresses){
}
@Override
protected void onPostExecute(String result){//更新ui,显示结果
asyncTask_text.setText("AsyncTask");
}
@Override
protected void onCancelled(){//取消执行任务时,更新ui
}
}
final class MyHandler extends Handler {
@Override
public void handleMessage(Message message) {
if (message.what == 1) {
timer_handler_text.setText("MainActivity.timer_handler."
+ Thread.currentThread().getName() + "-"
+ Thread.currentThread().getId());
} else if (message.what == 2) {
thread_handler_text.setText("MainActivity.thread_handler."
+ Thread.currentThread().getName() + "-"
+ Thread.currentThread().getId());
}
}
}
@Override
protected void onStop() {
super.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (timer != null) {
timer.cancel();
}
if (handler != null) {
handler.removeCallbacksAndMessages(null);// 释放Handler
}
}
@Override
protected void onResume() {
super.onResume();
}
}
3、AsyncTask
对Thread+Handler进行包装,更加流程化来处理UI。概括来说,当我们在UI线程中调用execute()方法后会调用onPreExecute()方法,然后由ThreadPoolExecutor实例sExecutor执行一个FutureTask任务,这个过程中doInBackground()方法将被调用,如果被开发者覆写的doInBackground()方法中调用了publishProgress()方法,则通过InternalHandler实例sHandler发送一条MESSAGE_POST_PROGRESS消息,更新进度;sHandler处理消息时onProgressUpdate()方法将被调用;如果遇到异常,则发送一条MESSAGE_POST_CANCEL的消息,取消任务,sHandler处理消息时onCancelled()方法将被调用;如果执行成功,则发送一条MESSAGE_POST_RESULT的消息,显示结果,sHandler处理消息时onPostExecute(Result result)方法被调用。
如下图所示: