注意:由主线程向非UI线程中发送消息的时候,非UI线程需要先添加消息队列,然后处理消息循环。
(1).默认情况下android中新诞生的线程是没有开启消息循环的。(主线程除外,主线程系统会自动为其创建Looper对象,开启消息循环。) Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。
(2).在非主线程中直接new Handler() 会报如下的错误: E/AndroidRuntime( 6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception E/AndroidRuntime( 6173): Java.lang.RuntimeException: Can’t create handler inside thread that has not called Looper.prepare() 原因是非主线程中默认没有创建Looper对象,需要先调用Looper.prepare()启用Looper。
在利用handler机制发送消息时,looper扮演者及其重要的信息,关于looper本文没做详细的介绍,如果你仅仅只是想简单的实现主线程给子线程发送Message,那下面的代码基本就能满足你的需求,如果有兴趣深入了解looper机制,请点击
Android – Looper.prepare()和Looper.loop() —深入版
package com.zhuozhuo;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
public class LooperThreadActivity extends Activity{
/** Called when the activity is first created. */
private final int MSG_HELLO = 0;
private Handler mHandler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new CustomThread().start();//新建并启动CustomThread实例
findViewById(R.id.send_btn).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {//点击界面时发送消息
String str = "hello";
Log.d("Test", "MainThread is ready to send msg:" + str);
mHandler.obtainMessage(MSG_HELLO, str).sendToTarget();//发送消息到CustomThread实例
}
});
}
//採用內部类的方式定义一个类继承自Thread并重写run()方法,在主线程将会新建线程对象并开启这个线程
class CustomThread extends Thread {
@Override
public void run() {
//**下面的代码是从工作线程接收主线程消息的关键代码**
//建立消息循环的步骤
Looper.prepare();//1、初始化Looper:让Looper开始工作,从消息队列里取消息,处理消息。
mHandler = new Handler(){//2、绑定handler到CustomThread实例的Looper对象
public void handleMessage (Message msg) {//3、定义处理消息的方法
switch(msg.what) {
case MSG_HELLO:
Log.d("Test", "CustomThread receive msg:" + (String) msg.obj);
}
}
};
Looper.loop();//4、启动消息循环
//注意:loop里面是一个循环,在调用looper.loop()后,这个循环就是一个死循环,有消息就处理,无消息就挂起!
//也就是说,写在looper.loop()这行代码下的其他代码都不会再执行了,除非你调用mHandler.getLooper().quit()后,
//loop才会中止,其后的代码才能得以运行!需要注意,退出之后这个线程也就无法继续监听主线程发来的消息了!!
//
}
}
}