Обновить счет игры TextView, используя AsyncTask - PullRequest
1 голос
/ 03 апреля 2012

Я пишу настольную игру для Android, в которой пользовательский интерфейс состоит из текстовых представлений для оценки (CPUScore и PlayerScore). У меня проблема в том, что пользовательский интерфейс не обновляет счет по сравнению с его начальным значением при вызове onCreate. Я рассмотрел аналогичные вопросы, и наиболее часто предлагаемое решение - использовать AsyncTask для обновления потока пользовательского интерфейса в фоновом режиме. Однако я не нашел решения, которое бы явно касалось использования textViews в AsyncTask.

Вот моя попытка:

@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

     }

Вопрос: Как передать textViews, которые я объявил в методе onCreate, в метод AsyncTask? Я в тупике. Я довольно новичок в разработке Android.

Ответы [ 2 ]

2 голосов
/ 03 апреля 2012

а) Я почти уверен, что вам не нужно лишать законной силы TextViews после того, как вы их установили;Android должен делать это автоматически.

b) Теоретически вы должны установить свои TextView ссылки в качестве переменных-членов, а затем ссылаться на них в onPostExecute вместо того, чтобы передавать их в doInBackground.doInBackground в свою очередь будет принимать те биты данных, которые позволят вам рассчитать новый счет.Что бы вы сделали на doInBackground, это действие, которое приведет к вычислению нового балла.Возвращаемое значение из doInBackground передается в onPostExecute.Затем вы обновите TextView (теперь переменная-член) с этими данными в onPostExecute.Имеет ли это смысл?На самом деле вы не разместили здесь ни одного кода, который бы обновлял эти значения.

См. здесь для быстрого примера.

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 голосов
/ 03 апреля 2012

Вы можете передать TextView в конструктор AsyncTask и обновить его с помощью метода 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));
         }

     }

note : если вы изменили конфигурацию действия длялюбая причина, т. е. пользователь поворачивает устройство, и вы AsyncTask не выполнили задачу, обновление вас TextView не будет обновлено, поэтому вам следует сохранить экземпляр AsyncTask и обновить TextView

...