我有几个TimerView
的活动。 TimerView是从textview扩展的自定义视图,用户可以单击该视图开始倒计时。
每个TimerView都拥有一个Timer。现在的问题是,当我更改屏幕的方向时,TimerViews会被重置(当前文本被删除(更改为“”)但运行时更改为bakground),但Handler线程仍在运行,更新TimerViews不再存在(?)。
在方向更改之前发送的消息仍处于活动状态。发送这些消息的线程(?)何时终止?
解决这个问题的正确方法是什么。更新从定时器到新活动的TimerViews的引用,或删除定时器并创建新的定时器?或其他一些更正确的解决方案?所有建设性的批评都表示赞赏!
我发布了我认为相关的代码部分:
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 - additional milliseconds delay between ticks
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;
}
}
答案 0 :(得分:0)
一种方法是将您的计时器移动到setRetainInstance(true)片段。这样的片段在方向改变时不会被破坏。 (顺便说一下,最好不要更新保留片段中的UI。)