最近在网上看到一个面试题,要求如下:
页面上现有ProgressBar控件progressBar,请用书写线程以10秒的的时间完成其进度显示工作。
package com.jiao;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
public class MainActivity extends AppCompatActivity {
private ProgressBar mProgressBar;
private Button mStartBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressBar = (ProgressBar) findViewById(R.id.progress);
mStartBtn = (Button) findViewById(R.id.start);
mStartBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
doProgress();
}
});
}
public void doProgress(){
new Thread(new Runnable() {
@Override
public void run() {
try {
int progressMax = mProgressBar.getMax();
while(progressMax != mProgressBar.getProgress()){
int step = progressMax / 10;
mProgressBar.setProgress(mProgressBar.getProgress() + step);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
看到这段代码的时候在想,是不是写错了!怎么可以在非UI线程中更新ProgressBar 的进度呢?后来,看了 ProgressBar.java 源码才明白。
先看setProgress(int progress)方法的实现
refreshProgress()方法的实现
在这里我们可以看到,
(1)先判断是否是UI线程,是的话就直接执行doRefreshProgress()方法来更新 ProgressBar。(2)否则创建一个RefreshProgressRunnable对象,然后添加到View的消息队列中也就是post(mRefreshProgressRunnable),说白就是用handler来更新UI。以下是源码的展示。
RefreshProgressRunnable的实现
View.post(Runable)的实现
如果有描述不清楚的话,大家可以看看ProgressBar.java源码的实现。