【问题标题】:Android Progressbar not updatingAndroid进度条未更新
【发布时间】:2013-09-18 07:46:33
【问题描述】:

我在更新进度条时遇到问题。我在单独的线程中更新进度条,并且进度条进度所依赖的变量(这是一个类变量)在另一个线程中更新。因此,进度对话框显示但总是 0% 不更新它的进度。请帮帮我。

public void setProgressbar()
{
    progressBar = new ProgressDialog(context);
    progressBar.setCancelable(true);
    progressBar.setMessage("File downloading ...");
    progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    progressBar.setProgress(0);
    progressBar.setMax(100);
    progressBar.show();

    Thread thread = new Thread()
    {
        public void run()
        {


             while(progressBar.getProgress() < 100)
             {
                Log.v("progressbar", getProgress()+"");
                 progressBar.setProgress(getProgress());
                 try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
             }
        }
    };
    thread.start();

更新值代码

  Thread thread = new Thread()
   {
        public void run()
      {
      .
      .
      .
 while((bytesRead = is.read(bytearray, 0, bytearray.length)) != -1)
                    {
                     bos.write(bytearray, 0, bytesRead);
                     totaldownload = totaldownload + bytesRead;
                     Log.v("downloadign ", totaldownload+"");
                    // progressBar.setProgress((int) ((totaldownload/sizeoffile) * 100));
                    }
                    bos.close();
.
.
.
};
thread.start()

还有getPrgoress方法

 public int getProgress()
    {
        return (int) ((totaldownload/sizeoffile) * 100);
    }

【问题讨论】:

  • 我可能错了,但这看起来不像线程保存...
  • 在哪里增加进度值?
  • @Raghunandan 我现在编辑帖子你可以看到我在哪里更新依赖值
  • @MarioLenci 为什么 getProgress()+1 ??
  • @umerk44 对不起,我错过了你的回答。我认为您正在使用 progressBar.getProgress() 更新 setPregress() :\

标签: android multithreading progressdialog


【解决方案1】:

这是 ProgressBar 中的一个错误!

如果再次传递相同的值,setProgress(...) 似乎不会触发drawable 上的更新。但它也不会在setMax 期间触发。所以没有更新。

为了解决这个问题,我只是在每次更新之前做一个bar.setProgress(0)...这只是一种解决方法,但它对我来说可以按预期工作:

bar.setProgress(0); // call these two methods before setting progress.
bar.setMax(20);
bar.setProgress(20);

第二个选项。

mSeekBar.post(new Runnable() {
        @Override
        public void run() {
            mSeekBar.setProgress(percentOfFullVolume);
        }
    });

它也可能对某人有用。

【讨论】:

  • 这个问题解决了吗? @Nepster?
  • 我一直在努力解决在应用程序进入待机/打盹后不会更新到当前进度的进度条。您认为runOnUiThread() 会导致更新前端出现任何问题吗?
  • 'runOnUiThread()' 不会引起任何问题。或者您也可以使用 Handler();这也适用于主用户界面
  • 使用处理程序有什么好处?您还知道使用不同小部件的任何解决方法吗?
  • 将进度条设置为 0,将其设置为最大值并将其设置为对我有用的新进度!
【解决方案2】:

您正在更新线程的运行方法中的进度条。您无法从线程更新 ui。您需要在 ui 线程上更新 ui。使用runOnUiThreadrunOnUiThread是activity类的方法。

或者使用异步任务。

http://developer.android.com/reference/android/os/AsyncTask.html

在 asynctask doInBackground 中,您可以调用 publishProgress(Progress...) 来发布一个或多个进度单位。这些值发布在 UI 线程的 onProgressUpdate(Progress...) 步骤中。

【讨论】:

    【解决方案3】:

    你的逻辑有问题。将您的主题更改为关注

    Thread thread = new Thread()
    {
        public void run()
        {
            int prog = 0;
             while(prog < 100)
             {
    
                 progressBar.setProgress(prog);
                 try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                 prog ++;
             }
        }
    };
    thread.start();
    

    【讨论】:

    • 在我的情况下,传递给 setProgress() 的变量正在另一个线程中更新,而不是在当前线程中,请参阅我的帖子中的编辑
    • @umerk44 使用 asynctask 并使用发布进程。检查我帖子中发布的文档
    【解决方案4】:

    使用AsyncTask,本文档中还有一个示例可以满足您的需求。

    来自 AsyncTask 的这段代码实际上做了你想要完成的事情。

    private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }
    
     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }
    
     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
      }
    

    您只需将 setProgressPercent() 更改为进度条值更改的方法名称。如果不需要,可以删除 onPostExecute 方法 AFAIK。尝试使用 AsyncTask 代替 java Thread,因为 AsyncTask 已经提供了满足您需要的方法,而如果您使用 Thread 代替,则需要编写它们。

    【讨论】:

    • 添加更多信息以使答案更好,正在考虑发布一些类似的东西
    • 链接的文档已经有很好的例子来完成任务。我认为阅读/应用它可以提供足够的信息来处理 OPs 问题。
    • 最好从那个页面引用一些东西,看看thisthis,因为它会解释我的推理
    • 嗯,其实你是对的。我想,我只是懒惰。感谢您的警告。
    【解决方案5】:

    试试这个。

    在全局声明这个变量。

    int delay = 100;
    int period = 2000;
    

    在您需要的地方调用函数。

    public void setProgressbar()
    {
        progressBar = new ProgressDialog(context);
        progressBar.setCancelable(true);
        progressBar.setMessage("File downloading ...");
        progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressBar.setProgress(0);
        progressBar.setMax(100);
        progressBar.show();
    
        final Handler mhandler = new Handler();
    
        final Runnable mRunnable = new Runnable() {
    
            @Override
            public void run() {
    
                progressBar.setProgress(progress);
                progress++;
    
            }
        };
        final Timer timer = new Timer();
    
        timer.scheduleAtFixedRate(new TimerTask() {
    
            @Override
            public void run() {
    
                mhandler.post(mRunnable);
    
            }
        }, delay, period);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-24
      • 1970-01-01
      • 1970-01-01
      • 2019-01-08
      • 1970-01-01
      相关资源
      最近更新 更多