Czy jesteś absolutnie pewien, że to IntentService
? to jest główna przyczyna zawieszania się interfejsu użytkownika? Usługi intencji są specjalnie zaprojektowane do działania w wątkach roboczych w celu odciążenia przetwarzania z wątku głównego (UI), a jednym z głównych powodów jest pomoc w zapobieganiu Interfejs użytkownika zawiesza się.
Być może spróbuj rozpocząć debugowanie na poziomie interfejsu użytkownika. W szczególności, co zapewnia ResultReceiver
do IntentService
kiedy go uruchomisz i co robisz w onReceiveResult
metoda wywołania zwrotnego w tej instancji odbiorcy?
Poza tym w przypadku aktywności, w której doświadczasz zawieszeń, sprawdź, jakie operacje podejmujesz. Ładowanie dużych ilości danych z bazy danych w głównym wątku (tj. bez użycia Loader
lub coś podobnego do przeniesienia przetwarzania na wątek roboczy) jest częstą przyczyną zawieszania się interfejsu użytkownika, przynajmniej z mojego dotychczasowego doświadczenia.
Aktualizacja
Chyba domyśliłem się, na czym polega problem. Są dwa główne problemy, oba wynikające z tego, jak używasz Volley. Gdy dodasz żądanie do kolejki Volley, zostanie ono wykonane asynchronicznie. Oznacza to, że queue
metoda zwraca natychmiast. W zamierzonym kodzie usługi oznacza to, że usługa natychmiast przekazuje informację do ResultReceiver
że zakończył przetwarzanie, podczas gdy w rzeczywistości wszystko, co zrobił, to kolejkowanie żądania. Wszystkie pięć usług intencji zrobi to, co oznacza, że MainActivity
zostanie wprowadzony bardzo szybko. To jest pierwszy numer.
Drugi problem wyjaśnia zamrożenie, którego doświadczasz. Chociaż Volley wykonuje żądania w wątkach roboczych, zwraca przeanalizowane odpowiedzi na żądania w wątku głównym - zobacz dokumentację tutaj. Oznacza to, że całe przetwarzanie odpowiedzi, które wykonujesz w usłudze intencji (wprowadzanie danych do bazy danych itp.), w rzeczywistości odbywa się w wątku głównym (UI). To wyjaśnia zamrażanie.
To, co prawdopodobnie chcesz tutaj zrobić, to przełączyć się na używanie RequestFuture
Volleya zamiast. Zasadniczo zmienia to żądanie asynchroniczne w synchroniczne, umożliwiając blokowanie do momentu zakończenia żądania. Aby to zrobić, utwórz przyszłość odpowiedniego typu (JSONObject
w twoim przypadku) i ustaw go jako odbiornik i odbiornik błędów dla żądania. Następnie zakolejkuj żądanie tak jak teraz, a zaraz potem wywołaj get
metoda na przyszłość. Ta metoda będzie blokować do momentu zakończenia przetwarzania odpowiedzi. Można to zrobić w usłudze intencji, ponieważ działa ona w wątku roboczym, a nie w wątku interfejsu użytkownika.
Jeśli żądanie się powiedzie, otrzymasz zwrócone dane i możesz wykonać całą logikę, która jest obecnie w twoim Response.Listener
realizacja. Jeśli wystąpi błąd (tj. żądanie nie powiedzie się z jakiegoś powodu), przyszłe żądanie zgłosi wyjątek, który możesz obsłużyć, aby podjąć odpowiednie działania.
Używanie przyszłości żądań to zupełnie inne podejście do używania detektorów i być może będziesz musiał trochę zmienić swój kod, aby działał, ale powinno to rozwiązać problemy, które widzisz.
Mam nadzieję, że to pomoże i przepraszam, że nie wykryłem błędu wcześniej.