- 首先看一段在子线程中更新UI的操作
Handler handler = new Handler();
//这是Button的点击事件
public void onClick(View v) {
//开启子线程
new Thread(new Runnable() {
@Override
public void run() {
String str= null;//这里必须要写上 = null !!初始化
try {
Thread.sleep(3000);
str = "网路请求得到的数据";
} catch (InterruptedException e) {
e.printStackTrace();
}
// 这里也必须为final
final String finalStr = str;
handler.post(new Runnable() {
@Override
public void run() {
//在这里将得到的数据直接更新到UI中
textView.setText(finalStr);
}
});
}
}).start();
}
- 主要查看Handler.post()方法
- 第一:生成Message对象
- 第二:将Runnable对象放入到msg的callback属性中,并把msg放入MessageQueue消息队列中!
//Handler类中
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
// 1.首先查看 getPostMessage(Runnable r)方法: 返回msg对象
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();//得到Msg对象
m.callback = r;
//将r对象赋值给msg的callback属性----msg的callback就是Runnable对象
return m;
}
//再来查看sendMessageDelayed(getPostMessage(r), 0);
//其实就等同于sendMessageDelayed(msg, 0);
// 2. 该方法下面一系列的操作就是将msg存入到消息队列中
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
...........
- Looper.loop()方法:
- (主线程)从消息队列中取出Runnable对象,及Message对象中的callback属性
- 可以去[http://blog.csdn.net/buttonxin/article/details/51793781]查看loop()方法
public static void loop() {
//loop()方法中调用该方法
msg.target.dispatchMessage(msg);
}
//Handler类中的dispatchMessage()方法
public void dispatchMessage(Message msg) {
//这里就是原因:Runnable对象不为空
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
//执行handleCallback()方法:里面直接执行了Runnable对象的run方法!而不是生成Thread对象并将r放入去执行start()方法!!!这样是不会另开线程的!!!,只能在原有的线程中执行run()方法!!!
private static void handleCallback(Message message) {
message.callback.run();
}
- 有点等同于iOS中的O-C中的block(不懂百度,我也不懂…) block语句块允许开发者 将一段代码当成一个变量传来传去!!
- 所以用Handler.post()来充当该机制