Android的应用程序中的可能会造成阻塞的操作一般是放在WorkerThread中的,最后会返回MainThread向用户反馈结果或者更新UI,一般会用到以下几种方法:
- handler.sendMessage(msg);
- handler.post(r);//此处r为Runnable对象
- view的post(r);
Activity中的runOnUiThread(r);
后面两种方法的本质还是基于handler.post(r)方法的
以下为handler.post()的测试代码:
public class MainActivity extends ActionBarActivity {
private Button button;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.buttonId);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
TextThread t = new TextThread();
t.start();
}
});
}
class TextThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
Runnable r = new Runnable() {
@Override
public void run() {
String currentThread = Thread.currentThread().getName();
System.out.println("当前线程为:" + currentThread ); //此处更新UI
}
};
handler.post(r);
}
}
}
运行会发现Runnable中的操作其实是发生在主线程中的,整个过程分为两部分:
- 将r对象放置在消息队列中
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}//延迟0秒其实就相当于sendMessage(getPostMessage(r));
这个过程其实是靠handler的getPostMessage()方法完成的,以下为该方法的源码:
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
我们可以看到先生成一个Message对象(位于主线程),然后将r对象赋给该Message对象的callback属性,然后是将Message对象放置在消息队列中。所以post方法的实质可以用以下代码表示:
public final boolean post(Runnable r){
Message msg = getPostMessage(r);
return sendMessage(msg);
}
- 取出消息并处理
从上一步可以看出,Looper取出的其实是赋了r的Message对象,取出之后会调用disPatchMessage()方法,先来看看该方法的源码
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
这个方法会首先判断Message对象的callback属性是否为空(还记得第一步将r对象赋给该Message对象的callback属性了吗),如果不为空,会调用handleCallback(msg)方法;
private static void handleCallback(Message message) {
message.callback.run();
}
在该方法中直接调用了message.callback.run()方法,此时在MainThread中完成了UI操作。
方法3和方法4可参考:Click here