implement a custom timer/clock
I have an android app where user presses a start button and some function of collecting data is started. I have a custom EditText that shows the time that all this process has taken and is updated every second till user presses stop. I implemented this using an AsyncTask like this below:
protected class RecTimer extends AsyncTask<Context, Integer, String>
{
@Override
protected String doInBackground( Context... params )
{
int sec=00;
int min=00;
int hours=00;
timerdata=timer.split(":");
hours=Integer.parseInt(timerdata[0]);
min=Integer.parseInt(timerdata[1]);
sec=Integer.parseInt(timerdata[2]);
while(Recording==true)
{
try{
Thread.sleep( 1000 );
publishProgress( sec , min , hours );
sec++;
if(sec==60){
min++;
sec=0;
if(min==60){
hours++;
min=0;
}
}
} catch( Exception e ){
Log.i("makemachine", e.getMessage() );
}
}
return "COMPLETE!";
}
@Override
protected void onPreExecute()
{
Log.i( "makemachine", "onPreExecute()" );
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
//Log.i( "makemachine", "onProgressUpdate(): " + String.valueOf( values[0] ) );
String format = String.format("%%0%dd", 2);
String Sec = String.format(format, values[0]);
String Min = String.format(format, values[1]);
String Hours = String.format(format, values[2]);
((EditText) findViewById(R.id.duration1)).setText(Hours + ":"+ Min + ":" + Sec);
}
@Override
protected void onPostExecute( String result )
{
super.onPostExecute(result);
Log.i( "makemachine", "onPostExecute(): " + result );
}
}
It seemed to work fine at first, but now I see that if the app is idle and out of focus the timer may not always count well. I mean that I leave for example the device for 15 minutes and then see that in my “clock” only 5 have passed. Since the view is back on focus everything seems to work normally again.
First of all why does this happen? Shouldn't the AsyncTask be always executed in background? Is there some other better approach I should use to implement this?
Thanks to everybody in advance!
EDIT: Thanks to TrackRuler I implemented it like this:
private Runnable Timer = new Runnable() {
public void run() {
long current = SystemClock.uptimeMillis();
String format = String.format("%%0%dd", 2);
timerdata=timer.split(":");
sec++;
if(sec==60){
min++;
sec=0;
if(min==60){
hours++;
min=0;
}
}
String Sec = String.format(format, sec);
String Min = String.format(format, min);
String Hours = String.format(format, hours);
((EditText) findViewById(R.id.duration1)).setText(Hours + ":"+ Min + ":" + Sec);
TimerHandler.postAtTime(this,
current + 1000);
}
};
From my main code I call it from a handler: TimerHandler.post(Timer);
It works by now.. I just want to know if there is a problem in updating the view inside the Runnable(?)
Basically the AsyncTask will be ended when the while completed. It wont wait for your sleep calls.
You may have to implement the Runnable
interface and do that what u needs inside the 'Runnable'.
What i have implemented is like this,
protected class RecTimer extends AsyncTask<Context, Integer, String>
{
@Override
protected String doInBackground( Context... params )
{
//ToDO........
new Thread(new Timer(CurrentActivity.this)).start();
//ToDO........
}
@Override
protected void onPreExecute()
{
//ToDO........
}
@Override
protected void onProgressUpdate(Integer... values)
{
//ToDO........
}
@Override
protected void onPostExecute( String result )
{
//ToDO........
}
}
And i think this is better for DB updates. But for the UI updates, Check whether it is affecting the UI thread or not. Now this working for you right, just wait for a master to answer this question. As well as I'll try to help you out...
链接地址: http://www.djcxy.com/p/13002.html上一篇: 如何在Android中更改TextView的fontFamily
下一篇: 实现一个定制的定时器/时钟