Reputation: 59
I am trying update text views while this loop is processing. Here is my code that I am using for this activity.
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_) );
}
}
Is there a better way to try to do this? And how would I want to do that? I get an error when I do the updateView()
to try to update textview.
Upvotes: 0
Views: 1357
Reputation: 5157
You cant access the UI using threads directly.Either use an AsyncTask
or Handler
for your longer thread operations which effect the UI.
Check these;
http://developer.android.com/resources/articles/painless-threading.html
http://developer.android.com/reference/android/os/Handler.html
Upvotes: 0
Reputation: 1233
You should use Handler
class:
Where you call:
updateView();
replace with:
myHandler.sendEmptyMessage(0);
In the handler:
private Handler myHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what==0){
updateView();
}
};
};
Upvotes: 0
Reputation: 48871
Although the other answers have covered the answer to your question, I'll point you at this section in the documentation.
In particular the last part.
Additionally, the Andoid UI toolkit is not thread-safe. So, you must not manipulate your UI from a worker thread—you must do all manipulation to your user interface from the UI thread. Thus, there are simply two rules to Android's single thread model:
- Do not block the UI thread
- Do not access the Android UI toolkit from outside the UI thread
Two very simple rules indeed but if you stick to them you'll avoid a lot of problems.
Upvotes: 0
Reputation: 46856
You are not allowed to change the appearance of your View
s from any thread that is not the main thread.
@Serdar has some great suggestions for how to handle that.
Also you should avoid calling findViewById() each time you need to call setText(). findViewById() is a fairly expensive call in terms of system resources. The fewer calls like that you make the better your app will run.
I suggest you make yourself a TextView reference and make your findViewById() call inside onCreate() and set your reference to what it returns to you. Then in your updateView() method call something like yourTxt.setText("");
Upvotes: 0
Reputation: 12367
Error message already contains answer to your question. You can not update UI from different thread - use runOnUIThread()
to do this. And for battery sake - get reference to textView in onCreate() and reuse it.
Upvotes: 1