2012-01-31 54 views
0

我正在尝试为Android创建一个简单的锻炼计时器。用户创建一个包含总持续时间,总休息时间等信息的WorkoutPlan,应用程序将显示一个每秒更新一次的计时器。如何用线程构建Android定时器应用程序?

很简单的开始,但我试图尽可能正确地,即关注,正确的技术,反应灵敏的用户界面,保证了计时器将被准确的分离构建应用程序等

这里有一个什么我迄今为止的简化:

WorkoutPlan,用户可以加载/不同的锻炼计划保存到计时器

public class WorkoutPlan { 
    public long duration; 
} 

TimerThread,这个类实现Runnable,它取在启动/停止构造函数中,在WorkoutPlan中显示已用时间。

public class TimerThread implements Runnable { 
    public boolean running = false; 

    private long lastStartTime; 
    private long savedTime; 
    private WorkoutPlan plan; 
    private Handler handler; 

    public TimerThread(WorkoutPlan p, Handler h) { 
     plan = p; 
     handler = h; 
    } 

    public synchronized void start() { 
     lastStartTime = System.currentTimeMillis(); 
     running = true; 
    } 

    public synchronized void pause() { 
     savedTime = elapsedTime(); 
     lastStartTime = 0; 
     running = false; 
    } 

    public synchronized long elapsedTime() { 
     if (lastStartTime == 0) { 
      return savedTime; 
     } else { 
      return savedTime + (System.currentTimeMillis() - lastStartTime); 
     } 
    } 

    public synchronized String currTimeStr() { 
     //format elapsed time in seconds to hh:mm:ss format 
     long elapsed = elapsedTime()/1000; 
     long h = elapsed/3600; 
     long m = (elapsed % 3600)/60; 
     long s = elapsed % 60; 

     if (h > 0) { 
      return String.format("%02d:%02d:%02d", h, m, s); 
     } else { 
      return String.format("%02d:%02d", m, s); 
     } 
    } 

    @Override 
    public void run() { 
     while (running) { 
      try { 
       handler.sendMessage(handler.obtainMessage()); 
       Thread.sleep(100); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

TimerView,显示经过的时间

public class TimerView extends View { 
    private final Paint mBg; 
    private final Paint mText; 
    private WorkoutPlan plan; 
    private TimerThread timer; 
    private Thread thread; 
    private Handler handler = new TimerHandler(); 

    public TimerView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     plan = new WorkoutPlan(); 

     timer = new TimerThread(plan, handler);   
     thread = new Thread(timer); 

     mBg = new Paint(); 
     mBg.setColor(getResources().getColor(R.color.bg_default)); 
     mText = new Paint(); 
     mText.setColor(getResources().getColor(R.color.text)); 
    } 

    public void start() { 
     timer.start(); 
     thread.start(); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     //draw current time and current round 
     canvas.drawText(timer.currTimeStr(), 0, 50, mText); 
    } 

    private class TimerHandler extends Handler { 

     @Override 
     public void handleMessage(Message msg) { 
      super.handleMessage(msg); 
      invalidate(); 
     }   
    } 
} 

最后,WorkoutTimer自定义视图,启动它关闭

public class WorkoutTimer extends Activity { 
    private TimerView mTimer; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.timer); 

     mTimer = (TimerView) findViewById(R.id.timer_view); 
    } 

    @Override 
    protected void onStart() { 
     super.onStart();   
     mTimer.start(); 
    } 
} 

几个问题的活动:

  1. 哪里是创建WorkoutPlan对象的最佳地点?目前它在TimerView完成。是否应该在WorkoutTimer活动中完成?如果是的话,我如何将WorkoutPlan对象传递给TimerView
  2. 该应用第一次正常工作,但是当我进入主屏幕然后第二次回到应用时崩溃。什么导致它崩溃?它是首字母吗?
  3. 当前我在新的Thread中使用了Handler。这是好的还是会TimerTask更好?哪里是开始线程的最佳地点?
  4. 我正确的把所有的线程代码放在TimerView?感觉他们应该在别的地方。
  5. 我是否正确添加同步到TimerThread中的所有方法?
  6. 我试图创建这个应用程序,因为我可以练习。请让我知道,如果我应该做的技术有所改进,或者如果我做了不正确的事情。

回答

0

如果你问的是风格,很糟糕的风格是在某些变体中使用“计时器”这个词来实现不是Timer,而是完全不同的类Handler。使用一些其他的名字。现在代码几乎是不可读的。