前言:
Handler的定义:主要接受子线程发送的数据, 并用此数据配合主线程更新UI。也就是说: 当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件,进行事件分发,比如说,你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。
Handler: 简介
Handler基本概念:
Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分逐个的在消息队列中将消息取出,然后对消息进行出来,就是发送消息和接收消息不是同步的处理。 这种机制通常用来处理相对耗时比较长的操作。
HandlerThread/Looper & MessageQueue & Message的关系:
handler负责将需要传递的信息封装成Message,通过handler对象的sendMessage()来将消息传递给Looper,由Looper将Message放入MessageQueue中。当Looper对象看到MessageQueue中含有Message,就将其广播出去。该handler 对象收到该消息后,调用相应的handler对象的handleMessage()方法对其进行处理。
Handler中分发消息的一些方法
post(Runnable)postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
以上post类方法允许你排列一个Runnable对象到主线程队列中,
sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.
示例1:一个应用程序中有2个按钮(start、end),当点击start按钮时,执行一个线程,这个线程在控制台输出一串字符串,并且每隔3秒再执行一次线程,直到点击end按钮为止,线程停止。
下图为这个应用程序的界面以及效果:
开发步骤:
1、 新建一个Android应用程序 。
2、 在布局文件中添加2个Button控件标签,并为其设置属性和值。
3、 在Activity中,声明控件变量并根据id获得控件对象。
4、 在Activity中,创建一个Handler对象。
5、 在Activity中,创建一个Runnable对象。
a) 以匿名内部类的方式。
b) 将要执行的操作写在Runnable对象中的run()方法中。
i. 打印出一句话,并将TextView设置文本内容。
ii. 调用Runnable对象的postDelayed()方法。
6、 在Activity中,编写start按钮需要的监听器,并绑定。
a) 在这个监听器的Onclick()方法中,调用Handler的post()方法,将要执行的线程对象放到队列当中。
7、 在Activity中,编写end按钮需要的监听器,并帮定。
a) 在这个监听器的Onclick()方法中,调用Handler的removeCallbacks ()方法,删除队列当中未执行的线程对象。
b)
下面是Activity的代码:
Java代码:
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button startButton;
private Button endButton;
private TextView tv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 根据id获得控件对象
tv=(TextView) findViewById(R.id.textView1);
startButton = (Button) findViewById(R.id.StartButton);
endButton = (Button) findViewById(R.id.EndButton);
// 为控件设置监听器
startButton.setOnClickListener(new StartButtonListener());
endButton.setOnClickListener(new EndButtonListener());
}
class StartButtonListener implements OnClickListener {
public void onClick(View v) {
// 调用Handler的post()方法,将要执行的线程对象放到队列当中
handler.post(updateThread);
}
}
class EndButtonListener implements OnClickListener {
public void onClick(View v) {
// 调用Handler的removeCallbacks()方法,删除队列当中未执行的线程对象
handler.removeCallbacks(updateThread);
}
}
// 创建Handler对象
Handler handler = new Handler();
// 新建一个线程对象
Runnable updateThread = new Runnable() {
// 将要执行的操作写在线程对象的run方法当中
public void run() {
System.out.println("updateThread");
tv.setText("updateThread");
// 调用Handler的postDelayed()方法
// 这个方法的作用是:将要执行的线程对象放入到队列当中,待时间结束后,运行制定的线程对象
// 第一个参数是Runnable类型:将要执行的线程对象
// 第二个参数是long类型:延迟的时间,以毫秒为单位
handler.postDelayed(updateThread, 3000);
}
};
}
示例2:和上面一个例子相似,实现轮播图效果。
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView tv;
private Handler handler=new Handler();
private ImageView iv;
private int index;
private Myrunnable mr=new Myrunnable();
private int images[]={R.drawable.image,R.drawable.image2,
R.drawable.image3,R.drawable.image4};
class Myrunnable implements Runnable{
public void run() {
index++;
index=index%4;
iv.setImageResource(images[index]);
handler.postDelayed(mr, 1000);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView) findViewById(R.id.textview);
iv=(ImageView) findViewById(R.id.imageView1);
handler.postDelayed(mr, 1000);
}
}