2012-04-02 76 views
1

我正在編寫一個Android遊戲,其中UI由分數(CPUScore和PlayerScore)的textViews組成。我遇到的問題是,在調用onCreate時,UI不會從其初始值更新分數。我看過類似的問題,最常見的解決方案是使用AsyncTask在後臺更新UI線程。然而,我沒有找到明確處理如何在AsyncTask中使用textViews的解決方案。使用AsyncTask刷新遊戲得分TextView

這裏是我的嘗試:

@Override 
    protected void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 
//.... 
setContentView(R.layout.main_layout); 

//..... 
//------------ textViews declared here don't refresh ------------------- 
TextView playerScoreForm = (TextView) findViewById(R.id.PlayerTotalScore); 
     playerScoreForm.setText(Integer.toString(PlayerTotal)); 
     playerScoreForm.invalidate(); 

     TextView CPUScoreForm = (TextView) findViewById(R.id.CPUTotalScore); 
     CPUScoreForm.setText(Integer.toString(CPUTotal)); 
     CPUScoreForm.invalidate(); 
//--------------------------------------------------------------------------  
//AsyncTask method:  
     new updatePlayerScore().execute(PlayerTotal); 
     new updateCPUScore().execute(CPUScoreForm); 
    } 

的的AsyncTask子類:

private class updatePlayerScore extends AsyncTask<TextView, Void, Void> { 

     @Override 
      protected TextView doInBackground(TextView... params) { 


        // what to put here?? 



      } 
      return playerScoreForm; 
     } 

      @Override 
     protected void onProgressUpdate(Integer... values) { 
      //?? 
     } 

     protected void onPostExecute(Integer result) { 
      playerScoreForm.setText(Integer.toString(result)); 
     } 

    } 


    private class UpdateCPUScore extends AsyncTask<TextView, Integer, Integer> { 
     // same syntax as updatePlayerScore 

    } 

問題: 我怎麼轉,我在onCreate方法到的AsyncTask方法聲明的textViews?我很難過。我對Android開發相當陌生。

+0

使'playerScoreForm'等類成員/將它們傳遞給構造函數或自定義AsyncTask的參數。 – zapl 2012-04-02 22:53:06

+0

您能否給我一個如何做到這一點的粗略例子? – Buzz 2012-04-02 23:25:04

回答

2

a)我敢肯定,你應該不需要在設置TextView後無效; Android應該這樣做自動。

b)理論上,您會將您的TextView引用設置爲成員變量,然後在onPostExecute中引用它們,而不是將它們傳遞給doInBackgrounddoInBackground反過來將採取任何一點數據使您能夠計算新的分數。你會在doInBackground上做什麼是任何會導致計算新分數的動作。 doInBackground的返回值傳入onPostExecute。然後,您將使用onPostExecute中的此數據更新TextView(現在是成員變量)。那有意義嗎?你實際上沒有發佈任何代碼來更新這些分數值。

查看here的快速示例。

private TextView myScoreView; //initialized in onCreate as you do above. 


@Override 
protected void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 
    //.... 
    setContentView(R.layout.main_layout); 

    //..... 

    myScoreView = (TextView) findViewById(R.id.PlayerTotalScore); 
    myScoreView.setText(Integer.toString(PlayerTotal)); 

    new updatePlayerScore().execute(1,2); //parameters for calculation 
} 

private class updatePlayerScore extends AsyncTask<Integer, Integer, Integer> { 

     @Override 
     protected TextView doInBackground(Integer... params) { 

       int score = params[0] + 2 * params[1]; 
       return score; 
     } 


     @Override 
     protected void onProgressUpdate(Integer... values) { 
      //if you want to provide some indication in the UI that calculation 
      //is happening, like moving a progress bar, that's what you'd do here. 
     } 

     @Override 
     protected void onPostExecute(Integer scoreCalculationResult) { 
      myScoreView.setText(Integer.toString(scoreCalculationResult)); 
     } 

} 

編輯:如果你不想做doInBackgroundThread的計算邏輯,你可能只是想用:

runOnUiThread(new Runnable(){ 
    @Override 
    public void run(){ 
     myScoreView.setText(PlayerScoreValue); 
    } 
}); 

或者:

myScoreView.post(new Runnable(){ 
    @Override 
    public void run(){ 
     myScoreView.setText(PlayerScoreValue); 
    } 
}); 
+0

感謝您的評論。遊戲玩法期間,遊戲邏輯更新public int PlayerTotal和public int CPUTotal分數。我的問題是如何轉換:TextView playerScoreForm =(TextView)findViewById(R.id.PlayerTotalScore); playerScoreForm.setText(Integer.toString(PlayerTotal));到一個AsyncTask進程。當在textView PlayerScoreForm上執行setText時,PlayerTotal的更新值(從遊戲循環更新)不會傳遞到UI線程。 – Buzz 2012-04-02 23:20:04

+0

這聽起來像AsyncTask在這裏使用是不正確的。我會更新我的答案。 – 2012-04-03 00:18:07

+0

非常感謝。我用了你的第一個編輯的建議,並在虛空方法updateScores()封閉它的:public void updateScores(){ \t \t \t runOnUiThread(新的Runnable(){ \t \t \t @覆蓋 \t \t \t公共無效的run() { \t \t \t \t playerScoreForm.setText(Integer.toString(PlayerTotal)); \t \t \t \t CPUScoreForm.setText(Integer.toString(CPUTotal)); \t \t \t} \t \t}); \t}。訣竅是從onCreate調用它得到初始分數,然後從遊戲中產生分數的方法調用它。 – Buzz 2012-04-03 19:13:21

0

您可以通過TextViewAsyncTask的構造函數中,並從onPostExecute方法更新它

private class updatePlayerScore extends AsyncTask<Void, Void, Integer> { 
private TextView view; 
public updatePlayerScore(TextView textView){ 
this.view = textView; 
} 
     @Override 
      protected Integer doInBackground(Void... params) { 
      int score = 0; 

        //do you calculation the 

      return score; 
     } 
     protected void onPostExecute(Integer result) { 
      view.setText(Integer.toString(result)); 
     } 

    } 

:如果因任何原因即用戶你的活動配置更改旋轉設備和您AsyncTask還沒有完成它的任務,你的更新TextView將不會被更新,所以你應該保留你一個實例AsyncTask並更新TextView

+0

感謝您的貢獻。我的錯誤是我試圖從onCreate獲得分數,但這是錯誤的,因爲onCreate只會觸發一次(即當第一次創建活動時),因此嘗試在onCreate執行時獲得分數意味着分數保留其初始值在初始化時傳遞給onCreate。 – Buzz 2012-04-03 19:17:09