2017-03-20 44 views
0

我正在用大量數據更新數據庫(SQLite),這需要幾分鐘的時間。我正在線程上執行此操作。同時,我想通過吐司來展示更新的進度(25%,50%等)。由於我在一個線程內,我需要使用runOnUiThread()函數來運行Toast。像這樣:在繁重的工作負載任務期間舉行內線程

getActivity().runOnUiThread(new Runnable() { 
        public void run() { 
         Toast.makeText(getActivity(),"Updating the database...", Toast.LENGTH_SHORT).show(); 
        } 
       }); 

當工作量不夠大時,它工作正常。現在,它根本沒有烤麪包。

我一直在尋找方法來爲敬酒的線程設置非常高的優先級,但沒有成功。也許我可以繞過使用一個線程爲第一位的祝酒?

謝謝你的見解!

編輯:其實,麪包工作,但所有的工作已經完成後顯示。我想通知給用戶的完整更新百分比,所以我需要在更新期間顯示敬酒,而不是之後。

我嘗試刪除工作量(沒有數據庫更新,只有Log.d裏面的for循環的東西添加到數據庫)。儘管在循環內調用runOnUiThread()方法,但循環結束後仍會顯示吐司。

編輯2:我設法做我清理代碼,並開始新的後通緝。我發佈了以下用作答案的代碼。

+0

這麼大的工作量的某些部分在主線程上執行? – Massimo

+0

不,現在在主線程上沒有發生任何事情(只能聽按鈕點擊等等)。但是由於繁重的工作量,這些都沒有反應。 – Xema

+0

你有沒有在運行功能上放置一個斷點,並確保你到達那裏?或者在runOnUIThread調用? –

回答

0

AsyncTask小號已經清理了初始線程後,我設法有一些工作。我在這裏發佈的代碼,因爲它可以作爲一個模板做了具體任務:

運行一個初始線程定期做任務給定的次數(這裏收集一些數據)。該給定的次數後,將收集的數據被推到數據庫並通知用戶該工藝的進步(這需要很長的時間)的。

Timer timer = new Timer(); 
timer.scheduleAtFixedRate(new TimerTask(){ 
    long t0 = System.currentTimeMillis(); 
    @Override 
    public void run() { 
     if(System.currentTimeMillis() - t0 > EXPERIMENT_DURATION){ 
      processData(dataArrayList); // custom tasks - see below 
      cancel(); 
     }else { 
      dataArrayList = collectData(); // custom tasks 
     } 
    } 
}, 0, INTERVAL); 

有了:

void processData(Arraylist<Data> dataArrayList){ 
    for(Data data : dataArrayList){ 
     // show progression to the user 
     getActivity().runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       int percent = Math.round(((float)dataArrayList.indexOf(data))/((float)dataArrayList.size())*100) 
       Toast.makeText(getActivity(),"Update: " + Integer.toString(percent) + "%", Toast.LENGTH_LONG).show(); 
      } 
     }); 

     updateDataBase(data); 
    } 
} 
-1

我強烈建議你使用AsyncTask

AsyncTask執行的另一個工作Thread,但它提供了在UI ThreadpublishProgress(String ...)執行的方法。然後通過覆蓋onProgressUpdate(String ...)進行自定義。

編輯:正如評論閱讀,AsyncTask是不是一種選擇的是一件好事,因爲:

  • 所有的AsyncTask共享Thread(他們不workers如我所料運行)

  • 對於長時間運行的Task S,所有其他AsyncTasks(系統和你的)將保持

  • 這包括從圖書館

+1

AsyncTasks不應該用於超過一秒或兩秒的任何事情。原因是所有的AsyncTasks都共享一個公共線程,而長時間運行的任務會捱餓任何其他的AsyncTasks,因爲它們在你完成之前無法運行。你可以通過executeOnExecutor強制並行,但只能這麼做。 –

+0

@GabeSechan真的很有趣,我以爲他們只是'工人'。如果我知道它,我可能不會回答,但是,如果只有一個AsyncTask在同一時間工作,那麼問題是什麼? – JonZarate

+1

如果您有其他人在等待,他們會捱餓。直到前面的完成纔會運行。這包括您使用的圖書館或其他活動使用的圖書。最好避免使用不短的東西。他們以前是純粹的2.x工作者,Google改變了他們,因爲很多android程序員並不真正懂得如何進行並行編程並引發競爭條件 –

相關問題