首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >安卓ProgressBar没有按预期更新吗?

安卓ProgressBar没有按预期更新吗?
EN

Stack Overflow用户
提问于 2014-05-31 05:18:18
回答 4查看 915关注 0票数 0

我正在使用一个TableLayout动态地使用一个AsyncTask填充一个行,并且没有得到预期的ProgressBar行为。

最初,我将ProgressBar的最大值设置为我正在处理的项数的三倍,以适应三个操作。这是我的密码:

onPreExecute:

代码语言:javascript
复制
        progress.setMax(items.size() * 3); // We need to create the rows and add listeners to them

异步类

代码语言:javascript
复制
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();
    }
}

那我就有:

代码语言:javascript
复制
@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只是:

代码语言:javascript
复制
protected void onProgressUpdate(String... values) {
  progress.incrementProgressBy(1);
}

最后,在我的onPostExecute method中,我对使用AsyncTask的活动进行了回调,在主要活动中如下所示:

代码语言:javascript
复制
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。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-05-31 11:49:18

由于某些原因,初始增量工作正常,使progressBar在完成后达到1/3满。

这意味着异步部分工作正常,第三个部分涉及doInBackground / ProgressUpdate,也就是说,大量工作是在UI线程之外完成的,只是表示进度更新。UI线程正在休眠,并愉快地等待更新请求。

之后,有2-5秒的暂停,UI线程阻塞,然后progressBar消失,我已将其设置为在(第三次也是最后一次操作)中的for循环结束后发生。然后显示数据.

另外两个操作在UI线程中进行。for in onPostExecutedonTaskCompleted都在UI线程上运行,并且都是紧密的循环。-- UI线程在循环中被阻塞。因此,当您在这些紧循环中时,不管您与任何UI组件混合了多少次: setprogress、settext等等.它不会更新,直到for循环结束,您的例程完成,并且系统再次控制UI线程.。

您可以做的是,就像看起来有大量行一样,将它们添加到块中,然后更新进度。这会让人透气的。看看下面的原型

代码语言:javascript
复制
 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); 
 }

因此,要添加您现在可以执行的行:

代码语言:javascript
复制
 addRows (new AddRowListener() {
       public void onRowsAdded() {

           // the rows have been added.

       }
 });

顺便问一下,你的行号是多少?一定很大!

PD_您必须选择一个CHUNK_SIZE。只需尝试值,直到UI是快速的。我会说40-50是可以的,但这只是一个疯狂的猜测,取决于手机硬件。

票数 0
EN

Stack Overflow用户

发布于 2014-05-31 05:50:00

不要将progress.setMax()设置在doInBackground()中,而是在onPreExecute()中设置它。您不应该修改工作线程/后台线程中的UI线程(主线程),而且doInBackground()正是在这里运行的。onPreExecute()onProgressUpdate()onPostExecute()在UI线程上运行。

票数 0
EN

Stack Overflow用户

发布于 2014-05-31 06:03:53

为什么不使用线程更新进度条。如果您想手动设置,则此方法非常适合更新progress........but,然后首先设置进度条的最大值,只需在onPreExecute中调用下面的方法,然后调用onPostExecute

代码语言:javascript
复制
 progressBar.setProgress(value);

当您从onPreExecute调用时,值应该是最大值的一半,然后是从onPostExecute......but调用的百分比,我建议您使用线程来更新正确的进度。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23966656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档