ストップウォッチのようなコードを含むアクティビティを作成しました。本当に正確である必要があります。問題は、リアルタイムで徐々に遅れることです。問題のコードの小さな例を次に示します。
import java.util.Date;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
public static final int TIME_STEP = 500; // milliseconds between updates
private Handler mHandler = new Handler();
private long mTimeElapsed = 0;
private Runnable mUpdateTimeTask = new Runnable()
{
private long mOldTime = 0; // previous real time (ms) that run() was called
public void run()
{
mHandler.postDelayed(mUpdateTimeTask, TIME_STEP);
long currentTime = new Date().getTime();
long realDelay = currentTime - mOldTime; // the actual delay between successive calls to run()
if (mOldTime != 0)
mTimeElapsed += realDelay;
Log.d(this.toString(), "time elapsed = " + mTimeElapsed/1000);
// some slow operations here...
mOldTime = currentTime;
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTimeElapsed = 0;
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 0);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
問題を説明すると、(logcat タイムスタンプによると) 8:23 の間アプリを実行した後、mTimeElapsed は 456 秒、つまり 7:36 になります。
run() の連続呼び出し間の遅延は getTime() を使用して計算されるため (つまり、実際の遅延が TIME_STEP になるとは想定していません)、なぜこれが同期から外れるのか理解できませんか?
エミュレーターと実際のデバイスでこれをテストしましたが、同じ結果が得られました。
編集:時間の結果は投稿されたコード、つまり「遅い操作」がない場合でも、ここで作業を行うと遅延が悪化するようです
同じことを達成するための代替方法を提供しないでください。私は代替案自体に反対しているわけではありません。このコードが期待どおりに機能しない理由を知りたいだけです。ありがとう!