SQLite
 sql >> Database >  >> RDS >> SQLite

IntentService sta bloccando l'interfaccia utente dell'applicazione

Sei assolutamente certo che sia il IntentService questa è la causa principale dei blocchi dell'interfaccia utente? I servizi di intent sono appositamente progettati per essere eseguiti nei thread di lavoro al fine di scaricare l'elaborazione dal thread principale (UI), con uno dei motivi principali per aiutare a prevenire L'interfaccia utente si blocca.

Forse prova a iniziare i tuoi sforzi di debug a livello di interfaccia utente. In particolare, cosa fornisce il ResultReceiver al IntentService quando lo avvii e cosa fai in onReceiveResult metodo di callback nell'istanza del destinatario?

A parte questo, per l'attività in cui stai vivendo i blocchi, controlla che tipo di operazioni stai effettuando. Caricamento di grandi quantità di dati da un database sul thread principale (cioè senza utilizzare un Loader o qualcosa di simile per scaricare l'elaborazione su un thread di lavoro) è una causa comune di blocchi dell'interfaccia utente, almeno nella mia esperienza finora.

Aggiorna

Penso di aver capito qual è il problema. Ci sono due problemi principali, entrambi derivanti da come stai usando Volley. Quando aggiungi una richiesta alla coda Volley, viene eseguita in modo asincrono. Ciò significa che la queue il metodo ritorna immediatamente. Nel codice del servizio intento, ciò significa che il servizio continua immediatamente a comunicare a ResultReceiver che ha terminato l'elaborazione, quando in realtà non ha fatto altro che accodare la richiesta. Tutti e cinque i servizi di intent lo faranno, il che significa che MainActivity verrà inserito molto rapidamente. Questo è il primo problema.

Il secondo problema spiega il blocco che stai riscontrando. Sebbene Volley esegua le richieste sui thread di lavoro, restituisce le risposte analizzate alle richieste sul thread principale - vedere la documentazione qui. Ciò significa che tutta l'elaborazione della risposta che stai eseguendo nel servizio di intenti (inserimento dei dati nel database, ecc.) Sta effettivamente accadendo sul thread principale (UI). Questo spiega il congelamento.

Quello che probabilmente vuoi fare qui è passare all'utilizzo di RequestFuture di Volley invece. Questo fondamentalmente trasforma una richiesta asincrona in una sincrona consentendoti di bloccare fino al termine della richiesta. Per fare ciò, crea un future del tipo appropriato (JSONObject nel tuo caso) e impostalo sia come listener che come listener di errori per la richiesta. Quindi, metti in coda la richiesta come fai ora, e subito dopo chiama il get metodo sul futuro. Questo metodo si bloccherà fino al termine dell'elaborazione della risposta. Va bene farlo in un servizio intent perché viene eseguito su un thread di lavoro, non sul thread dell'interfaccia utente.

Se la richiesta ha esito positivo, riceverai i dati restituiti e potrai eseguire tutta la logica che è attualmente nel tuo Response.Listener implementazione. Se si verifica un errore (ad es. la richiesta non riesce per qualche motivo), la richiesta futura genererà un'eccezione che puoi gestire per intraprendere qualsiasi azione appropriata.

L'utilizzo di richieste future è un approccio piuttosto diverso all'utilizzo dei listener e potrebbe essere necessario modificare un po' il codice per farlo funzionare, ma dovrebbe risolvere i problemi che stai riscontrando.

Spero di esserti stato d'aiuto e mi scuso sinceramente per non aver rilevato il bug prima.