一、 Handler的定义:
通过Handler你可以发布或者处理一个消息或者是一个Runnable的实例。每个Handler都会与唯一的一个线程以及该线程的消息队列关联。当你创建一个新的Handler时候,默认情况下,它将关联到创建它的这个线程和该线程的消息队列。
主要接受子线程发送的数据,并用此数据配合主线程更新UI.
解释:当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) ,主线程为管理界面中的UI控件,进行事件分发,比如说,
你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。 如果此时需要一个耗时的操作。例如:联网读取数据,或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,,如果你放在主线程中的话,界面会出现假死现象,如果5秒钟还没有完成的话,,会收到Android系统的一个错误提示 "强制关闭". 这个时候我们需要把这些耗时的操作,放在一个子线程中, 因为子线程涉及到UI更新,,Android主线程是线程不安全的,也就是说,更新UI只能在主线程中更新,子线程中操作是危险的.这个时候,Handler就出现了.,来解决这个复杂的问题 , 由于Handler运行在主线程中(UI线程中), 它与子线程可以通过Message对象来传递数据,这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据) , 把这些消息放入主线程队列中,配合主线程进行更新UI.
二、 Handler一些特点
handler可以分发Message对象和Runnable对象到主线程中,每个Handler实例,都会绑定到创建他的线程中(一般是位于主线程),
它有两个作用:
(1) 安排消息或Runnable在某个主线程中某个地方执行,
(2)安排一个动作在不同的线程中执行
Handler中一些方法
public final boolean sendMessage(Message msg)
把消息放入该Handler所关联的消息队列,放置在消息队列尾部。
public void handleMessage(Message msg)
关联该消息队列的线程将通过调用Handler的handleMessage方法来接收和处理消息,通常需要子类化Handler来实现handleMessage。
另外:
post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
以上post类方法允许你排列一个Runnable对象到主线程队列中,
三、Handler和线程的关系
Handler和Activtiy是出于同一线程的。直接调用run函数,是在当前线程中调用run方法。
例子:
publicclass MainActivityextends Activity { /** Called when the activity is first created. */ private Handlerhandler =new Handler();
@Override publicvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handler.post(r); setContentView(R.layout.main); System.out.println("Activity_ID---->" + Thread.currentThread().getId()); System.out.println("Activity_NAME---->" + Thread.currentThread().getName());
}
Runnabler =new Runnable() {
@Override publicvoid run() { System.out.println("Handler_ID---->" + Thread.currentThread().getId()); System.out.println("Handler_NAME---->" + Thread.currentThread().getName()); try { Thread.sleep(10000); }catch (InterruptedException e) {
e.printStackTrace(); } }
}; } |
四、举例说明:
man.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:text="线程ID:"
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<ProgressBar
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:id="@+id/bar"/>
<Button
android:text="Button"
android:id="@+id/startButton"
</LinearLayout>
HandlerActivity.java
public class HandlerActivity extends Activity {
private TextView textView;
private MyHandler myHandler;
private Button button;
private ProgressBar progressBar;
private MyThread m = new MyThread();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView=(TextView)findViewById(R.id.text);
button=(Button)findViewById(R.id.startButton);
progressBar=(ProgressBar)findViewById(R.id.bar);
progressBar.setMax(100); //Set the range of the progress bar to 0...max
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
myHandler=new MyHandler();
new Thread(m).start();
System.out.println("onCreate线程ID是: "+Thread.currentThread().getId());
}
});
}
//在对UI进行更新时,执行时所在的线程为主UI线程
class MyHandler extends Handler{//继承Handler类时,必须重写handleMessage方法
public MyHandler(){}
public MyHandler(Looper lo){
super(lo);
}
@Override
public void handleMessage(Message msg) {
System.out.println("Handler线程ID是: "+Thread.currentThread().getId());
super.handleMessage(msg);
Bundle b = msg.getData();//Obtains a Bundle of arbitrary data associated with this event
String textStr0 = textView.getText().toString();
String textStr1 = b.getString("textStr");
HandlerActivity.this.textView.setText(textStr0+" "+textStr1);//更改TextView中的值
int barValue = b.getInt("barValue");
HandlerActivity.this.progressBar.setProgress(barValue);//更改进度条当中的值
}
}
//该线程将会在单独的线程中运行
class MyThread implements Runnable{
int i = 1;
public void run() {
while(i < 11){
System.out.println("Thread线程ID是: "+Thread.currentThread().getId());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message msg = new Message();
Bundle b = new Bundle();
b.putString("textStr", "线程运行"+i+"次");
b.putInt("barValue", i*10);
i++;
msg.setData(b);//Sets a Bundle of arbitrary data values
HandlerActivity.this.myHandler.sendMessage(msg);//通过sendMessage向Handler发送更新UI的消息
}
}
}
}
说明:Activity的onCreate方法里启动一个线程,在这个线程的run方法里使用一个Message对象并使用Handler的sendMessage方法发送到队列中,最后在Activity里new一个Handler的内部类实现handMessage方法,使用这个方法把队列中的Message对象取出来以实现异步操作。
例子2:使用post:
public class MyThread extends Activity {
private Handler handler = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Handy class for starting a new thread that has a looper
HandlerThread handlerThread = new HandlerThread("myHandlerThread");
//Starts the new Thread of execution
handlerThread.start();
//handlerThread.getLooper():This method returns the Looper associated with this thread
handler = new Handler(handlerThread.getLooper());
//Causes the Runnable r to be added to the message queue
handler.post(new MyRunnable());
System.out.println("onCreate线程ID:"
+ Thread.currentThread().getId());
setContentView(R.layout.main);
}
private class MyRunnable implements Runnable {
public void run() {
System.out.println("Runnable线程ID正在运行:");
System.out.println("Runnable线程ID:"
+ Thread.currentThread().getId());
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
参考博客:http://lichen.blog.51cto.com/697816/486402