2016-02-23 150 views
1

我有一個數組代表迷宮。在UI上,迷宮被表示爲按鈕的行和列。在異步任務的doInBackground方法中,我搜索了一個路徑並用導致目標的路徑初始化一個解決方案數組。我想要做的是更新這些按鈕的按鈕文本,以顯示通向目標的路徑。我在OnPostExecute中這樣做。但是,它不起作用。它甚至不執行啓用解決方案按鈕的最後一行。我在哪裏做什麼?從OnPostExecute更新UI(異步)

private void updateUI() { 
    Button cell; 
    TableRow row; 

    do { 
     row = (TableRow) (State.maze.getChildAt(solution.row)); 
     cell = (Button) (row.getChildAt(solution.col)); 
     cell.setText(State.pathCell); 
     try { 
      Thread.sleep(100); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     solution = solution.next; 
    } while (solution.next != null); 
} 

@Override 
protected void onPostExecute(String result) { 
    super.onPostExecute(result); 
    updateUI(); 
    //Enable solution button 
    State.solveResetButton.setEnabled(true); 

} 

更新: 我檢查,以確保解決方案變量包含一個解決方案,它包含有效data.I還試圖消除睡眠,但無濟於事。

UPDATE: logcat的輸出(在紅色的)

02-23 13:09:15.471 4640-4640/? E/Zygote: MountEmulatedStorage() 
02-23 13:09:15.471 4640-4640/? E/Zygote: v2 
02-23 13:09:15.471 4640-4640/? E/Zygote: accessInfo : 0 
02-23 13:09:15.471 4640-4640/? E/SELinux: [DEBUG] get_category: variable seinfo: default sensitivity: NULL, cateogry: NULL 
+0

是否有您的logcat的任何異常做到這一點? – Lal

+0

一個簡單的解決方案將可用,如果你可以調試它.. – Lal

+0

你可以發佈你的所有代碼,你是否在串行Executor上運行AsyncTask? –

回答

1

不進行更新,你while循環solution.next的價值。這導致無限循環,因此您的updateUI()方法永遠不會停止執行。

此外,作爲AsyncTask的一部分的onPostExecute始終在主線程上調用。您不想在主線程上使用Thread.sleep。這是獲得ANR的好方法。

關於如何做到這一點,有很多方法可能有效。考慮這樣的一個處理程序主線程:

private void updateUI() { 
    Button cell; 
    TableRow row; 

    if (solution != null){ 
     row = (TableRow) (State.maze.getChildAt(solution.row)); 
     cell = (Button) (row.getChildAt(solution.col)); 
     cell.setText(State.pathCell); 
     solution = solution.next; 
     new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       updateUI(); 
      } 
     }, 100); 
    } 
} 

你也可以用一個新的AsyncTask使用publishProgress回調到UI線程

private void updateUI(){ 
    new AsyncTask<Solution, Solution, Void>(){ 
     @Override 
     protected Void doInBackground(Solution... solutions) { 
      Solution solution = solutions[0]; 
      do { 
       publishProgress(solution); 
       try { 
        Thread.sleep(100); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       solution = solution.next; 
      } 
      while(solution.next != null); 
      return null; 
     } 

     @Override 
     protected void onProgressUpdate(Solution... values) { 
      super.onProgressUpdate(values); 
      Solution solution = values[0]; 
      row = (TableRow) (State.maze.getChildAt(solution.row)); 
      cell = (Button) (row.getChildAt(solution.col)); 
      cell.setText(State.pathCell); 
     } 

     @Override 
     protected void onPostExecute(Void aVoid) { 
      super.onPostExecute(aVoid); 
      //Enable solution button 
      State.solveResetButton.setEnabled(true); 
     } 
    }.execute(solution); 
} 

@Override 
protected void onPostExecute(String result) { 
    super.onPostExecute(result); 
    updateUI(); 
} 
+0

那麼延遲更新按鈕文本的正確方法是什麼,以便一次只更新一個按鈕?現在,它不會延遲,但一次更新所有按鈕。 – user3273345

+1

@ user3273345我已經編輯了上面的答案以包含一些代碼示例。這些只是您可以選擇的2個選項。有很多方法可以完成你想要做的事情。 – jacobhyphenated

+0

對不起,延遲迴復,但得到它的工作。謝謝! – user3273345