Android提供了一个异步的消息回调机制Handler, 它负责发送消息和处理线程消息队列中的消息及runnable对象,Handler实例都是与一个线程和该线程的消息队列一起使用,一旦创建了一个新的handler实例,系统就把该实例与一个线程和该线程的消息队列捆绑起来,这将可以发送消息和runnable对象给该消息队列,并在消息队列出口处处理它们。
Handler默认使用当前的线程RunLoop,
但是也可以通过它的构造函数来指定某个线程的runloop, 或者使用专用的HandlerThread。
使用Handler的线程中,必须实现了Runloop消息循环,否则会产生运行异常。
通常情况下,如果我们在主线程使用Handler, 则不需要我们主动去创建runloop, 因为android系统为自动为activity主线程创建一个runloop。
我们可以在一个特殊的子线程中使用Handler,而不必去创建runloop。这个特殊子线程就是HandlerThread, 查看其源码,我们可以发现,它也在run方法中实现了runloop。
通过handler中一个线程向消息队列中用sendMessage方法发送消息,发送的消息当然可以用来传递参数。在handler中用handleMessage来处理消息,处理方法是获得消息队列中的消息参数
本实验实现的是当开始按钮按下时,会启动一个线程,并绑定到handler中,该线程发送带有参数的message到handler的消息队列中,消息队列的另一端获取该消息,并且用该消息的参数来更新进度条。
package com.example.marshandler2;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
public class MainActivity extends Activity {
private ProgressBar proBar=null;
private Button start=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
proBar=(ProgressBar)findViewById(R.id.progressBar);
start=(Button)findViewById(R.id.start);
start.setOnClickListener(new startOnClickListener());
}
public class startOnClickListener implements OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
proBar.setVisibility(View.VISIBLE);
myHandler.post(myThread);
}
}
Handler myHandler=new Handler(){
@Override
public void handleMessage(Message msg){
proBar.setProgress(msg.arg1);
myHandler.post(myThread);
}
};
Runnable myThread=new Runnable(){
int i=0;
@Override
public void run() {
// TODO Auto-generated method stub
Message msg=myHandler.obtainMessage();
i+=10;
msg.arg1=i;
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
myHandler.sendMessage(msg);
if(i==100)
myHandler.removeCallbacks(myThread);
}
};
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="match_parent"
android:layout_height="200dip"
style="?android:attr/progressBarStyleHorizontal"
android:visibility="gone"/>
<Button
android:id="@+id/start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="start"/>
</LinearLayout>