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>