Handler对于多线程有多重要已经,毋须多言,实际上View.post、postDelay、postAtTime等绝大多数的本质都是依赖于Handler机制。
前面一篇文章Android进阶——异步不可或缺的组件Handler(一)介绍了Handler的机制及相关知识点,接下来我们就用一个例子来实际使用下Handler。
首先布局文件很简单:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" >
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Handler的应用——简易图片切换器"/>
<ImageView android:id="@+id/id_show_img" android:layout_width="match_parent" android:layout_height="match_parent" />
</LinearLayout>
package com.crazymo.styleattrdemo;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
import java.util.Timer;
import java.util.TimerTask;
/** * Created by cmo on 16-4-16. */
public class PicBrowserActivity extends Activity {
private ImageView mImg;
private int[] imgs=new int[]{
R.mipmap.ic_blue_launcher,
R.mipmap.ic_green_launcher,
R.mipmap.ic_red_launcher,
R.mipmap.pool_balls_05,
R.mipmap.ic_toy,
R.mipmap.ic_launcher
};
private int curIndex=0;//当前图片的id
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler);
mImg= (ImageView) findViewById(R.id.id_show_img);
final Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what==0x123){
mImg.setImageResource(imgs[curIndex++]);
if(curIndex>=5){
curIndex=5;
}
}
}
};
new Timer().schedule(new TimerTask() {
@Override
public void run() {
Message msg=new Message();
msg.what=0x123;
handler.sendMessage(msg);
}
},0,1000);//每隔1s 切换一次
}
}
利用Activity.runOnUiThread(Runnable)把更新ui的代码创建在Runnable中,然后在需要更新ui时,把这个Runnable对象传给Activity.runOnUiThread(Runnable)。 这样Runnable对像就能在ui程序中被调用。如果当前线程是UI线程,那么行动是立即执行。如果当前线程不是UI线程,操作是发布到事件队列的UI线程
private Activity mActivity;
mActivity=this;
//从这部分源码可以看到,本质也还是handler
//注意:勿在runOnUiThread(Runnable action)中做耗时操作
public final void More ...runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
mActivity.runOnUiThread(new Runnable(){
@Override
public void run(){
//做UI操作
}
});
new Thread(new Runnable(){
@Override
public void run(){
//在这里做耗时操作
mImgv.post(new Runnable(){
@Override
public void run(){
//在这里直接做UI操作
}
}).start();
}
});
AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程
在Handler实现异步时通常涉及到 Handler, Looper, Message,Thread四个角色,实现异步的流程是主线程启动Thread(子线程)àthread(子线程)运行并生成Message- àLooper获取Message并传递给HandleràHandler逐个获取Looper中的Message,并进行UI变更。
延时跳转
//延时跳转方式1:利用Handler
new Handler(new Handler.Callback() {
//当接收到信息之后,会自动触发回调里的handleMessage处理接收到的消息
@Override
public boolean handleMessage(Message msg) {
//启动直接跳转到MainActivity
startActivity(new Intent(WelcomeActivity.this,MainActivity.class));
finish();
return false;
}
}).sendEmptyMessageDelayed(0,2500);//延时2.5s发送空消息,即延时2.5s再去处理handleMessage里方法
new Handler().postDelayed(new Runnable(){
@Override
public void run(){
startActivity(new Intent(WelcomeActivity.this,GuideActivity.class));
}
},3000);//延时3s跳转
private Handler handler = new Handler();
private Runnable myRunnable= new Runnable() {
public void run() {
if (run) {
handler.postDelayed(this, 3000);
}
startActivity(new Intent(WelcomeActivity.this,GuideActivity.class));
}
};
调用触发
handler.post(myRunnable);
handler.post(myRunnable,time);
class StartTask extends TimerTask{
@Override
public void run() {
startActivity(new Intent(WelcomeActivity.this,GuideActivity.class));
}
}
执行定时任务
//延时跳转2:利用timerTask
Timer timer=new Timer();
timer.schedule(new StartTask(), 2500);//延时2.5s执行任务的方法