Er du helt sikker på, at det er IntentService
det er årsagen til, at brugergrænsefladen fryser? Intent-tjenester er specielt designet til at køre i arbejdertråde for at aflaste behandling fra hovedtråden (UI), med en af hovedårsagerne til dette at hjælpe med at forebygge Brugergrænsefladen fryser.
Prøv måske at starte din fejlfindingsindsats på UI-niveau. Især hvad giver ResultReceiver
til IntentService
når du starter det, og hvad gør du i onReceiveResult
tilbagekaldsmetode i den modtagerinstans?
Bortset fra det, for den aktivitet, du oplever at fryser i, skal du kontrollere, hvilken slags operationer du foretager. Indlæsning af store mængder data fra en database på hovedtråden (dvs. uden at bruge en Loader
eller noget lignende til at overføre behandlingen til en arbejdstråd) er en almindelig årsag til, at brugergrænsefladen fryser, i hvert fald efter min erfaring indtil videre.
Opdater
Jeg tror, jeg har fundet ud af, hvad problemet er. Der er to hovedproblemer, som begge stammer fra, hvordan du bruger Volley. Når du tilføjer en anmodning til volley-køen, bliver den eksekveret asynkront. Det betyder, at queue
metode vender tilbage med det samme. I din hensigtstjenestekode betyder det, at tjenesten straks fortsætter med at fortælle ResultReceiver
at den er færdig med at behandle, når faktisk alt, hvad den har gjort, er at sætte anmodningen i kø. Alle fem hensigtstjenester vil gøre dette, hvilket betyder at MainActivity
vil blive indgået meget hurtigt. Dette er det første nummer.
Det andet problem forklarer den frysning, du oplever. Selvom Volley udfører anmodninger på arbejdertråde, returnerer den de parsede svar til anmodninger på hovedtråden - se dokumentationen her. Det betyder, at al den svarbehandling, du laver i hensigtstjenesten (indsætter dataene i databasen, osv.) faktisk foregår på hovedtråden (UI). Dette forklarer frysningen.
Det, du sandsynligvis vil gøre her, er at skifte over til at bruge Volleys RequestFuture
i stedet. Dette forvandler dybest set en asynkron anmodning til en synkron ved at tillade dig at blokere, indtil anmodningen afsluttes. For at gøre dette skal du oprette en fremtid af den passende type (JSONObject
i dit tilfælde) og indstil den som både lytteren og fejllytteren for anmodningen. Sæt derefter anmodningen i kø, som du gør nu, og ring straks derefter til get
metode om fremtiden. Denne metode vil blokere, indtil svaret er færdigbehandlet. Det er okay at gøre dette i en hensigtstjeneste, fordi den kører på en arbejdstråd, ikke brugergrænsefladetråden.
Hvis anmodningen lykkes, vil du få dataene returneret, og du kan udføre al den logik, der i øjeblikket er i din Response.Listener
implementering. Hvis der opstår en fejl (dvs. anmodningen mislykkes af en eller anden grund), vil den fremtidige anmodning give en undtagelse, som du kan håndtere for at foretage passende handlinger.
Brug af request futures er en helt anden tilgang til at bruge lyttere, og du skal muligvis ændre din kode en del for at få den til at fungere, men det burde løse de problemer, du ser.
Håber det hjælper, og min oprigtige undskyldning for ikke at opfange fejlen tidligere.