您的位置:首页 > 产品设计 > UI/UE

ProgressBar 为什么可以在非UI线程中更新进度。

2016-04-17 12:31 621 查看
最近在网上看到一个面试题,要求如下:

页面上现有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源码的实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: