2016-02-23 108 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