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.