我使用TableLayout
动态填充AsyncTask
行,但未获得预期的ProgressBar
行为。
我最初将ProgressBar
的最大值设置为我正在处理的项目数的三倍,以容纳三个操作。这是我的代码:
onPreExecute:
progress.setMax(items.size() * 3); // We need to create the rows and add listeners to them
异步类
public class TableLoader extends AsyncTask<Object, String, Boolean>{
@Override
protected Boolean doInBackground(Object... params) {
for (int i = 0; i < items.size(); i++) {
// doStuffToCreateRow
rows.add(row);
progress.publishProgress();
}
}
然后我有:
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (!isCancelled()) {
for (int i = 0; i < rows.size(); i++) {
table.addView(rows.get(i));
progress.incrementProgressBy(1);
}
table.requestLayout();
listener.onTaskCompleted();
}
}
其中publishProgress只是:
protected void onProgressUpdate(String... values) {
progress.incrementProgressBy(1);
}
最后,在我的onPostExecute method
中,我回调了使用AsyncTask
的活动,在主要活动中看起来像这样:
public void onTaskCompleted() { // TableRows have been generated
TableLayout itemTable = (TableLayout) findViewById(R.id.itemTable);
for (int i = 0; i < itemTable.getChildCount(); i++) {
TableRow row = (TableRow) itemTable.getChildAt(i);
// Create and add a listener to that row's checkbox
// progress.incrementProgressBy(1);
}
progress.setVisibility(View.GONE);
}
由于某种原因,初始增量正常工作并导致progressBar
在完成后生成1/3(生成TableRows)。然后,在UI线程阻塞然后progressBar消失的情况下会有2-5秒的暂停,我将设置为在onTaskCompleted
(第三个和最后一个操作)中的for循环终止后发生。然后显示数据。
为什么我的progressBar
没有按预期更新?
我看过这个问题,但发现人们通过&lt; 1使用除法或不使用UI线程。据我所知,我正在使用UI线程进行更新,每次增加1个/项目数* 3。
答案 0 :(得分:0)
不要在progress.setMax()
内设置doInBackground()
,而是在onPreExecute()
内进行设置。您不应该从工作者/后台线程修改UI线程(主线程),并且确实存在doInBackground()运行的位置。在UI线程上运行onPreExecute()
,onProgressUpdate()
和onPostExecute()
。
答案 1 :(得分:0)
为什么您没有使用线程来更新进度条。这种方法非常适合更新进度........但如果你想手动设置,那么首先设置进度条的最大值只需在onPreExecute中调用下面的方法,然后调用onPostExecute
progressBar.setProgress(value);
当你从onPreExecute调用时,Value应该是最大值的一半,然后从onPostExecute调用%百分比......但是我建议你使用一个线程来更新正确的进度。
答案 2 :(得分:0)
不要在onPostExecute中使用publishProgress。只需调用incrementProgressBy。
答案 3 :(得分:0)
出于某种原因,初始增量正常工作并导致progressBar在完成后达到1/3满
这意味着Async部分正常工作,你的第三个是涉及doInBackground / ProgressUpdate的部分,也就是说,重要的东西是在UI线程之外完成的,只是表示进度更新。 UI线程正在休眠,并且正在等待更新请求。
然后,在UI线程阻塞然后progressBar消失的情况下会有2-5秒的暂停,我已经设置为在onTaskCompleted
中的for循环之后发生(第三次和最后一次操作) )终止。然后显示数据。
其他两个操作发生在UI线程中。 onPostExecuted
和onTaskCompleted
中的 for 都在UI线程上运行并且是紧密循环。 您的循环中阻止了UI线程。因此,当你进入那些紧密的循环时,无论你与任何UI组件混合了多少次:setprogress,settext等.... 它将不会更新,直到for循环结束,你的例程完成,系统再次控制UI线程。
你可以做的是,因为看起来有很多行,要以块的形式添加它们然后更新进度。这会给一些空气。看看以下原型
Handler handler=new Handler();
interface AddRowListener {
public void onRowsAdded();
}
private void addRowChunk(final int startRow, final int totalRows, final AddRowListener listener) {
for (int i=startRow; i<startRow+CHUNK_SIZE; i++) {
if (i>=totalRows) {
// we have finished! Just call the listener
listener.onRowsAdded();
return;
}
addView....
}
// After adding some rows, we end here, and schedule a call to this function again
// to continue. The 25ms delay is optional, but it will give some air to Android for sure
handler.postDelayed(new Runnable() {
addRowChunk(startRow+CHUNK_SIZE, totalRows, listener);
}, 25);
}
private void addRows(AddRowListener listener) {
TableLayout itemTable = (TableLayout) findViewById(R.id.itemTable);
// we start the process, it will create row chunks and call the listener when done
addRowChunk (0, itemTable.getChildCount(), listener);
}
所以要添加你现在可以做的行:
addRows (new AddRowListener() {
public void onRowsAdded() {
// the rows have been added.
}
});
顺便问一下,你的行大小是多少?它必须是巨大的!
PD_您必须选择CHUNK_SIZE。只需尝试使用值,直到UI变得活泼。我说40-50是可以的,但这只是一个疯狂的猜测,取决于手机硬件。