sql >> Databasteknik >  >> RDS >> SQLite

IntentService fryser mitt applikationsgränssnitt

Är du helt säker på att det är IntentService det är grundorsaken till att användargränssnittet fryser? Intent-tjänster är speciellt utformade för att köras i arbetartrådar för att avlasta bearbetning från huvudtråden (UI), med en av huvudskälen till detta för att hjälpa till att förebygga Användargränssnittet låser sig.

Testa kanske att starta dina felsökningar på gränssnittsnivå. I synnerhet vad tillhandahåller ResultReceiver till IntentService när du startar det, och vad gör du i onReceiveResult återuppringningsmetod i den mottagarinstansen?

Utöver det, kontrollera vilken typ av operationer du gör för aktiviteten som du upplever att det fryser. Laddar stora mängder data från en databas på huvudtråden (dvs utan att använda en Loader eller något liknande för att överföra bearbetningen till en arbetstråd) är en vanlig orsak till att användargränssnittet fryser, åtminstone enligt min erfarenhet hittills.

Uppdatera

Jag tror att jag har räknat ut vad problemet är. Det finns två huvudproblem, båda härrör från hur du använder Volley. När du lägger till en förfrågan i volley-kön exekveras den asynkront. Det betyder att queue metoden återkommer omedelbart. I din avsiktstjänstkod betyder detta att tjänsten omedelbart fortsätter med att berätta för ResultReceiver att den har avslutat bearbetningen, när egentligen allt den har gjort är att köa förfrågan. Alla fem avsiktstjänsterna kommer att göra detta, vilket betyder att MainActivity kommer att ingås mycket snabbt. Detta är det första numret.

Det andra problemet förklarar frysningen du upplever. Även om Volley kör förfrågningar på arbetartrådar, returnerar den de analyserade svaren på förfrågningar på huvudtråden - se dokumentationen här. Detta betyder att all svarsbehandling du gör i avsiktstjänsten (att lägga in data i databasen, etc.) faktiskt sker på huvudtråden (UI). Detta förklarar frysningen.

Vad du förmodligen vill göra här är att gå över till att använda Volleys RequestFuture istället. Detta förvandlar i princip en asynkron begäran till en synkron genom att tillåta dig att blockera tills begäran är klar. För att göra detta, skapa en framtid av lämplig typ (JSONObject i ditt fall) och ställ in den som både lyssnare och fellyssnare för begäran. Ställ sedan begäran i kö som du gör nu och ring direkt efteråt get metod för framtiden. Den här metoden blockeras tills svaret har avslutats. Det är okej att göra detta i en intent-tjänst eftersom den körs på en arbetstråd, inte UI-tråden.

Om begäran lyckas får du informationen tillbaka och du kan köra all logik som för närvarande finns i din Response.Listener genomförande. Om ett fel uppstår (d.v.s. begäran misslyckas av någon anledning), kommer framtida begäran att skapa ett undantag som du kan hantera för att vidta lämpliga åtgärder.

Att använda framtida förfrågningar är ett helt annat tillvägagångssätt för att använda lyssnare och du kan behöva ändra din kod en hel del för att få den att fungera, men det borde lösa problemen du ser.

Hoppas det hjälper, och jag ber uppriktigt om ursäkt för att jag inte upptäckte felet tidigare.



  1. Återställ din WordPress-databas med WP-CLI

  2. System.Data.OracleClient kräver Oracle-klientprogramvara version 8.1.7 eller senare

  3. Vad är det bästa sättet att trunkera ett datum i SQL Server?

  4. Hur ändrar man MySQL-tidszon i en databasanslutning med Java?