Как правильно обновить TextViews в пользовательском интерфейсе в Android? - PullRequest
0 голосов
/ 22 марта 2012

Я пытаюсь обновить текстовые представления во время обработки этого цикла.Вот мой код, который я использую для этого действия.

public class StartDayActivity extends Activity {
Data data_;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.startdayscreen);            


    Thread seperationTimer = new Thread(){
        public void run(){
            int seperationTimer = 5000;
            int weatherAffect = 0;
            int randomEventAffect = 0;
            int locationTotalAvailable = 10;
            //int servingTime = 3000;
            int totalAvailableCustomers = (weatherAffect + randomEventAffect + locationTotalAvailable);
            int dayTimer = (totalAvailableCustomers * seperationTimer);
            int seperationTimerDay = 0;
            int lemonadeSold = 11;
            int totalDrinksSold = 0;
            int pitcherSize = 12;
            int totalLemonsUsed= 0;
            int totalIceUsed =0;
            int totalSugarUsed = 0;
            int totalCupsUsed = 0;
            double drinkPrice = 0.80;

            try{                    
                while(seperationTimerDay < dayTimer){  
                    sleep(seperationTimer);
                    seperationTimerDay = seperationTimerDay + seperationTimer;
                    lemonadeSold = lemonadeSold + 1;
                    totalDrinksSold += 1;
                    data_.cups_ -= 1;
                    totalIceUsed += 2;

                    if(lemonadeSold == pitcherSize){
                        lemonadeSold = 0;
                        data_.lemons_ -= 4;
                        data_.sugar_ -= 2;  
                        totalSugarUsed +=2;
                        totalLemonsUsed +=4;                            
                    }
                    if(data_.lemons_ == 0 || data_.ice_ == 0 || data_.sugar_ ==0 || data_.cups_ == 0){
                        break;
                    }

                    updateView();
                    Log.d("TAG", "for each : " + data_.ice_);
                    //calcMarketing();
                }

                    data_.day_gross_profit_ = (totalDrinksSold * drinkPrice);
                    data_.cash_ += (totalDrinksSold * drinkPrice);
                Intent i = new Intent("com.game.lemonade.PLAYSCREEN");
                startActivity(i);
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }  
            finally{
                finish();
            }

        }
    };
    seperationTimer.start();
}   

@Override
public void onStart(){
    super.onStart();
    data_ = getData();

}
@Override
public void onResume(){
    super.onResume();
    data_ = getData();
    //refreshDisplay();
}

@Override
public void onPause(){
    super.onPause();
    saveData();
    //refreshDisplay();
}

@Override
public void onConfigurationChanged(Configuration newConfig){
    super.onConfigurationChanged(newConfig);
    //refreshDisplay();
}

private Data getData() {
    GameData player_data = new GameData(this);
    player_data.open();
    Data game_state = new Data(player_data.getGameString());
    player_data.close();
    return game_state;
  }

private void saveData() {
    GameData player_data = new GameData(this);
    player_data.open();
    player_data.setGameString(data_.SerializeGame());
    player_data.close();

}
private void updateView(){
    ((TextView)findViewById(R.id.lemonsLeftText2)).setText(
            (data_.lemons_) );
}
}

Есть ли лучший способ попробовать это сделать?И как бы я хотел это сделать?Я получаю сообщение об ошибке, когда я updateView() пытаюсь обновить текстовое представление.

Ответы [ 5 ]

1 голос
/ 22 марта 2012

Сообщение об ошибке уже содержит ответ на ваш вопрос. Вы не можете обновить пользовательский интерфейс из другого потока - используйте runOnUIThread() для этого. И ради батареи - получите ссылку на textView в onCreate () и используйте ее повторно.

0 голосов
/ 23 марта 2012

Вы должны использовать Handler класс:

Где вы звоните:

    updateView();

заменить на:

    myHandler.sendEmptyMessage(0);

В обработчике:

    private Handler myHandler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        if(msg.what==0){
            updateView();
        }
    };
};
0 голосов
/ 23 марта 2012

Хотя другие ответы охватывают ответ на ваш вопрос, я укажу вам на этот раздел документации.

Темы

В частности, последнийpart.

Кроме того, инструментарий Andoid UI не является поточно-ориентированным.Таким образом, вы не должны манипулировать своим пользовательским интерфейсом из рабочего потока - вы должны выполнять все манипуляции со своим пользовательским интерфейсом из потока пользовательского интерфейса.Таким образом, для однопоточной модели Android существует два правила:

  • Не блокировать поток пользовательского интерфейса
  • Не обращаться к инструментарию пользовательского интерфейса Android извне потока пользовательского интерфейса

Действительно, два очень простых правила, но если вы будете их придерживаться, вы избежите многих проблем.

0 голосов
/ 22 марта 2012

Вам не разрешено изменять внешний вид ваших View с любого потока, который не является основным потоком.

@ У Сердара есть отличные предложения, как с этим справиться.

Также вам следует избегать вызова findViewById () каждый раз, когда вам нужно вызвать setText (). findViewById () - довольно дорогой вызов с точки зрения системных ресурсов. Чем меньше таких звонков вы сделаете, тем лучше будет работать ваше приложение.

Я предлагаю вам сделать ссылку TextView и сделать вызов findViewById () внутри onCreate () и установить ссылку на то, что он вам возвращает. Затем в вашем методе updateView () вызовите что-то вроде yourTxt.setText("");

0 голосов
/ 22 марта 2012

Вы не можете получить доступ к пользовательскому интерфейсу, используя потоки напрямую. Либо используйте AsyncTask или Handler для операций с более длинными потоками, которые влияют на пользовательский интерфейс.

Проверьте это;

http://developer.android.com/resources/articles/painless-threading.html

http://developer.android.com/reference/android/os/Handler.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...