一. 消息机制的存在理由
1. ANR 全名是application is not response,即程序无响应,这是android非常常见的异常,在点击屏幕后,UI在5秒内无更新,则会抛出ANR的异常.
2. 为了避免ANR的出现,android规定所有关于网络方面等耗时的操作都不能在主线程中运行,否则会报错(2.3版本不会报错,4.0后会报).
3. android的另一规定 : 由主线程(UI线程)创造出来的view,任何子线程都不允许对其更新操作.
那么问题就来了,如果要从网络上下载一个资源并展示出来或者从事一个比较耗时的操作, 该怎么办?很显然, 必须要创建一个子线程来完成这个事,
但是这又有一个矛盾,那就是子线程不能更新view,很简单的道理,自己不能做的事只有叫能做这个事的去做了,于是这个时候只有叫主线程来帮忙更新UI了,
那么如果让主线程知道何时更新怎么更新UI,android为我们提供了一个handler类,这就是消息机制的作用.
在这简单地剖析一下上面的这个图:
1.子线程在需要通知主线程更新界面的时候, 创建一个handler对象,通过该对象的方法sendMessage发送一个消息给主线程.
Message message = new Message(); message.what = TestHandler.what1; TestHandler.this.myHandler.sendMessage(message);
2. 主线程中有一个消息队列messageQueue,在收到消息后会将其直接添加到队尾.
3. 主线程中有一个轮询器looper,他的工作就是一直遍历messageQueue并从队头取出消息并处理,处理消息的具体操作在handleMessage()方法里.
Handler myHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case TestHandler.what1: myView.update(); break; } super.handleMessage(msg); } };
注:发送消息的handler对象必须与handler对象为同一对象, 因此必须在主线程中创建handler对象并重写方法handleMessage(),在子线程中使用.
二. 除了采用handler消息机制进行线程间通信的方法来更新UI外,android还提供了另一种简便的方法来更新主线程的UI,那就是方法 runOnUiThread(Runnable r)
runOnUiThread(Runnable r)的定义:如果当前线程是主线程,则立即执行该线程;如果不是,则将其放入UI线程的messageQueue队列等待处理,原理与handler相同.
用法:
new Thread() { public void run() { //子线程不能直接更新UI //1. handler 方法 //Message msg = new Message(); //msg.what = 1; //mHandler.sendMessage(msg) //将消息放入UI 线程的消息队列 //更新UI操作放在UI线程中的handleMessage()方法里执行 //2. runOnUiThread() //runOnUiThread(new Runnable(){ public void run(){ //直接进行更新UI操作 } }); } }