SQLite
 sql >> Base de Dados >  >> RDS >> SQLite

IntentService está congelando a interface do meu aplicativo


Você tem certeza absoluta de que é o IntentService essa é a causa raiz dos congelamentos da interface do usuário? Os serviços de intenção são especialmente projetados para serem executados em threads de trabalho para descarregar o processamento do thread principal (UI), com uma das principais razões para isso ajudar a prevenir A interface do usuário congela.

Talvez tente iniciar seus esforços de depuração no nível da interface do usuário. Em particular, o que fornece o ResultReceiver para o IntentService quando você o inicia e o que você faz no onReceiveResult método de retorno de chamada nessa instância do receptor?

Fora isso, para a atividade em que você está enfrentando os congelamentos, verifique que tipo de operações você está realizando. Carregando grandes quantidades de dados de um banco de dados no thread principal (ou seja, sem usar um Loader ou algo semelhante para descarregar o processamento para um thread de trabalho) é uma causa comum de congelamento da interface do usuário, pelo menos na minha experiência até agora.

Atualizar

Acho que descobri qual é o problema. Existem dois problemas principais, ambos decorrentes de como você está usando o Volley. Quando você adiciona uma solicitação à fila do Volley, ela é executada de forma assíncrona. Isso significa que a queue método retorna imediatamente. Em seu código de serviço de intenção, isso significa que o serviço imediatamente informa ao ResultReceiver que terminou o processamento, quando na verdade tudo o que fez foi enfileirar a solicitação. Todos os cinco serviços de intenção farão isso, o que significa que MainActivity será inserido muito rapidamente. Esta é a primeira questão.

A segunda questão explica o congelamento que você está enfrentando. Embora o Volley execute solicitações em threads de trabalho, ele retorna as respostas analisadas para solicitações no thread principal - veja a documentação aqui. Isso significa que todo o processamento de resposta que você está fazendo no serviço de intenção (colocando os dados no banco de dados etc.) está realmente acontecendo no encadeamento principal (UI). Isso explica o congelamento.

O que você provavelmente quer fazer aqui é usar o RequestFuture do Volley em vez de. Isso basicamente transforma uma solicitação assíncrona em uma síncrona, permitindo que você bloqueie até que a solicitação termine. Para fazer isso, crie um futuro do tipo apropriado (JSONObject no seu caso) e defina-o como ouvinte e ouvinte de erro para a solicitação. Em seguida, coloque a solicitação na fila como você faz agora e, imediatamente depois, ligue para get método no futuro. Este método irá bloquear até que a resposta termine o processamento. Não há problema em fazer isso em um serviço de intenção porque ele é executado em um thread de trabalho, não no thread da interface do usuário.

Se a solicitação for bem-sucedida, você receberá os dados retornados e poderá executar toda a lógica que está atualmente em seu Response.Listener implementação. Se ocorrer um erro (ou seja, a solicitação falhar por algum motivo), a solicitação futura lançará uma exceção que você pode manipular para executar as ações apropriadas.

Usar futuros de solicitação é uma abordagem bem diferente do uso de ouvintes e talvez seja necessário alterar um pouco seu código para que funcione, mas deve resolver os problemas que você está vendo.

Espero que ajude, e minhas sinceras desculpas por não ter percebido o bug antes.