欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Handler与Android多线程详解

程序员文章站 2022-10-09 14:04:09
下面是一段大家都比较熟悉的代码:复制代码 代码如下:handler handler = new handler(); handler.post(mythread); //...

下面是一段大家都比较熟悉的代码:

复制代码 代码如下:

handler handler = new handler();
handler.post(mythread);


//使用匿名内部类创建一个线程mythread
runnable mythread = new runnable() {
public void run() {
}
};


一开始,相信很多人都以为mythread中的run()方法会在一个新的线程中运行,但事实并非如此。

上述代码中的handler并没有调用线程mythread的start()方法,而是直接调用了run()方法,这也就意味着实际上并没有创建一个新的线程,只是在当前线程中调用run()方法而已。

这牵扯出一个问题,如果我们将一个很耗时的操作放到了run()方法内,然后使用一个handler对象将该线程post到线程队列。原本我们希望将这些耗时操作放到另外一个线程中,以免影响当前进程。但实际上却恰恰相反:post()以下的那些代码必须等到run()方法执行完毕后才能继续执行。如当前线程为主线程,那么主程序便会处于硬直状态。

那么应该如何去实现真正的多线程呢?

一种最简便的方法就是直接利用java中的实现多线程的方法,即建立一个thread对象,然后调用start()方法。

还有另外一种方法,代码如下:

复制代码 代码如下:

//handlerthread建立了一个新线程,它包含一个looper
handlerthread handlerthread = new handlerthread("handler_thread");
handlerthread.start();//启动一个线程
myhandler myhandler = new myhandler(handlerthread.getlooper());//使用新线程的looper建立一个handler
//此时myhandler便与一个新线程绑定到一起了

message msg = myhandler.obtainmessage();
msg.sendtotarget();//将message压入提供message的handler的消息队列中

//建立一个handler的子类
class myhandler extends handler {
myhandler(looper looper) {
super(looper);
}
public void handlemessaage(message msg) {
//处理消息的代码
}
}


今天我又仔细的看了一下android文档,发现android虽然支持上两种建立线程的方法,但是它有一个规则:

原文是:it violates the second rule of the single-threaded model: do not access the android ui toolkit from outside the ui thread.

大概意思就是:android不支持在ui线程以外的线程中修改ui控件。比如给一个textview设置文字,这样的操作便不能放在ui线程以外的线程内执行,否则便会出现异常。