public class MainActivity extends Activity
{
int min, sec;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
min = 5;
sec = 0;
final TextView timer1 = (TextView) findViewById(R.id.timer1);
timer1.setText(min + ":" + sec);
Thread t = new Thread() {
public void run() {
sec-=1;
if (sec<0) {
min-=1;
sec=59;
}
timer1.setText(min + ":" + sec);
try
{
sleep(1000);
}
catch (InterruptedException e)
{}
}
};
t.start();
}
}
This is a code for a Thread in Java but it doesn't work. Can you help me?
Its a Timer that counts down from 5 Minutes to 0:00.
The timer isn't a thread BUT having a timer fire events asynchronously can be regarded as a form of multi-threading - along with all the traditional multi-threading issues!
A core (CPU) in Processor will handle only one Task ( Process or Thread ) at a given time. so in Processor with 1 core will handle one thread at a time. so technically no matter how many threads you open for this processor it will serve a thread at a given time.
Working on multiple tasks at the same time is Multitasking. In the same way, multiple threads running at the same time in a machine is called Multi-Threading. Technically, a thread is a unit of a process.
In your case you are using threads. So you cannot update ui from the thread other than the ui thread. SO you use runOnUithread
. I would suggest you to use a countdown timer or a Handler.
1.CountDownTimer
http://developer.android.com/reference/android/os/CountDownTimer.html
Here's a link to another example. Suggest you to check the link for the count down timer.
Countdowntimer in minutes and seconds
Example:
public class MainActivity extends Activity {
Button b;
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.textView1);
b= (Button) findViewById(R.id.button1);
b.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
startTimer(200000);
}
});
}
private void startTimer(long time){
CountDownTimer counter = new CountDownTimer(30000, 1000){
public void onTick(long millisUntilDone){
Log.d("counter_label", "Counter text should be changed");
tv.setText("You have " + millisUntilDone + "ms");
}
public void onFinish() {
tv.setText("DONE!");
}
}.start();
}
}
2.You can use a Handler
Example :
Handler m_handler;
Runnable m_handlerTask ;
int timeleft=100;
m_handler = new Handler();
m_handlerTask = new Runnable()
{
@Override
public void run() {
if(timeleft>=0)
{
// do stuff
Log.i("timeleft",""+timeleft);
timeleft--;
}
else
{
m_handler.removeCallbacks(m_handlerTask); // cancel run
}
m_handler.postDelayed(m_handlerTask, 1000);
}
};
m_handlerTask.run();
3.Timer
Timer runs on a different thread. You should update ui on the ui thread. use runOnUiThread
Example :
int timeleft=100;
Timer _t = new Timer();
_t.scheduleAtFixedRate( new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() //run on ui thread
{
public void run()
{
Log.i("timeleft",""+timeleft);
//update ui
}
});
if(timeleft>==0)
{
timeleft--;
}
else
{
_t.cancel();
}
}
}, 1000, 1000 );
You are trying to update the UI Thread
from a background Thread
with
timer1.setText(
which you can't do. You need to use runOnUiThread()
, AsyncTask
, CountDownTimer
, or something similar.
See this answer for an example of runOnUiThread()
But CountDownTimer is nice for things like this.
Also, when posting a question on SO, statements like "it doesn't work." are very vague and often unhelpful. Please indicate the expected results compared to actual results of your code and logcat if the app is crashing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With