2017-06-02 130 views
0

我想處理一些文件,它需要一些時間,所以我想在操作正在執行時使用progressBar。在我的活動中,我有一個按鈕開始處理,當我按下它時,progressBar不會更新,過了一會兒操作完成,我看到處理的結果(因此函數被正確調用並充當預期)。progressBar沒有更新與setProgress

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(); 
      } 
     } 
    }); 

現在的進度工作,但使用processedFile失敗,這是我用Glide顯示的圖像,它以前運行良好,但現在它不顯示任何東西。

編輯2:使用runOnUiThread所有用戶界面更新像一個魅力工作,並修復了我的新問題。

+0

哪個線程你鬥這個循環的每個迭代上? –

回答

0

您需要使用兩個線程:

主線程(也稱爲UI線程)(又名WhereYouWorkAlways線程)

查找和存儲ProgressBar,創建一個Handler,然後創建新的線程(見以下)

工作線程(又名只是一個新的線程)

裏面的線程中運行nable,工作的每個步驟後(=每個文件操作完成後),在該更新進度條

handler.post(new Runnable() { 
    public void run() { 
     progressBar.setProgress(i); 
    } 
}) 

爲什麼需要兩個線程

主線程的處理器發佈Runnable實際上UI線程,這意味着,每一個操作被放置在下一週期的「更新」的步驟:

-> Update -> (Re)Draw -> Wait -> 

這意味着,如果更新持續10秒,然後屏幕上會後10秒更新。(大多數的用戶界面是單線程爲主)

+0

如果你想要我添加更多的代碼只需要詢問... – MaanooAk

+0

嗨,感謝您的幫助。是否有可能不使用兩個線程來更新progressBar?爲什麼我的方法不起作用? – barouf

+0

已更新的答案,包括您的問題 – MaanooAk

0

因爲你已經progressBar.setProgress(0);

+0

這是一個其他海報有相同問題的建議,我也更新到正確的值後,無論如何,所以它應該沒有關係。 – barouf

+0

對不起,我沒看過'setProgress(i + 1);' –