Reputation: 3
I just want to continously update text in an android app. However my App crashes every time.
This is my code:
package org.pgvw.main;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class InertialView extends Activity {
TextView tv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tv = new TextView(this);
tv.setText("Time: ");
new Thread(new Runnable() {
public void run() {
while(true) {
try {
Thread.currentThread().sleep(100);
tv.setText("Time: " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
setContentView(tv);
}
}
Can anyone spot the mistake?
Greetings and thx!
Upvotes: 0
Views: 1807
Reputation: 3319
Consider that you do not need to launch any additional threads to update the UI every x milliseconds. The additional overhead of an added thread is justified IF you have a time intensive task. In the following example the timer is launched on a button click. Note that this code does not create a new thread.
private Handler myHandler= new Handler(){
@Override
public void handleMessage(Message msg){
switch(msg.what){
case 0:
if (!isDoneThinking){
editTextConfusedText.setText("Still Thinking "+new Integer(thinkSeconds).toString());
thinkSeconds++;
this.removeMessages(0);
sendMessageDelayed(obtainMessage(0),1000); // <== Loop on delayed messages every second
}
else {
thinkSeconds= 0; // reset timer
}
break;
default:
super.handleMessage(msg);
break;
}
}
};
We launch the timer in onClick. We simply send an empty message with a what value of "0".
buttonConfuseText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
isDoneThinking= false;
myHandler.sendEmptyMessage(0); <== starts timer with what value of "0"
}
};
The timer is unconstrained and will continue to count until the flag isDoneThinking is set to true.
Upvotes: 2
Reputation: 137282
You cannot update GUI from another thread. You can use runOnUiThread
or handler
to update the GUI.
for example:
new Thread(new Runnable() {
public void run() {
while(true) {
try {
Thread.currentThread().sleep(100);
runOnUiThread(new Runnable() {
public void run() {
tv.setText("Time: " + System.currentTimeMillis());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
BTW - The use of Thread.currentThread().sleep(100);
can be shorted to Thread.sleep(100)
since it's a static method. see Jon Skeet's answer regarding that
Upvotes: 2
Reputation: 2532
Or use AsyncTask. It was designed to do background tasks and properly update the UI. Your design will be more scalable this way.
Upvotes: 0