如何在Android中的UI中正确更新TextView?

时间:2012-03-22 19:47:48

标签: android while-loop

我正在尝试在循环处理时更新文本视图。这是我用于此活动的代码。

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()尝试更新textview时出错。

5 个答案:

答案 0 :(得分:1)

错误消息已包含您问题的答案。您无法从不同的线程更新UI - 使用runOnUIThread()执行此操作。为了电池的缘故 - 在onCreate()中引用textView并重用它。

答案 1 :(得分:0)

您无法直接使用线程访问UI。请使用AsyncTaskHandler进行影响用户界面的较长线程操作。

检查这些;

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

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

答案 2 :(得分:0)

不允许您从任何非主线程的线程更改View的外观。

@Serdar对如何处理它有一些很好的建议。

每次你需要调用setText()时,你应该避免调用findViewById()。就系统资源而言,findViewById()是一个相当昂贵的调用。您的应用运行效果越好,就越少。

我建议你自己创建一个TextView引用并在onCreate()中调用findViewById()并设置对它返回给你的引用。然后在你的updateView()方法中调用yourTxt.setText("");

之类的东西

答案 3 :(得分:0)

虽然其他答案已经涵盖了您的问题的答案,但我会在文档的这一部分指出。

Threads

特别是最后一部分。

  

此外,Andoid UI工具包不是线程安全的。因此,您不能从工作线程操纵UI - 您必须从UI线程对您的用户界面进行所有操作。因此,Android的单线程模型只有两个规则:

     
      
  • 不要阻止UI线程
  •   
  • 不要从UI线程外部访问Android UI工具包
  •   

确实有两个非常简单的规则,但如果坚持下去,你就会避免很多问题。

答案 4 :(得分:0)

您应该使用Handler类:

你打电话的地方:

    updateView();

替换为:

    myHandler.sendEmptyMessage(0);

在处理程序中:

    private Handler myHandler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        if(msg.what==0){
            updateView();
        }
    };
};