我有几个TimerView
s 的活动。TimerView 是从 textview 扩展而来的自定义视图,用户可以单击它来开始倒计时。
每个 TimerView 都拥有一个 Timer。现在的问题是,当我更改屏幕的方向时,TimerViews 被重置(当前文本被删除(更改为“”)但运行时对 bakground 的更改被保留),但处理程序线程仍在运行,正在更新TimerViews 不再存在(?)。
在方向改变之前发送的消息仍然有效。发送这些消息的线程(?)何时终止?
解决这个问题的正确方法是什么。将 Timers 的引用更新到新活动的 TimerViews,或者删除 Timers 并创建新的?还是其他更正确的解决方案?感谢所有建设性的批评!
我发布了我认为相关的代码部分:
TimerView 扩展了 TextView
public class TimerView extends TextView implements View.OnClickListener
{
private SecondTimer secondTimer;
public TimerView(Context context, AttributeSet attrs)
{
super(context, attrs);
secondTimer = new SecondTimer(120, this);
setOnClickListener(this);
}
@Override
public void onClick(View view)
{
if(!secondTimer.isRunning())
secondTimer.start();
}
}
秒计时器
// 这里派生自 Sam 的计时器android CountDownTimer - 滴答之间的额外毫秒延迟
public abstract class SecondTimer
{
private final long millisInFuture;
private final long countdownInterval;
private long stopTimeInFuture;
private long nextTime;
private boolean running;
// Reference to TimerView that this timer should update
TimerView timerView;
// Constructor
public SecondTimer(long secondsInFuture, TimerView timerView)
{
this.millisInFuture = secondsInFuture * 1000;
this.countdownInterval = 1000;
this.timerView = timerView;
}
private static final int MSG = 1;
public synchronized SecondTimer start() //Synch needed?
{
running = true;
if(millisInFuture <= 0)
{
onFinish();
return this;
}
nextTime = SystemClock.uptimeMillis();
stopTimeInFuture = nextTime + millisInFuture;
// Message for start tick
handler.sendMessage(handler.obtainMessage(MSG));
return this;
}
// Takes care of counting down
private Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
synchronized(SecondTimer.this)
{
final long millisLeft = stopTimeInFuture - SystemClock.uptimeMillis();
if(millisLeft <= 0)
{
onFinish();
}
else
{
onTick(millisLeft);
long currentTime = SystemClock.uptimeMillis();
do
{
nextTime += countdownInterval;
} while(currentTime > nextTime);
// Make sure this interval doesn't exceed the stop time
if(nextTime < stopTimeInFuture)
sendMessageAtTime(obtainMessage(MSG), nextTime);
else
sendMessageAtTime(obtainMessage(MSG), stopTimeInFuture);
}
}
}
};
private void onTick(long millisUntilFinished)
{
long secondsUntilFinished = (millisUntilFinished + 500) / 1000;
long minutesUntilFinished = secondsUntilFinished / 60;
secondsUntilFinished %= 60;
timerView.setText(String.format("%01d", minutesUntilFinished)
+ ":"
+ String.format("%02d", secondsUntilFinished));
}
private void onFinish()
{
running = false;
}
public boolean isRunning()
{
return running;
}
}