0

我在这个主题上读得足够好,以至于完全困惑。我正在做一个锻炼跟踪器应用程序,例如 RunKeeper,它跟踪用户说跑步的时间和距离。我正在编写这个“锻炼”的主界面,它显示了一个类似秒表的布局,其中包括一个显示每秒更新时间的计时器和一个显示他到目前为止跑了多远的计数器。

我的问题是更新界面。我有一个秒表类来跟踪时间,并且我根据 gps 位置计算距离,但是我找不到推荐的方法来在后台运行连续线程,以固定的时间速率更新 ui .

据我所知,我应该要么在活动类中实现 Handler.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 的“标准”方式吗?哦,很抱歉这个长问题,只是想彻底。

4

2 回答 2

3

使用runOnUiThread().

定义一个Runnable

private Runnable mRunnable = new Runnable() {
    @Override
    public void run() {
        mTextViewOne.setText("10 miles!");
        mTextViewTwo.setText("40 minutes!");
    }
};

在你的连续线程内:

runOnUiThread(mRunnable);
于 2012-08-20T13:06:23.637 回答
-1

在 AsyncTask 中使用以下线程......我希望这对你有用......

   Handler mHandler;
private final Runnable mRunnable = new Runnable() {

        public void run() {
            Call your AsyncTask Class;;;;
            mHandler.postDelayed(mRunnable, 1000);
        }

    };
于 2012-08-20T13:09:04.083 回答