2012-04-16 30 views
1

我有一个Android应用程序,用户按下开始按钮并启动一些收集数据的功能。我有一个自定义的EditText,它显示了所有这个过程所花费的时间,并且每秒更新一次,直到用户按下停止。我实现了这个使用的AsyncTask这样如下:Android - 实现自定义计时器/时钟

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); 

       }   
     } 

它似乎正常工作在第一,但现在我看到的是,如果应用程序处于空闲状态,失焦的定时器可能并不总是算好。我的意思是说,我离开例如该设备15分钟,然后看到在我的“时钟”只有5通过。由于观点重新聚焦,一切似乎都能正常工作。

首先为什么会发生这种情况?不应该总是在后台执行AsyncTask?有没有其他更好的方法可以用来实现?

感谢大家提前!

编辑:感谢TrackRuler我实现这样的:

私人Runnable的定时器=新的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); 
        }      
      }; 

从我主要的代码我把它从一个处理程序: TimerHandler.post (定时器);

它的工作原理现在..我只是想知道是否有在更新了Runnable(?)里面的观点有问题

回答

1

基本上在同时完成的AsyncTask将结束。它不会等待你的睡眠呼叫。

您可能需要实现Runnable接口,并在'Runnable'中执行您需要的操作。

+0

非常感谢!我试图用一个处理程序和一个Runnable来完成它。像TimerHandler.post(定时器);并在里面的定时器runnable我有所有的代码类似于AsyncTask加TimerHandler.postAtTime(this,current + 1000;) 这是你的意思吗?如果我更新计时器内的视图也没有问题 – george 2012-04-16 10:26:10

+0

@乔治这是类似于我的意思上面。如何适合你? 如果你不是这个意思,在外面创建一个'Runnable',并从'doInBackground()'调用'Runnable',它会给你准确的结果, postExcute()'。 – 2012-04-16 11:02:49

+0

它现在可以工作,但我不知道更新runnable中的视图是否好,我完全删除了AsyncTask(请参阅Edit),所以我不明白你的意见是什么意思“从doInBackground()调用Runnable”) – george 2012-04-16 11:12:05

1

我所实行的是这样的,

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........ 
       }   
     } 

,我认为这是对数据库更新更好。但对于UI更新,请检查它是否影响UI线程。现在,这对你的工作是正确的,只是等待主人回答这个问题。以及我会尽力帮助你...

+0

非常感谢!我会尝试一些事情,看看最有效的方法 – george 2012-04-16 12:07:51