int delay = 1000; // delay for 1 sec.
int period = 10000; // repeat every 10 sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask()
{
Use onPostDelayed()
accessed from any of your View or a Handler. You save memory by not creating a Timer
or new Thread
.
private final Handler mHandler = new Handler();
private final Runnable mUpdateUI = new Runnable() {
public void run() {
displayData();
mHandler.postDelayed(mUpdateUI, 1000); // 1 second
}
}
};
mHandler.post(mUpdateUI);
There several mistakes you have done:
You should never invoke Thread.sleep() on the main thread (and you should never block it for a long time as well). Once main thread is blocked for more then 5 seconds, an ANR (application not responding) happens and it is force closed.
You should avoid using Timer in android. Try Handler instead. Good thing about handler is that it is created on the main thread -> can access Views (unlike Timer, which is executed on its own thread, which cannot access Views).
class MyActivity extends Activity {
private static final int DISPLAY_DATA = 1;
// this handler will receive a delayed message
private Handler mHandler = new Handler() {
@Override
void handleMessage(Message msg) {
if (msg.what == DISPLAY_DATA) displayData();
}
};
@Override
void onCreate(Bundle b) {
//this will post a message to the mHandler, which mHandler will get
//after 5 seconds
mHandler.postEmptyMessageDelayed(DISPLAY_DATA, 5000);
}
}
You code is failed because you perform sleep in background thread but display data must be performed in UI thread.
You have to run displayData from runOnUiThread(Runnable) or define handler and send message to it.
for example:
(new Thread(new Runnable()
{
@Override
public void run()
{
while (!Thread.interrupted())
try
{
Thread.sleep(1000);
runOnUiThread(new Runnable() // start actions in UI thread
{
@Override
public void run()
{
displayData(); // this action have to be in UI thread
}
});
}
catch (InterruptedException e)
{
// ooops
}
}
})).start(); // the while thread will start in BG thread
I came across this thread when i tried to get around the problem that you can't hide seconds in DigitalClock widget for Android. DigitalClock is deprecated now and the recommended widget to use now is TextClock. That don't work on old APIs tho... Therefore i had to write my own 24 hour clock. I don't know if this is a good implementation but it seems to work (and it is updated every second):
import java.util.Calendar;
import android.os.Handler;
import android.view.View;
import android.widget.TextView;
/**
* A 24 hour digital clock represented by a TextView
* that can be updated each second. Reads the current
* wall clock time.
*/
public class DigitalClock24h {
private TextView mClockTextView; // The textview representing the 24h clock
private boolean mShouldRun = false; // If the Runnable should keep on running
private final Handler mHandler = new Handler();
// This runnable will schedule itself to run at 1 second intervals
// if mShouldRun is set true.
private final Runnable mUpdateClock = new Runnable() {
public void run() {
if(mShouldRun) {
updateClockDisplay(); // Call the method to actually update the clock
mHandler.postDelayed(mUpdateClock, 1000); // 1 second
}
}
};
/**
* Creates a 24h Digital Clock given a TextView.
* @param clockTextView
*/
public DigitalClock24h(View clockTextView) {
mClockTextView = (TextView) clockTextView;
}
/**
* Start updating the clock every second.
* Don't forget to call stopUpdater() when you
* don't need to update the clock anymore.
*/
public void startUpdater() {
mShouldRun = true;
mHandler.post(mUpdateClock);
}
/**
* Stop updating the clock.
*/
public void stopUpdater() {
mShouldRun = false;
}
/**
* Update the textview associated with this
* digital clock.
*/
private void updateClockDisplay() {
Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY); // 24 hour
int min = c.get(Calendar.MINUTE);
String sHour;
String sMin;
if(hour < 10) {
sHour = "0" + hour;
} else sHour = "" + hour;
if(min < 10) {
sMin = "0" + min;
} else sMin = "" + min;
mClockTextView.setText(sHour + ":" + sMin);
}
}
Thankyou biegleux for pointing me in the, i suppose, correct direction!
Try this :
@Override
public void run() {
TextView tv1 = (TextView) findViewById(R.id.tv);
while(true){
showTime(tv1);
try {
Thread.sleep(1000);
}catch (Exception e) {
tv1.setText(e.toString());
}
}
}
U can also try this
There is an another way also that you can use to update the UI on specific time interval. Above two options are correct but depends on the situation you can use alternate ways to update the UI on specific time interval.
First declare one global varialbe for Handler to update the UI control from Thread, like below
Handler mHandler = new Handler(); Now create one Thread and use while loop to periodically perform the task using the sleep method of the thread.
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
Thread.sleep(10000);
mHandler.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
// Write your code here to update the UI.
}
});
} catch (Exception e) {
// TODO: handle exception
}
}
}
}).start();