sql >> Database >  >> RDS >> SQLite

IntentService bevriest de gebruikersinterface van mijn toepassing

Weet je absoluut zeker dat het de IntentService . is? dat is de oorzaak van het bevriezen van de gebruikersinterface? Intent-services zijn speciaal ontworpen om in werkthreads te worden uitgevoerd om de verwerking van de hoofdthread (UI) te ontlasten, met als een van de belangrijkste redenen om te helpen voorkomen UI loopt vast.

Misschien kunt u proberen uw debugging-inspanningen op UI-niveau te starten. In het bijzonder, wat levert de ResultReceiver naar de IntentService wanneer u het start, en wat doet u in de onReceiveResult callback-methode in die ontvangerinstantie?

Anders dan dat, controleer voor de activiteit waarin u de bevriezing ervaart, wat voor soort bewerkingen u uitvoert. Het laden van grote hoeveelheden gegevens uit een database op de hoofdthread (d.w.z. zonder gebruik van een Loader of iets dat lijkt op het offloaden van de verwerking naar een werkthread) is een veelvoorkomende oorzaak van het vastlopen van de gebruikersinterface, althans in mijn ervaring tot nu toe.

Bijwerken

Ik denk dat ik erachter ben wat het probleem is. Er zijn twee hoofdproblemen, die beide voortkomen uit de manier waarop je Volley gebruikt. Wanneer u een aanvraag toevoegt aan de Volley-wachtrij, wordt deze asynchroon uitgevoerd. Dat betekent dat de queue methode keert onmiddellijk terug. In uw intentie-servicecode betekent dit dat de service onmiddellijk doorgaat met het doorgeven van de ResultReceiver dat het klaar is met verwerken, terwijl het eigenlijk alleen maar het verzoek in de wachtrij heeft gezet. Alle vijf de intentieservices zullen dit doen, wat betekent dat MainActivity zeer snel zal worden ingevoerd. Dit is het eerste nummer.

Het tweede probleem verklaart de bevriezing die u ervaart. Hoewel Volley verzoeken uitvoert op werkthreads, retourneert het de geparseerde antwoorden op verzoeken op de hoofdthread - zie de documentatie hier. Dit betekent dat alle responsverwerking die u doet in de intentieservice (het plaatsen van de gegevens in de database, enz.) daadwerkelijk plaatsvindt op de hoofdthread (UI). Dit verklaart het bevriezen.

Wat je hier waarschijnlijk wilt doen, is overschakelen naar het gebruik van Volley's RequestFuture in plaats van. Dit verandert in feite een asynchrone aanvraag in een synchrone door u toe te staan ​​te blokkeren totdat de aanvraag is voltooid. Maak hiervoor een toekomst van het juiste type (JSONObject in uw geval) en stel het in als zowel de listener als de foutlistener voor het verzoek. Zet het verzoek dan in de wachtrij zoals u nu doet, en bel onmiddellijk daarna de get methode voor de toekomst. Deze methode blokkeert totdat het antwoord is verwerkt. Het is prima om dit in een intent-service te doen, omdat deze wordt uitgevoerd op een werkthread, niet op de UI-thread.

Als het verzoek slaagt, krijgt u de gegevens terug en kunt u alle logica uitvoeren die momenteel in uw Response.Listener staat. implementatie. Als er een fout optreedt (d.w.z. het verzoek mislukt om de een of andere reden), zal het toekomstige verzoek een uitzondering genereren die u kunt afhandelen om de juiste acties te ondernemen.

Het gebruik van request futures is een heel andere benadering van het gebruik van listeners en het kan zijn dat je je code behoorlijk moet veranderen om het te laten werken, maar het zou de problemen moeten oplossen die je ziet.

Ik hoop dat dat helpt, en mijn oprechte excuses dat ik de bug niet eerder heb opgepikt.



  1. Pyodbc - Naam gegevensbron niet gevonden en geen standaardstuurprogramma opgegeven

  2. Voortschrijdend gemiddelde op basis van tijdstempels in PostgreSQL

  3. JDBC-verbindingen in pool sluiten

  4. Excel-spreadsheetkolommen importeren in SQL Server-database