Was ist der empfohlene Weg, um Android-UI von einem-Continuous- Hintergrund-Thread zu aktualisieren?

Ich habe zu diesem Thema gut genug gelesen, um mich zu erholen und gründlich zu verwirren. Ich mache eine Workout-Tracker-App wie RunKeeper, die protokolliert, wie lange und wie weit der Benutzer ausgeführt hat. Ich bin gerade dabei, die Hauptoberfläche dieses "Trainings" zu programmieren, die ein Stoppuhr-ähnliches Layout zeigt, das sowohl einen Timer enthält, der die sekündlich aktualisierte Zeit anzeigt, als auch einen Zähler, der anzeigt, wie weit er bisher gelaufen ist.

Mein Problem aktualisiert die Schnittstelle. Ich habe eine Stoppuhr-Klasse, die die Zeit verfolgt, und ich berechne die Entfernung basierend auf den GPS-Standorten. Ich bin jedoch ratlos, die empfohlene Methode zu finden, um einen fortlaufenden Thread im Hintergrund auszuführen, der die Benutzeroberfläche mit einer festen Zeitrate aktualisiert .

Soweit ich es beurteilen konnte, sollte ich entweder die Handler.Callback-Schnittstelle in der Aktivitätsklasse implementieren oder ein separates Callback-Objekt zusammen mit einem Thread haben, aber ich weiß nicht, wie ich es bekommen soll es ist alles zusammen zu arbeiten. Ich muss sowohl die angezeigte Zeit, die ich von meiner Stoppuhrklasse erhalte (einfache Start- / Stoppzeitberechnung, nichts Thread-bezogen), als auch die Entfernung, die basierend auf den in onLocationChanged () empfangenen Positionen berechnet wurde, aktualisieren.

Hier ist eine abgespeckte Version meines Aktivitätscodes:

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

Nach den meisten Antworten, die ich hier gelesen habe, sollte ich ein Handler-Objekt verwenden, das die handleMessage-Methode erweitert, aber heutzutage (zumindest gemäß der Warnung in Lint) müssen Sie solche Objekte statisch machen, um Speicherverluste zu vermeiden. Das macht es jedoch etwas seltsam, direkt aus dem Handler auf die anderen privaten Objekte in der Aktivitätsklasse zuzugreifen und diese zu ändern. Ich nehme an, Sie könnten dies lösen, indem Sie die Objekte erstellen, die Sie benötigen, um Parameter in einem Klassenerweiterungs-Handler zu beeinflussen, aber ich weiß nicht, es fühlt sich wie ein kleiner "Hack" an (verschachtelte Klasse in 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;
        }           
    }

Kann mir jemand erklären, wie die Benutzeroberfläche standardmäßig über einen fortlaufenden Hintergrund-Thread aktualisiert wird? Oh, und Entschuldigung für die lange Frage, ich wollte nur gründlich sein.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage