一、Handler的定义:
主要接受子线程发送的数据, 并用此数据配合主线程更新UI.解释: 我们需要更新主线程(也叫UI线程)里面的ui,比如填充一个TextView,但是这个过程可能比较耗时,就可以通过生成一个子线程的方式来实现。但是子线程是不能更新UI的,这个时候就可以用Handler来处理。
我们只需要这样做:
子线程中传递Message给Handler(用handler传递,handler.setMessage(Bundle bundle))
Handler处理Message,更新UI(handler.HandleMessage(Message msg),这是一个回调函数,会自动执行)
二、作用
主要有两个作用:
1.在新启动的线程中发送消息
2.在主线程中获取、处理消息(回调机制来实现)
三、与Handle工作的几个组件Looper、MessageQueue各自的作用
1.Handler:它把消息发送给Looper管理的MessageQueue,并负责处理Looper分给它的消息
2.MessageQueue:采用先进的方式来管理Message
3.Looper:每个线程只有一个Looper,比如UI线程中,系统会默认的初始化一个Looper对象,它负责管理MessageQueue,不断的从 MessageQueue中取消息,并将相对应的消息分给Handler处
四、在线程中使用Handler的步骤
从非UI线程传递消息到UI线程(界面主线程),因为主界面已经有MessageQueue,所以可以直接获取消息处理消息。而上面由主线程向非UI线程中处理消息的时候,非UI线程需要先添加消息队列,然后处理消息循环。<span style="font-family:Microsoft YaHei;">package com.example.handlertest;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
private MyHandler myHandler;
private TextView textView;
private MyThread myThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myHandler = new MyHandler();
textView = (TextView)findViewById(R.id.text);
myThread = new MyThread();
new Thread(myThread).start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
class MyHandler extends Handler{
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
textView.setText("name="+msg.getData().getString("name")+"\n"+msg.getData().getString("password"));
}
}
class MyThread implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
Bundle bundle = new Bundle();
bundle.putString("name", "yanru");
bundle.putString("password", "123456");
Message message = new Message();
message.setData(bundle);
myHandler.sendMessage(message);
}
}
}
</span>
从主线程发送消息到子线程(准确地说应该是非UI线程)
<span style="font-family:Microsoft YaHei;">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实例
}
});
}
class CustomThread extends Thread {
@Override
public void run() {
//建立消息循环的步骤
Looper.prepare();//1、初始化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、启动消息循环
}
}
}</span>