我的活动有一个ProgressBar。启动活动时,我会检查从其他地方获取的值并更新到ProgressBar。这是我的代码:
final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar_detail);
final TextView progressText = (TextView) findViewById(R.id.progressText_detail);
final ImageView btnCancel = (ImageView) findViewById(R.id.imgCancel_detail);
progressBar.setVisibility(View.VISIBLE);
progressText.setVisibility(View.VISIBLE);
btnCancel.setVisibility(View.VISIBLE);
Thread t = new Thread() {
public void run() {
((Activity) ctx).runOnUiThread(new Runnable() {
public void run() {
int oldProgress = 0;
while (progressBar.getProgress() < 100) {
int value = Downloader.progress.get(gameId+ "");
if (value != oldProgress) {
oldProgress = value;
progressBar.setProgress(value);
progressText.setText(value + " %");
}
}
}
});
}
};
t.start();
ProgressBar的价值我来自int value = Downloader.progress.get(gameId)
并且它是正确的。但是,当我运行此代码时,活动没有响应,也没有显示任何内容(但应用程序没有崩溃)。看起来像更新ProgressBar的线程正在运行并阻止UI线程,因此活动布局没有显示。
我的代码出了什么问题?在这种情况下更新ProgressBar的正确方法是什么?
答案 0 :(得分:12)
您正在UI线程中运行while (progressBar.getProgress() < 100)
(使用runOnUiThread
),因此在此循环完成之前,UI线程将被阻止(并且不会被绘制)。
你可以:
将runOnUiThread
放入循环中,或许可以在de runOnUiThread
调用中进行睡眠。但是,它不是首选的解决方案,因为您使用太多CPU来查找值更改。睡眠接近它有点难看但解决了cpu问题。它会像::
Thread t = new Thread() {
public void run() {
int oldProgress = 0;
while (progressBar.getProgress() < 100) {
((Activity) ctx).runOnUiThread(new Runnable() {
public void run() {
int value = Downloader.progress.get(gameId+ "");
if (value != oldProgress) {
oldProgress = value;
progressBar.setProgress(value);
progressText.setText(value + " %");
}
}
}
Thread.sleep(500);
}
});
}
};
以事件方式更新进度条,以便在进度更改时仅调用(在UI线程中)更新代码。这是首选方式。
答案 1 :(得分:1)
尝试:
int currentPosition=0;
int total=mediaPlayer.getDuration();
while(mediaPlayer!=null && currentPosition<total){
try{
if(progressEnable){
Thread.sleep(1000);
currentPosition=mediaPlayer.getCurrentPosition();
long pos=1000L * currentPosition/total;
Log.d("thread pos", pos+"");
progressSeekBar.setProgress((int) pos);
}
}
catch (Exception e) {
}
}
全局声明progressEnable:
private boolean progressEnable=true;
答案 2 :(得分:0)
我通常使用此代码:
private int mProgressStatus;
private Handler mHandler = new Handler();
public void startProgress(View view) {
final ProgressBar progressBar = (ProgressBar) findViewById(R.id.horizontal_progress);
mProgressStatus = 0;
progressBar.setProgress(mProgressStatus);
//progressBar.setVisibility(View.VISIBLE);
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(final Void... params) {
while (mProgressStatus < 100) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
mProgressStatus += 15;
mHandler.post(new Runnable() {
public void run() {
progressBar.setProgress(mProgressStatus);
}
});
}
return null;
}
}.execute();
}
希望这有帮助
答案 3 :(得分:0)
您可以使用RXJava自动提升进度条。
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (autoProgress) {
autoProgressSubscriber = Observable.interval(0, 1000/60, TimeUnit.MILLISECONDS) //~60fps
.map(index -> calculateAutoProgress())
.subscribe(progress -> {
if (progressBar != null) {
progressBar.setProgress(progress);
}
});
}
}
@Override
protected void onDetachedFromWindow() {
if (autoProgress) {
autoProgressSubscriber.unsubscribe();
}
super.onDetachedFromWindow();
}