一、Handler介绍
在一个线程中存在一个消息队列,当消息队列中存在消息时,Handler就会处理这些消息;我们考虑一下这种场景:
我们要执行一个耗时很长的业务,执行完后要返回一个结果显示在TextView上,我们在主线程中执行这种业务是否合理呢?
显然是不合理的,因此我们会想到把业务放到子线程中执行,但是Android有个规定:所有更新UI的操作全要在主线程中完成,因此我们要做的就是把子线程执行完的结果传到主线程中并显示,这就需要Handler的帮忙;
比如ProgressBar、TextView的使用都会用到Handler;
当应用5秒内没有响应用户的输入,则会抛出以下错误:

Handler的原理如下:

模板代码:
package org.xiazdong.handler;
public class SampleActivity extends Activity {
private Button button;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what == 1){
//更新UI
}
if(msg.what == 2){
//更新UI
}
}
};
private OnClickListener listener = new OnClickListener() {
class ServiceThread extends Thread{
private ServiceListener serviceListener = new ServiceListener() {
@Override
public void onService(int current) {//服务监听器
//一边执行,一边发送消息给主线程
handler.sendMessage(msg);
}
};
@Override
public void run() {
//执行业务
}
}
@Override
public void onClick(View v) {
ServiceThread thread = new ServiceThread(); //子线程执行业务
thread.start();
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button)this.findViewById(R.id.button);
button.setOnClickListener(listener);
}
}二、实例
程序说明:
执行一个业务:从零开始,每隔3秒加1,直到加到5,返回结果5,并通过ProgressBar实时显示加到几了;
程序类声明:
(1)ServiceListener接口:此接口专门用来监听服务进行,并根据服务进行执行逻辑
- onService(int current);
(2)Service:此类为业务类,执行此业务;
执行效果:点击开始执行,则每三秒进度条加1,等到进度满时,显示result=5;
ServiceListener.java
package org.xiazdong.handler;
/**
* Service监听器
* @author xiazdong
*
*/
public interface ServiceListener {
public void onService(int current);
}
Service.java
package org.xiazdong.handler;
public class Service {
private int sum = 5;
private int current = 0;
public void sum(ServiceListener listener)throws Exception{
while(current<sum){
Thread.sleep(3000);
current++;
listener.onService(current);
}
}
}
MainActivity.java
package org.xiazdong.handler;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView textView;
private Button button;
private ProgressBar progressBar;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what == 1){
int current = msg.getData().getInt("current");
progressBar.setProgress(current);
}
if(msg.what == 2){
int result = msg.getData().getInt("result");
textView.setText("result="+result);
}
}
};
private OnClickListener listener = new OnClickListener() {
class ServiceThread extends Thread{
private ServiceListener serviceListener = new ServiceListener() {
@Override
public void onService(int current) {//服务监听器
Message msg = new Message();
msg.what = 1;
msg.getData().putInt("current", current);
handler.sendMessage(msg);
}
};
@Override
public void run() {
Service service = new Service();
progressBar.setMax(5); //设置最大进度
progressBar.setProgress(0); //初始进度为0
try {
service.sum(serviceListener); //执行业务,并传入监听器,监听业务的执行
//当执行完成,发送最后的结果5给TextView
Message msg = new Message();
msg.what = 2;
msg.getData().putInt("result", 5);
handler.sendMessage(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void onClick(View v) {
ServiceThread thread = new ServiceThread(); //子线程执行业务
thread.start();
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView = (TextView)this.findViewById(R.id.textView);
button = (Button)this.findViewById(R.id.button);
progressBar = (ProgressBar)this.findViewById(R.id.progressBar);
button.setOnClickListener(listener);
}
}
本文详细介绍了如何在Android应用中利用Handler将后台任务与UI更新分离,确保应用响应及时且用户体验良好。通过实例展示了如何在子线程执行耗时操作,并通过Handler将结果传递回主线程进行UI更新。
1591

被折叠的 条评论
为什么被折叠?



