私は数人で活動していTimerView
ます。TimerView は、ユーザーがクリックしてカウントダウンを開始できる textview から拡張されたカスタム ビューです。
各 TimerView は Timer を所有します。現在の問題は、画面の向きを変更すると TimerViews がリセットされることです (現在のテキストは削除されます ("" に変更されます) が、bakground へのランタイムの変更は保持されます) が、ハンドラー スレッドは引き続き実行され、更新されます。もう存在しない (?) TimerViews。
向きが変わる直前に送信されたメッセージはまだアクティブです。これらのメッセージを送信するスレッド (?) はいつ終了しますか?
これを解決する正しい方法は何ですか。タイマーから新しいアクティビティの TimerView への参照を更新するか、タイマーを削除して新しいタイマーを作成しますか? または、他のより正しい解決策はありますか?すべての建設的な批判を歓迎します!
関連すると思われるコードの部分を投稿しています。
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;
}
}