Napotkałem bardzo dziwną funkcję.
Kiedy próbuję uruchomić animację w głównym wątku, to się nie uruchamia. Kiedy uruchomiłem wspomnianą animację za pomocą
getView().post(new Runnable() {
@Override
public void run() {
getView().startAnimation(a);
}
});
Zaczyna się.
Wydrukowałem CurrentThread
przed rozpoczęciem animacji i oba wydruki main
.
Oczywiście czegoś mi tu brakuje, bo obaj powinni zacząć animację w głównym wątku ... Domyślam się, że gdy post dodaje zadanie do kolejki, zaczyna się w bardziej "odpowiednim czasie", ale chciałbym wiedzieć co dzieje się tutaj na większej głębokości.
EDYCJA: Pozwólcie, że wyjaśnię - moje pytanie brzmi, dlaczego uruchomienie animacji na poście powoduje jej uruchomienie, a uruchomienie animacji na głównym wątku nie.
AnimationDrawable
! ZwykłaAnimation
instancja zaczęła pomyślnie animować się przy każdej konfiguracji. WAnimationDrawable
przypadku; kiedy próbujesz rozpocząćonCreate
, nie zaczyna się, ponieważ w tym momencie nie jesteś przywiązany do widoku. Nie jest to więc problem z wątkamiAnimationDrawable
. Może to samo dotyczyAnimation
? developer.android.com/guide/topics/graphics/…Odpowiedzi:
post : post powoduje dodanie Runnable do kolejki wiadomości,
Runnable: Reprezentuje polecenie, które można wykonać. Często używany do uruchamiania kodu w innym wątku.
run () : Rozpoczyna wykonywanie aktywnej części kodu klasy. Ta metoda jest wywoływana, gdy uruchamiany jest wątek, który został utworzony za pomocą klasy implementującej Runnable.
kod :
getView().startAnimation(a);
w swoim kodzie,
post powoduje, że Runnable ( kod zostanie uruchomiony w innym wątku), aby dodać kolejkę komunikatów.
Więc startAnimation zostanie uruchomiona w nowym wątku, gdy zostanie pobrana z messageQueue
[EDYCJA 1]
Dlaczego używamy nowego wątku zamiast wątku interfejsu użytkownika (wątek główny)?
Wątek interfejsu użytkownika:
Po uruchomieniu aplikacji, wątek Ui jest tworzony automatycznie
odpowiada za wysyłanie wydarzeń do odpowiednich widżetów, w tym za rysowanie.
Jest to również wątek, z którym korzystasz z widżetów Androida
Co się stanie, jeśli użytkownik naciśnie przycisk, który będzie działał długo?
Interfejs użytkownika zawiesza się. Program może się nawet zawiesić.
Łamie regułę Androida, która nigdy nie aktualizuje interfejsu użytkownika bezpośrednio z wątku roboczego
Android oferuje kilka sposobów uzyskiwania dostępu do wątku interfejsu użytkownika z innych wątków.
Jak poniżej,
View.post (Runnable)
Treser
Po więcej informacji
http://android-developers.blogspot.com/2009/05/peling-threading.html
http://www.aviyehuda.com/blog/2010/12/20/android-multithreading-in-a-ui-environment/
źródło
Czy dzieje się to w onCreate czy onCreateView? Jeśli tak, aplikacja może nie znajdować się w stanie, w którym widok jest dołączony do okna. Wiele algorytmów opartych na metrykach widoku może nie działać, ponieważ takie elementy, jak pomiary i położenie widoku, mogły nie zostać obliczone. Animacje systemu Android zazwyczaj wymagają, aby były obsługiwane przez obliczenia w interfejsie użytkownika
View.post faktycznie kolejkuje animację w pętli komunikatów widoku, więc gdy widok zostanie dołączony do okna, wykonuje animację, zamiast wykonywać ją ręcznie.
W rzeczywistości uruchamiasz rzeczy w wątku interfejsu użytkownika, ale w innym czasie
źródło
Zajrzyj tutaj, aby uzyskać dobrą odpowiedź. view.post () działa prawie tak samo jak handler.post (). Przechodzi do głównej kolejki wątków i jest wykonywany po zakończeniu innych oczekujących zadań. Jeśli wywołasz activity.runOnUiThread () zostanie wywołany natychmiast w wątku interfejsu użytkownika.
źródło
Myślę, że problemem może być metoda cyklu życia, w której wywołujesz metodę post (). Czy robisz to w onCreate ()? jeśli tak, spójrz na to, co znalazłem w dokumentacji onResume () działania:
https://developer.android.com/reference/android/app/Activity.html#onResume ()
Tak więc, jak powiedział Joe Plante, być może widok nie jest gotowy do rozpoczęcia animacji w momencie wywołania post (), więc spróbuj przenieść go do onResume ().
PD: Właściwie, jeśli przeniesiesz kod do onResume (), myślę, że możesz usunąć wywołanie post (), ponieważ jesteś już w wątku interfejsu użytkownika, a widok powinien być gotowy do rozpoczęcia animacji.
źródło
onResume
może być wywoływane wiele razy (ekrany przechodzą w stan uśpienia, aktywność przenoszona do tyłu itp.) po tym, jak początkowo „widok jest gotowy”. Jeśli zostanie wywołana zonResume
, może być potrzebna flaga do śledzenia pogody, której animacja została już uruchomiona, aby uniknąć (ponownego) uruchomienia się wiele razy.