progressBar 未使用 setProgress 更新
progressBar not updating with setProgress
我正在尝试处理一些文件,这需要一些时间,所以我想在执行操作时使用进度条。在我的 activity 中,我有一个开始处理的按钮,当我按下它时,progressBar 没有更新,过了一会儿操作完成,我看到了处理的结果(所以功能是正确的调用并按预期操作)。
进度条是可见的,只是没有更新。我已经在日志中显示了getProgress()
并且值增加了,只有实际的progressBar没有更新。
应该更新进度条的函数:
private byte[] processFiles() throws ExecutionException, InterruptedException {
//Init things
final ArrayList<String> fileNames = getFileList();
progressBar.setVisibility(View.VISIBLE);
progressBar.setMax(fileNames.size());
progressBar.setIndeterminate(false);
for (int i = 0 ; i<fileNames.size(); i++) {
//Do stuff on files
progressBar.setProgress(i+1);
Log.d("CurrentActivity", String.valueOf(progressBar.getProgress()));
}
return bos.toByteArray();
}
在onCreate()
中:
progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressBar.setIndeterminate(false);
我也尝试过 android developer tutorial 中显示的使用线程但没有成功(虽然我没有使用 while 循环而是 for 循环,但我认为这无关紧要)。
谁能帮我解决这个问题?
请注意,我也尝试按照其他一些答案中的建议在每次更新之前使用它:
progressBar.setProgress(0);
progressBar.setMax(fileNames.size());
编辑,这是我的 onClickListener:
fileButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
// Init things
try{
new Thread(new Runnable() {
public void run() {
try {
outStream = new FileOutputStream(path);
outStream.write(processFiles());
outStream.close();
runOnUiThread(new Runnable() {
@Override
public void run() {
//stuff that updates ui
}
});
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}catch(Exception e){
e.printStackTrace();
}
}
});
现在 progressBar 可以工作了,但是使用 processedFile 失败了,它是我用 Glide 显示的图像,它以前工作得很好,但现在它不显示任何东西。
编辑 2:对所有 UI 更新使用 runOnUiThread
非常有效,解决了我的新问题。
您需要使用两个线程:
主线程(又名 UI 线程)(又名 WhereYouWorkAlways 线程)
找到并存储 ProgressBar
,创建一个 Handler
,然后创建新线程(见下文)
工作线程(也就是一个新线程)
在 Thread Runnable 中,在每个工作步骤之后(= 在每个文件操作完成之后)post Runnable
在更新进度条的处理程序中
handler.post(new Runnable() {
public void run() {
progressBar.setProgress(i);
}
})
为什么需要两个线程
主线程实际上是UI线程,这意味着每个操作都放在以下循环的"Update"步骤中:
-> Update -> (Re)Draw -> Wait ->
也就是说,如果更新持续10秒,那么屏幕将在10秒后更新。 (大多数 UI 都是基于单线程的)
因为在循环的每次迭代中你有 progressBar.setProgress(0);
我正在尝试处理一些文件,这需要一些时间,所以我想在执行操作时使用进度条。在我的 activity 中,我有一个开始处理的按钮,当我按下它时,progressBar 没有更新,过了一会儿操作完成,我看到了处理的结果(所以功能是正确的调用并按预期操作)。
进度条是可见的,只是没有更新。我已经在日志中显示了getProgress()
并且值增加了,只有实际的progressBar没有更新。
应该更新进度条的函数:
private byte[] processFiles() throws ExecutionException, InterruptedException {
//Init things
final ArrayList<String> fileNames = getFileList();
progressBar.setVisibility(View.VISIBLE);
progressBar.setMax(fileNames.size());
progressBar.setIndeterminate(false);
for (int i = 0 ; i<fileNames.size(); i++) {
//Do stuff on files
progressBar.setProgress(i+1);
Log.d("CurrentActivity", String.valueOf(progressBar.getProgress()));
}
return bos.toByteArray();
}
在onCreate()
中:
progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressBar.setIndeterminate(false);
我也尝试过 android developer tutorial 中显示的使用线程但没有成功(虽然我没有使用 while 循环而是 for 循环,但我认为这无关紧要)。
谁能帮我解决这个问题?
请注意,我也尝试按照其他一些答案中的建议在每次更新之前使用它:
progressBar.setProgress(0);
progressBar.setMax(fileNames.size());
编辑,这是我的 onClickListener:
fileButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
// Init things
try{
new Thread(new Runnable() {
public void run() {
try {
outStream = new FileOutputStream(path);
outStream.write(processFiles());
outStream.close();
runOnUiThread(new Runnable() {
@Override
public void run() {
//stuff that updates ui
}
});
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}catch(Exception e){
e.printStackTrace();
}
}
});
现在 progressBar 可以工作了,但是使用 processedFile 失败了,它是我用 Glide 显示的图像,它以前工作得很好,但现在它不显示任何东西。
编辑 2:对所有 UI 更新使用 runOnUiThread
非常有效,解决了我的新问题。
您需要使用两个线程:
主线程(又名 UI 线程)(又名 WhereYouWorkAlways 线程)
找到并存储 ProgressBar
,创建一个 Handler
,然后创建新线程(见下文)
工作线程(也就是一个新线程)
在 Thread Runnable 中,在每个工作步骤之后(= 在每个文件操作完成之后)post Runnable
在更新进度条的处理程序中
handler.post(new Runnable() {
public void run() {
progressBar.setProgress(i);
}
})
为什么需要两个线程
主线程实际上是UI线程,这意味着每个操作都放在以下循环的"Update"步骤中:
-> Update -> (Re)Draw -> Wait ->
也就是说,如果更新持续10秒,那么屏幕将在10秒后更新。 (大多数 UI 都是基于单线程的)
因为在循环的每次迭代中你有 progressBar.setProgress(0);