我正在尝试将PC Java程序移植到Android平台。 PC应用程序使用Swing.Timer每秒触发更新。在被调用时,关联的侦听器从数据库获取新数据,然后使用Graphics2D更新/重绘屏幕。我已经学会了如何使用Android的Canvas来绘制与PC应用程序相同的东西。现在我正在尝试学习如何在Android中使用等效的Timer。不幸的是,在Android平台上,事情似乎并不那么简单。有计时器,处理程序,AlarmManagers和AsyncTasks。似乎AsyncTasks和AlarmManagers更适合一次(重任?)任务(对吗?错误?)关于定时器和处理程序,我看过很多帖子说不使用Timer,而是使用Handler。我在Web上的某处找到了下面代码中使用的方法并尝试了它。它似乎应该做我想要的,但每当我点击停止按钮时它会挂起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需要一个绝对时间来启动,而不是我的例子正在使用的延迟。 (See postAtTime here) 所以我用下面的代码替换了上面的所有时序代码,它做了我想要的!!:
long millis = SystemClock.uptimeMillis();
mHandler.postAtTime(this, millis+1000);
答案 0 :(得分:1)
我不知道这会如何挂起你的应用程序,除非你的意思是开始按钮不再起作用...也许你想将它添加到你的停止监听器:
public void onClick(View v) {
startUptimeMillis = 0l; // Reset startUptimeMillis
mHandler.removeCallbacks(mUpdateTimeTask);
}
就Timers,AsyncsTask等而言......你是对的,在不久的将来在Android中编程事件的最好方法是使用Handler和Runnable。 AlarmManagers不适用于动画中的快速回调,AsyncTasks更适合重载计算。
我想提供一个更简单的更新Runnable:
class MyRunnable implements Runnable {
public void run() {
// You should make this a class variable and initialize it in onCreate(),
// there is no need to search for the same View every second.
TextView tv = (TextView) findViewById(R.id.time_textView);
final long now = System.currentTimeMillis();
tv.setText(dateFormat.format(now));
mHandler.postAtTime(this, 1000 - (now - start) % 1000); // Accounts for millisecond offsets over time
// mHandler.postDelayed(this, 1000); // Effected by minute offsets
}
};