2017-08-11 28 views
0

第一次寫AsyncTask,我似乎有一個微妙的設計缺陷,防止ProgressDialog,ProgressBar,甚至Log.d()正常工作。我懷疑,不知何故,我實際上並沒有創建一個新的線程/任務。Android:ASyncTask的行爲違背文檔

簡稱:症狀

  • 一個ProgressDialog是在構造函數創建的,該代碼的Android訂單給它顯示onPreExecute(),但是對話從來沒有顯示。

  • onProgressUpdate()應該在我從doInBackground()內調用publishProgress()時執行,對嗎?那麼,它不會。相反,它在doInBackground()完成時執行。

長:

事情我必須通過仿真器,並在可能的情況覈實調查

,在手機上:

  • onPreExecute()是絕對稱得上

    • 進度直到doInBackground()完成後才重置酒吧

    • update_dialog.show()肯定會執行,但除非我刪除中的.dismiss();我想象對話框,像進度條,不顯示,直到後doInBackground()完成,但自然是立即解僱

    • 代碼將愉快地顯示對話框時,沒有計算涉及

  • doInBackground()絕對調用publishProgress()

    • 當它發生時,onProgressUpdate()不立即執行!也就是說,我在函數中有一個斷點,調試器不會在那裏停止,直到doInBackground()完成! (也許這是調試器的一個現象,而不是doInBackground(),但我觀察在移動設備上相同的症狀)

    • 的都會更新進度條... doInBackground()完成一切

    • 同樣只後,在Android的監視器Log.d()數據顯示,高達doInBackground()一切完成後,才

  • ,當然還有對話並不無論是在模擬器或設備上顯示出來(除非我刪除.dismiss() from onPostExecute()

任何人都可以幫助找到問題嗎?理想情況下,我想要一個工作對話框,但Android已經棄用了,無論如何,我會很好地處理一個工作進度條。

代碼

下面是要領,計算&Ç:少細節

當我打電話AsyncTask從主線程:

if (searching) { // this block does get executed! 
    Compute_Task my_task = new Compute_Task(overall_context, count); 
    my_task.execute(field, count, max_x, max_y); 
    try { result = my_task.get(); } catch (Exception e) { } 
} 

AsyncTask本身:

private class Compute_Task extends AsyncTask<Object, Integer, Integer> { 

    public Compute_Task(Context context, int count) { 
     super(); 
     current_positions = 0; 
     update_dialog = new ProgressDialog(context); 
     update_dialog.setIndeterminate(true); 
     update_dialog.setCancelable(false); 
     update_dialog.setTitle("Thinking"); 
     update_dialog.setMessage("Please wait"); 
    } 

    protected void onPreExecute() { 
     super.onPreExecute(); 
     update_dialog.show(); 
     ProgressBar pb = ((ProgressBar) ((Activity) overall_context).findViewById(R.id.progress_bar)); 
     pb.setMax(base_count); 
     pb.setProgress(0); 
    } 

    protected void onPostExecute() { 
     super.onPostExecute(); 
     update_dialog.dismiss(); 
    } 

    protected void onProgressUpdate(Integer... values) { 
     super.onProgressUpdate(values); 
     ProgressBar pb = ((ProgressBar) ((Activity) overall_context).findViewById(R.id.progress_bar)); 
     pb.setMax(base_count); 
     pb.incrementProgressBy(1); 
     Log.d(tag, values[0].toString()); 
    } 

    protected Integer doInBackground(Object... params) { 
     Integer result = compute_scores(
     (boolean[][]) params[0], (Integer) params[1], (Integer) params[2], (Integer) params[3], 0) 
    ); 
     return result; 
    } 

    public int compute_scores(boolean[][] field, int count, int max_x, int max_y, int level) { 
     int result, completed = 0; 
     switch(count) { 
     // LOTS of computation goes on here, 
     // including a recursive call where all params are modified 
     if (level == 0) 
      publishProgress(++completed); 
     } 
    } 

    ProgressDialog update_dialog; 

} 

回答

0

原來這與問題here的問題基本相同。 「致命」線是這一個:

try { result = my_task.get(); } catch (Exception e) { } 

顯然這使得UI線程陷入深度睡眠。 除非有人願意暫停UI線程,否則不應使用get()AsyncTask我們不得不在onPostExecute()中執行一點魔術。

雖然事實證明這是重複的,但直到我寫完之後才發現它,因爲我沒有意識到線程被阻塞。