Jestem nowy w Androidzie i próbuję użyć wątku interfejsu użytkownika, więc napisałem proste ćwiczenie testowe. Ale wydaje mi się, że coś źle zrozumiałem, bo po kliknięciu przycisku - aplikacja już nie reaguje
public class TestActivity extends Activity {
Button btn;
int i = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
runThread();
}
});
}
private void runThread(){
runOnUiThread (new Thread(new Runnable() {
public void run() {
while(i++ < 1000){
btn.setText("#"+i);
try {
Thread.sleep(300);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}));
}
}
Po prostu opakuj go jako funkcję, a następnie wywołaj tę funkcję z wątku w tle.
źródło
final
)Masz to od tyłu do przodu. Kliknięcie przycisku powoduje wywołanie funkcji
runOnUiThread()
, ale nie jest to potrzebne, ponieważ moduł obsługi kliknięcia jest już uruchomiony w wątku interfejsu użytkownika. Następnie twój kodrunOnUiThread()
uruchamia nowy wątek w tle, w którym próbujesz wykonać operacje interfejsu użytkownika, które następnie kończą się niepowodzeniem.Zamiast tego po prostu uruchom wątek w tle bezpośrednio z modułu obsługi kliknięć. Następnie zawiń wywołania do
btn.setText()
wewnątrz wywołania dorunOnUiThread()
.źródło
runOnUiThread()
jest konieczne, ale powinno być nieszkodliwe. Dokument Javadoc dla tej metody mówi „Uruchamia określoną akcję w wątku interfejsu użytkownika. Jeśli bieżący wątek jest wątkiem interfejsu użytkownika, akcja jest wykonywana natychmiast. Jeśli bieżący wątek nie jest wątkiem interfejsu użytkownika, akcja jest wysyłana do kolejki zdarzeń wątku interfejsu użytkownika ”.źródło
Istnieje kilka technik wykorzystujących runOnUiThread (), zobaczmy wszystko
To jest mój główny wątek (wątek UI) o nazwie AndroidBasicThreadActivity i mam zamiar zaktualizować go z wątku roboczego na różne sposoby -
1.) Przekazując instancję Activity jako argument w wątku roboczym
2.) Używając metody posta View (Runnable runnable) w wątku roboczym
3.) Używając klasy Handler z pakietu android.os Jeśli nie mamy kontekstu (this / getApplicationContext ()) lub instancji Activity (AndroidBasicThreadActivity.this) to musimy użyć klasy Handler jak poniżej -
źródło
Jeśli używasz we fragmencie, po prostu napisz
źródło
twój to:
źródło
Używamy wątku roboczego, aby aplikacje działały płynniej i unikały błędów ANR. Może być konieczne zaktualizowanie interfejsu użytkownika po ciężkim procesie roboczym Tread. Interfejs użytkownika można aktualizować tylko z poziomu wątku interfejsu użytkownika. W takich przypadkach używamy Handler lub runOnUiThread, oba mają Runnable run metodę, która jest wykonywana w UI Thread. Metoda onClick działa w wątku interfejsu użytkownika, więc nie trzeba tutaj używać runOnUiThread.
Korzystanie z Kotlin
Podczas aktywności
Od fragmentu,
Korzystanie z języka Java ,
źródło
Możesz użyć z tego przykładu:
W poniższym przykładzie zamierzamy użyć tej funkcji do opublikowania wyniku wyszukiwania synonimów, które zostało przetworzone przez wątek w tle.
Aby osiągnąć cel podczas wywołania zwrotnego działania OnCreate, skonfigurujemy onClickListener, aby uruchamiał searchTask na utworzonym wątku.
Kiedy użytkownik kliknie przycisk Wyszukaj, utworzymy anonimową klasę Runnable, która wyszukuje słowo wpisane w R.id.wordEt EditText i uruchamia wątek w celu wykonania Runnable.
Po zakończeniu wyszukiwania utworzymy wystąpienie Runnable SetSynonymResult, aby opublikować wynik z powrotem w synonimie TextView w wątku interfejsu użytkownika.
Ta technika czasami nie jest najwygodniejsza, zwłaszcza gdy nie mamy dostępu do instancji Activity; Dlatego w następnych rozdziałach omówimy prostsze i czystsze techniki aktualizacji interfejsu użytkownika z zadania obliczeniowego w tle.
Źródło :
asynchroniczne programowanie na Androida Helder Vasconcelos
źródło
Oto jak go używam:
źródło
źródło
Spróbuj tego:
getActivity().runOnUiThread(new Runnable...
To dlatego, że:
1) niejawne this w wywołaniu runOnUiThread odnosi się do AsyncTask , a nie do twojego fragmentu.
2) Fragment nie ma runOnUiThread.
Jednak Activity tak.
Zauważ, że Activity po prostu wykonuje Runnable, jeśli jesteś już w głównym wątku, w przeciwnym razie używa Handler. Możesz zaimplementować Handler w swoim fragmencie, jeśli nie chcesz się martwić o kontekst tego, jest to w rzeczywistości bardzo proste:
// Instancja klasy
// gdziekolwiek w kodzie
// ^ to będzie zawsze uruchamiane w następnej pętli uruchamiania w głównym wątku.
źródło