PC Java プログラムを Android プラットフォームに移植しようとしています。PC アプリケーションは Swing.Timer を使用して、1 秒ごとに更新をトリガーします。関連付けられたリスナーは、呼び出されると、データベースから新しいデータを取得し、Graphics2D を使用して画面を更新/再描画します。Android のキャンバスを使用して、PC アプリケーションで行うのと同じことを描画する方法を学びました。今、私は Android で同等のタイマーを使用する方法を学ぼうとしています。残念ながら、Android プラットフォームでは物事は単純ではないようです。Timer、Handler、AlarmManager、および AsyncTask があります。AsyncTasks と AlarmManagers は、1 回限りの (負荷の高い?) タスクに適しているように思われます (正しい? 間違っている?)。以下のコードで使用されているアプローチをウェブ上のどこかで見つけて、試してみました。やりたいことができるように思えますが、停止ボタンをクリックするたびに GUI がハングします。なぜそれがそうするのか誰にも分かりますか?
百万ビルに感謝
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
dateFormat = new SimpleDateFormat(dateFormatString);
mHandler = new Handler();
mUpdateTimeTask = new MyRunnable();
Button button = (Button) findViewById(R.id.start_button);
button.setOnClickListener(new MyStartListener());
button = (Button) findViewById(R.id.stop_button);
button.setOnClickListener(new MyStopListener());
}
class MyStartListener implements View.OnClickListener {
public void onClick(View v) {
if (startUptimeMillis == 0L) {
startUptimeMillis = SystemClock.uptimeMillis();
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 100);
}
}
};
class MyStopListener implements View.OnClickListener {
public void onClick(View v) {
mHandler.removeCallbacks(mUpdateTimeTask);
}
};
class MyRunnable implements Runnable {
public void run() {
final long start = startUptimeMillis;
long millis = SystemClock.uptimeMillis() - start;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
TextView tv = (TextView) findViewById(R.id.time_textView);
tv.setText(dateFormat.format(calendar.getTime()));
mHandler.postAtTime(this, (((minutes * 60) + seconds + 1) * 1000));
}
};
編集:問題は、 postAtTime が、私の例で使用している遅延ではなく、開始する絶対時間を必要とすることです。(ここでpostAtTimeを参照してください)それで、上記のすべてのタイミングコードを以下に置き換えました。
long millis = SystemClock.uptimeMillis();
mHandler.postAtTime(this, millis+1000);