2012-04-13 138 views
1

我目前正在創建一個程序,遞歸搜索android手機上的視頻的SD卡,然後生成每個視頻的散列。Android UI不更新

一切工作正常,但是當我試圖創建一個progress bar,在progress bar不更新,直到結束

所以基本上進度條的進度似乎從0轉到最大,但我可以從日誌輸出告訴值被髮送到進度條進行更新,進度條只是不upating。

我的代碼如下:

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     progress = (ProgressBar) findViewById(R.id.progressBar1); 
     text = (TextView) findViewById(R.id.tv1); 
     Button btnStart = (Button) findViewById(R.id.btnStart); 

     btnStart.setOnClickListener(new OnClickListener() { 
      public void onClick(View v) { 

       recursiveVideoFinder(new File("/sdcard")); 
       String strDB3File = getFilesDir().getPath() 
         + "/VideoHashes.db3"; 
       sql3 = SQLiteDatabase.openDatabase(strDB3File, null, 
         SQLiteDatabase.CREATE_IF_NECESSARY); 
       try { 
        String mysql = "CREATE TABLE videohashes (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, path TEXT NOT NULL, hash TEXT NOT NULL, date TEXT NOT NULL, size INTEGER)"; 
        sql3.execSQL(mysql); 
       } catch (SQLiteException e) { 
        // TODO: handle exception 
       } 

       progress.setProgress(0); 
       progress.setMax(myFiles.size()); 

       for (String path : myFiles) { 
        try { 
         String hash = getMD5Checksum(path); 
         ContentValues myInsertData = new ContentValues(); 
         myInsertData.put("path", path); 
         myInsertData.put("hash", hash); 
         Date date = new Date(); 
         myInsertData.put("date", dateFormat.format(date)); 
         myInsertData.put("size", getFileSize(path)); 
         sql3.insert("videohashes", null, myInsertData); 
         currVid++; 
         updateProgress(); 
         Log.i("Progress", "CurrVid:" + currVid + " Max:" 
           + progress.getMax()); 
         text.append(currVid + " "); 

        } catch (Exception e) { 
         Log.i("File", "File not Found"); 
        } 
       } 

       Cursor cur = sql3.query("videohashes", null, null, null, null, 
         null, null); 
       cur.moveToFirst(); 
       while (!cur.isAfterLast()) { 
        /* 
        * ((TextView) findViewById(R.id.tv1)).append("\n" + 
        * cur.getString(1) + "\n" + cur.getString(2) + "\n" + 
        * cur.getString(3) + "\n" + cur.getString(4) + "\n"); 
        */ 
        cur.moveToNext(); 
       } 
       cur.close(); 
      } 
     }); 

    } 

    public long getFileSize(String path) { 
     File file = new File(path); 
     return file.length(); 

    } 

    private void recursiveVideoFinder(File _dir) { 

     File[] files = _dir.listFiles(); 
     if (files == null) { 
      return; 
     } 

     for (File currentFile : files) { 
      if (currentFile.isDirectory()) { 
        recursiveVideoFinder(currentFile); 
       continue; 
      } else { 
       for (String aEnd : getResources().getStringArray(
         R.array.VideoExtensions)) { 
        if (currentFile.getName().endsWith(aEnd)) { 

         Log.d("PS:", currentFile.getPath().toString()); 

         String videoFileName = currentFile.getPath().toString(); 
         myFiles.add(videoFileName); 

        } 
       } 

      } 
     } 
    } 

    // Code based off this example: 
    // http://stackoverflow.com/questions/304268/getting-a-files-md5-checksum-in-java 
    public static byte[] createCheckSum(String filename) throws Exception { 
     InputStream fis = new FileInputStream(filename); 

     byte[] buffer = new byte[1024]; 
     MessageDigest complete = MessageDigest.getInstance("MD5"); 
     int numRead; 

     do { 
      numRead = fis.read(buffer); 
      if (numRead > 0) { 
       complete.update(buffer, 0, numRead); 
      } 
     } while (numRead != -1); 

     fis.close(); 
     // Return MD5 Hash 
     return complete.digest(); 
    } 

    public String getMD5Checksum(String filename) throws Exception { 
     byte[] b = createCheckSum(filename); 
     String result = ""; 

     for (int i = 0; i < b.length; i++) { 
      result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1); 
     } 
     return result; 
    } 

    public void updateProgress() { 
     progress.setProgress(currVid); 
     progress.invalidate(); 
     Log.i("Updating", "Updating Progress Bar"); 
    } 
} 
+0

此問題不僅限於進度條。我無法更新textview的。它們在這裏包含的代碼上方聲明,但我沒有包含該部分。我確信他們宣佈正確。 – johns4ta 2012-04-13 02:35:45

+0

'for循環'在ui線程中運行,它可能會阻塞ui,所以不能更新ui,你可以在後臺線程中做'for循環'嗎? – idiottiger 2012-04-13 02:46:02

+0

在我的原始代碼中,我將它放在單獨的線程中,但不是後臺線程,它仍然存在相同的問題。我會嘗試後臺線程,並讓你知道它是怎麼回事。謝謝。 – johns4ta 2012-04-13 12:01:09

回答

2

你爲什麼把所有的處理代碼中的onClick()。這不是一個好方法。創建一個AsyncTask並使用publishProgress更新您的進度條。

0

通過覆蓋onResume()放置更新任務。在那裏啓動一個新的定時器線程並繼續調用你的函數。當你點擊後,通過說timer.cancel()來完成該線程。所以無論你什麼時候開始這個活動,只有當計時器啓動並退出時退出。 Check this for more info