我已经阅读了很多关于这个主题的内容,以获得良好和彻底的困惑。我正在做一个运动追踪器应用程序,如RunKeeper,它可以追踪用户说话和运行的时间长度。我正在编程这个“锻炼”的主界面,它显示了一个类似秒表的布局,包括一个显示每秒更新时间的计时器,以及一个计数器,显示他到目前为止的运行距离。
我的问题是更新界面。我有一个秒表类跟踪时间,我根据gps位置计算距离,但我找不到在后台运行连续线程的建议方法,以固定的时间速率更新ui
据我所知,我应该在activity类中实现Handler.Callback接口,或者在Thread中有一个单独的Callback对象,但是我有点不知所措。如何让所有人一起工作。我都需要更新从秒表课程中得到的时间(简单的开始/停止时间计算,没有线程相关),以及根据onLocationChanged()中收到的位置计算的距离。
这是我的活动代码的精简版:
public class WorkoutActivity extends Activity implements OnClickListener, LocationListener
{
private LocationManager locManager;
private boolean workoutStarted = false;
// The TextViews to update
private TextView timeLabel;
private TextView distanceLabel;
private Stopwatch stopwatch;
@Override
public void onCreate(Bundle savedInstanceState)
{
/*
... Interface initialisation
*/
stopwatch = new Stopwatch();
}
private void startWorkout() {/* ...*/}
private void stopWorkout() {/* ...*/}
private void pauseWorkout() {/* ...*/}
private void resumeWorkout(){/* ...*/}
public void onClick(View v) {/* ...*/}
public void onLocationChanged(Location location){/* ...*/}
}
根据我在这里阅读的大多数答案我应该使用扩展handleMessage方法的Handler对象,但是现在(至少根据Lint中的警告)你必须使这些对象静态以避免内存泄漏。但是,这使得从Handler中直接访问和更改活动类中的其他私有对象有点奇怪。我想你可以通过在扩展Handler的类中创建需要影响参数的对象来解决这个问题,但我不知道,这感觉就像是一个“hack”(WorkoutActivity中的嵌套类):
static class TimeHandler extends Handler
{
static final int MSG_START_TIMER = 1;
static final int MSG_UPDATE_TIMER = 2;
static final int MSG_STOP_TIMER = 3;
private static final int REFRESH_RATE = 1000;
private Stopwatch stopwatch;
private TextView timeLabel;
public TimeHandler(Stopwatch stopwatch, TextView label)
{
this.stopwatch = stopwatch;
this.timeLabel = label;
}
@Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
switch(msg.what)
{
case MSG_START_TIMER:
stopwatch.start();
this.sendEmptyMessage(MSG_UPDATE_TIMER);
break;
case MSG_UPDATE_TIMER:
timeLabel.setText(stopwatch.getElapsedTimeString());
this.sendEmptyMessageDelayed(MSG_UPDATE_TIMER, REFRESH_RATE);
break;
case MSG_STOP_TIMER:
this.removeMessages(MSG_UPDATE_TIMER);
stopwatch.stop();
timeLabel.setText(stopwatch.getElapsedTimeString());
break;
}
}
那么,任何人都可以解释从连续后台线程更新UI的“标准”方式吗?哦,抱歉这个长期的问题,只是想彻底。
答案 0 :(得分:3)
定义Runnable
:
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
mTextViewOne.setText("10 miles!");
mTextViewTwo.setText("40 minutes!");
}
};
在你的连续线程中:
runOnUiThread(mRunnable);
答案 1 :(得分:-1)
在AsyncTask中使用以下线程...我希望这对你有用....
Handler mHandler;
private final Runnable mRunnable = new Runnable() {
public void run() {
Call your AsyncTask Class;;;;
mHandler.postDelayed(mRunnable, 1000);
}
};