Jaki jest zalecany sposób aktualizacji android ui z ciągłego wątku tła?

Czytałem wystarczająco dobrze na ten temat, aby się dobrze i dokładnie pomylić. Robię aplikację do śledzenia treningu, taką jak RunKeeper, która śledzi, jak długo i jak długo użytkownik mówił, działa. Jestem w trakcie programowania głównego interfejsu tego „treningu”, który pokazuje układ przypominający stoper, który zawiera zarówno zegar pokazujący czas, który jest aktualizowany co sekundę, jak i licznik pokazujący, jak daleko on dotąd biegnie.

Moim problemem jest aktualizacja interfejsu. Mam klasę stoperów śledzącą czas i obliczam odległość na podstawie lokalizacji GPS, ale nie mogę znaleźć zalecanego sposobu uruchamiania ciągłego wątku w tle, który aktualizuje interfejs użytkownika w ustalonym czasie .

O ile mogłem powiedzieć, powinienem albo zaimplementować interfejs Handler.Callback w klasie aktywności, albo mieć osobny obiekt Callback wraz z Wątkiem, ale jestem pewien, że nie mogę uzyskać wszystko do współpracy. Muszę zaktualizować pokazany czas, który otrzymuję z mojej klasy stopera (obliczanie czasu rozpoczęcia / zakończenia prostego, nic związanego z wątkiem) oraz odległość obliczoną na podstawie lokalizacji otrzymanych w onLocationChanged ().

Oto uproszczona wersja mojego kodu działania:

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){/* ...*/}
}

Zgodnie z większością odpowiedzi, które przeczytałem tutaj, powinienem użyć obiektu Handler rozszerzającego metodę handleMessage, ale obecnie (przynajmniej zgodnie z ostrzeżeniem w Lint) musisz uczynić takie obiekty statycznymi, aby uniknąć wycieków pamięci. To jednak sprawia, że ​​nieco dziwnie jest uzyskiwać bezpośredni dostęp i zmieniać inne prywatne obiekty w klasie aktywności z poziomu Handlera. Przypuszczam, że możesz rozwiązać ten problem, tworząc obiekty, których potrzebujesz, aby wpływać na parametry w klasie rozszerzającej Handler, ale nie wiem, wydaje mi się, że to trochę „hack” (klasa zagnieżdżona w 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;
        }           
    }

Czy więc ktoś mógłby wyjaśnić „standardowy” sposób aktualizacji interfejsu użytkownika z ciągłego wątku w tle? Och, i przepraszam za długie pytanie, chciałem być dokładny.

questionAnswers(2)

yourAnswerToTheQuestion