我正在尝试为Android创建一个简单的锻炼计时器。用户创建包含总持续时间,总休息时间等信息的WorkoutPlan
,应用程序将显示每秒更新的计时器。
开始时非常简单,但我正在尝试尽可能正确地构建应用程序,即分离关注点,正确的技术,响应式UI,确保计时器准确等等。
这是我到目前为止的简化:
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();
}
}
几个问题:
WorkoutPlan
对象的最佳位置?目前已在TimerView
完成。是否应该在WorkoutTimer
活动中完成?如果是,我如何将WorkoutPlan
对象传递给TimerView
?Handler
中使用了Thread
。这样可以或TimerTask
会更好吗?哪个是开始该主题的最佳位置?TimerView
?感觉他们应该在别的地方。TimerThread
?答案 0 :(得分:0)
如果你问的是风格,那么非常糟糕的风格就是在某些变体中使用“timer”这个词来实现不是Timer,而是完全不同的类,Handler。使用其他名称。现在代码几乎不可读。