2010-12-13 13 views
7

mam to:Jak odświeżyć tekst podczas pętli w systemie Android?

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 


    TextView debugView = (TextView)findViewById(R.id.debugView); 

    for(int i=0;i<100;i++) { 
     try { 
      Thread.sleep(100); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     debugView.setText(Integer.toString(i)); 
    } 

} 

Spodziewam się go zaktualizować tekst zobaczyć za każdym razem przez pętlę więc chciałbym dostać: 1, 2, 3, ... 99

Zamiast aplikacja nie robi nic przez 10 sekund, a następnie wyjścia: 99

Zgaduję, że potrzebuję TextView do odświeżenia podczas pętli. Jestem nowy w rozwoju Androida. Czy ktoś może mi powiedzieć, czy jest to najlepszy sposób, aby to osiągnąć?

Moim ostatecznym celem jest umożliwienie przetwarzania próbek audio w celu zbudowania tunera gitarowego. Próbuję po prostu zweryfikować wizualnie, że aplikacja reaguje na dźwięk zewnętrzny i chcę zaktualizować TextView, aby to pokazać. Proszę poinformować, czy istnieje lepszy sposób na zrobienie tego.

+2

Nic nie zostanie wyświetlony aż onCreate zwrotów. – Falmarri

Odpowiedz

6

Twój problem polega na tym, że uruchamiasz pętlę onCreate(). Dzieje się to w wątku interfejsu użytkownika przed wyświetleniem aktywności.

Spójrz na Activity lifecycle w systemie Android. Pokazuje onCreate jest tylko jednym z etapów tworzenia działania. To, co chcesz zrobić, to uruchomić pętlę w wątku w tle i opublikować powiadomienie, aby zaktualizować widok TextView do wątku interfejsu użytkownika przy użyciu polecenia runOnUiThread. Odpowiedź Christiana pokazuje, jak to zrobić.

Jednak ostatecznym celem jest aktualizacja TextView w oparciu o dane wejściowe użytkownika (audio w twoim przypadku), nie będziesz musiał przeskakiwać przez wszystkie te pętle, aby działało. Jedyną ważną rzeczą jest to, że publikujesz swoje połączenia, aby zaktualizować interfejs użytkownika w wątku interfejsu użytkownika, w przeciwnym razie dostaniesz wyjątki.

+0

Z tego samego problemu wystąpił. –

8

Lepiej użyć Timer:

new Timer().schedule(new TimerTask() { 

     @Override 
     public void run() { 
      runOnUiThread(new Runnable() { 
       public void run() { 
        debugView.setText("something"); 
       } 
      }); 
     } 
    }, 0, 100); 

Zauważ, że używam runOnUiThread ponieważ nie można zmodyfikować widok z innego wątku, który nie jest najważniejszy.

+0

Dla mojego rzeczywistego przypadku użycia muszę być w pętli, ponieważ mam pobieranie próbek audio. Mogę już wyświetlić wynik za pomocą Log.i(). Po prostu szukam prostego sposobu wyświetlania tych informacji na urządzeniu z Androidem. Nie obchodzi mnie, jaki typ interfejsu jest niezbędny, a nawet czy muszę narysować coś za pomocą jednego z interfejsów graficznych (jeśli jest szybszy niż renderowanie w TextView).Byłbym wdzięczny, gdybyś miał jakąkolwiek poradę, jak to zrobić, gdy jesteś w pętli. Dzięki. – chaimp

+0

Po prostu notatka, Thread.sleep (100) był tylko w celu przetestowania tego, więc nie idzie tak szybko, że tęsknię. Właściwie nie chcę, żeby była przerwa 100 milisekund. Najlepiej byłoby, gdyby wszystko poszło tak szybko, jak to możliwe. – chaimp

+1

W takim przypadku użyj AsyncTask. Istnieje wiele przykładów tutaj w stackoverflow lub w Google. – Cristian

22

miałem ten sam problem i rozwiązać go za pomocą uchwytu:

public class myClass extends Activity{ 

private Handler mHandler; 
private TextView text; 
private int i; 

    @Override 
     public void onCreate(Bundle savedInstanceState) { 
      text = (TextView) findViewById(R.id.textView01); 
      i = 0; 
      mHandler = new Handler(); 
      mHandler.post(mUpdate); 

     } 

private Runnable mUpdate = new Runnable() { 
    public void run() { 

     text.setText("My number: " + i); 
     i++; 
     mHandler.postDelayed(this, 1000); 

    } 
};} 

Z mHandler.post(mUpdate) zadzwonić mUpdate który jest Runnable, który działa w innym wątku, który można aktualizować UI. Wewnątrz metody run(), zamiast tworzyć pętlę for, która miałby taki sam problem jak twój, ustaw żądany tekst ze zmienną pomocniczą, zwiększ go i wywołaj mHandler.postDelayed(this,updateTime). W tym momencie widok jest aktualizowany, a tekst jest wyświetlany na ekranie, a po określonym czasie (w milisekundach) funkcja Runnable mUpdate zostanie ponownie wywołana i ustawi tekst na następny numer, a więc na.

Mam nadzieję, że to pomaga.

1

Zamiast Handler jest to możliwe, aby bezpośrednio przejść Runnable aby z postDelayed:

public class myClass extends Activity { 

    private TextView text; 
    private int i; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     text = (TextView) findViewById(R.id.textView01); 
     text.postDelayed(mUpdate, 0); 

    } 

    private Runnable mUpdate = new Runnable() { 
     public void run() { 

      text.setText("My number: " + i); 
      i++; 
      text.postDelayed(this, 1000); 

     } 
    }; 
} 
Powiązane problemy