第二种:Handler
Handler异步实现时涉及到Handler,Looper,Message,Thread四个对象,实现异步的流程时主线程启动子线程,子线程运行生成Message,Looper获取到Message并传递给Handler逐个获取Looper中的Message,并进行UI更新。
优点:
结构清晰,功能定义明确
对于多个后台任务时,简单,清晰
缺点:
对于单个后台异步处理时,显得代码过多,结果太复杂;
在主线程(UI线程)里,如果创建Handler时不传入Looper对象,那么将直接使用主线程(UI线程)的Looper对象(系统已经帮我们创建了);在其它线程里,如果创建Handler时不传入Looper对象,那么,这个Handler将不能接收处理消息。在这种情况下,通用的作法是:
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) { // process incoming messages here
}
};
Looper.loop();
}
}
在创建Handler之前,为该线程准备好一个Looper(Looper.prepare),然后让这个Looper跑起来(Looper.loop),抽取Message,这样,Handler才能正常工作。
因此,Handler处理消息总是在创建Handler的线程里运行。而我们的消息处理中,不乏更新UI的操作,不正确的线程直接更新UI将引发异常。因此,需要时刻关心Handler在哪个线程里创建的。
代码:
private Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
switch (msg.what)
{
case 1:
progressBar.setProgress((Integer)msg.obj);
break;
default:
break;
}
}
};
class MyRunnable implements Runnable
{
@Override
public void run()
{
for (int i = 0; i <=100; i += 10)
{
try
{
Thread.sleep(300);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
Message message = new Message();
message.what = 1;
message.obj = i;
handler.sendMessage(message);
}
}
}