我正在使用一个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)。之后,有2-5秒的暂停,UI线程阻塞,然后progressBar消失,我已将其设置为在onTaskCompleted中的for循环(第三个也是最后一个操作)结束后发生。数据就会显示出来。
为什么我的progressBar不按预期更新?
我已经查找了这个问题,但发现人们使用除法或不使用UI线程将栏的增量增加了<1。据我所知,我正在使用UI线程进行更新,每次增加1/3项*3。
发布于 2014-05-31 11:49:18
由于某些原因,初始增量工作正常,使progressBar在完成后达到1/3满。
这意味着异步部分工作正常,第三个部分涉及doInBackground / ProgressUpdate,也就是说,大量工作是在UI线程之外完成的,只是表示进度更新。UI线程正在休眠,并愉快地等待更新请求。
之后,有2-5秒的暂停,UI线程阻塞,然后progressBar消失,我已将其设置为在(第三次也是最后一次操作)中的for循环结束后发生。然后显示数据.
另外两个操作在UI线程中进行。for in onPostExecuted和onTaskCompleted都在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是可以的,但这只是一个疯狂的猜测,取决于手机硬件。
发布于 2014-05-31 05:50:00
不要将progress.setMax()设置在doInBackground()中,而是在onPreExecute()中设置它。您不应该修改工作线程/后台线程中的UI线程(主线程),而且doInBackground()正是在这里运行的。onPreExecute()、onProgressUpdate()和onPostExecute()在UI线程上运行。
发布于 2014-05-31 06:03:53
为什么不使用线程更新进度条。如果您想手动设置,则此方法非常适合更新progress........but,然后首先设置进度条的最大值,只需在onPreExecute中调用下面的方法,然后调用onPostExecute
progressBar.setProgress(value);当您从onPreExecute调用时,值应该是最大值的一半,然后是从onPostExecute......but调用的百分比,我建议您使用线程来更新正确的进度。
https://stackoverflow.com/questions/23966656
复制相似问题