下面的代碼來自「Android Developer's Cookbook」一書的第58-61頁。本書在消息的上下文中介紹了代碼,這是在線程之間傳遞信息的一種方式。它通過說:「計時器在後臺線程中運行,因此它不會阻塞UI線程,但它需要隨時更改而更新UI」。Android UI線程和消息處理程序混淆
我很困惑,因爲我沒有看到兩個線程。對我來說,主UI線程似乎將一個可運行的消息發佈到它自己的消息隊列中(並且該消息隨後以延時重新發布)。我錯過了什麼嗎?
package com.cookbook.background_timer;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class BackgroundTimer extends Activity {
//keep track of button presses, a main thread task
private int buttonPress=0;
TextView mButtonLabel;
//counter of time since app started, a background task
private long mStartTime = 0L;
private TextView mTimeLabel;
//Handler to handle the message to the timer task
private Handler mHandler = new Handler();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (mStartTime == 0L) {
mStartTime = SystemClock.uptimeMillis();
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 100);
}
mTimeLabel = (TextView) findViewById(R.id.text);
mButtonLabel = (TextView) findViewById(R.id.trigger);
Button startButton = (Button) findViewById(R.id.trigger);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view){
mButtonLabel.setText("Pressed " + ++buttonPress + " times");
}
});
}
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
final long start = mStartTime;
long millis = SystemClock.uptimeMillis() - start;
int seconds = (int) (millis/1000);
int minutes = seconds/60;
seconds = seconds % 60;
mTimeLabel.setText("" + minutes + ":" + String.format("%02d",seconds));
mHandler.postDelayed(this, 200);
}
};
@Override
protected void onPause() {
mHandler.removeCallbacks(mUpdateTimeTask);
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
mHandler.postDelayed(mUpdateTimeTask, 100);
}
}
據我瞭解... Android的主UI線程實例化BackgroundTimer活動,其中包括一個Handler。 Handler將消息傳遞給創建它的線程,在這種情況下,它是主UI線程。在執行BackgroundTimer的onCreate方法時,主UI線程將消息發佈到自己的處理程序。在執行onCreate之後,主UI線程處理事件/消息,例如,它先前發佈的可運行消息。所以主UI線程最終執行Runnable代碼,而不是其他線程。 – user592503 2011-02-04 04:08:53
啊,是的。我應該更多地閱讀API文檔。我認爲當他們說「兩個線程」時,我認爲他們基本上是說在Runnable中運行的代碼不會阻塞主UI線程,因此您仍然可以與UI交互並且不會收到ANR消息,而Handler正在等待再次執行Runnable。 – SpencerElliott 2011-02-04 04:17:51