AsyncTask no Android, Acesso a Thread Principal de Forma Otimizada

Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba grátis conteúdos Android sem precedentes! Você receberá um email de confirmação. Somente depois de confirma-lo é que eu poderei lhe enviar os conteúdos semanais exclusivos. Os artigos em PDF são entregues somente para os inscritos na lista.

Email inválido.
Blog /Android /AsyncTask no Android, Acesso a Thread Principal de Forma Otimizada

AsyncTask no Android, Acesso a Thread Principal de Forma Otimizada

Vinícius Thiengo
(9290) (4)
Go-ahead
"O método consciente de tentativa e erro é mais bem-sucedido que o planejamento de um gênio isolado."
Peter Skillman
Prototipagem Android
Capa do curso Prototipagem Profissional de Aplicativos
TítuloAndroid: Prototipagem Profissional de Aplicativos
CategoriasAndroid, Design, Protótipo
AutorVinícius Thiengo
Vídeo aulas186
Tempo15 horas
ExercíciosSim
CertificadoSim
Acessar Curso
Quer aprender a programar para Android? Acesse abaixo o curso gratuito no Blog.
Lendo
TítuloManual de DevOps: como obter agilidade, confiabilidade e segurança em organizações tecnológicas
CategoriaEngenharia de Software
Autor(es)Gene Kim, Jez Humble, John Willis, Patrick Debois
EditoraAlta Books
Edição
Ano2018
Páginas464
Conteúdo Exclusivo
Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba gratuitamente conteúdos Android sem precedentes!
Email inválido

Tudo bem?

Na vídeo aula acima estudaremos por completo a classe AsyncTask, classe que permite o trabalho de uma thread secundária e da thread principal em um mesmo objeto.

Para que o entendimento da AsyncTask seja mais eficiente, é importante que você saiba o que é a thread principal no Android e também como utilizar o atalho de acesso a thread principal, a API runOnUiThread.

A AsyncTask é uma importante API para projetos que envolvem algoritmos que devem rodar local, no aplicativo Android, e que exigem alguns segundos de processamento, ou seja, que podem travar a tela caso executando em thread principal.

Seguramente posso lhe dizer que a API AsyncTask é a junção de uma thread de execução em background, secundária, com a API runOnUiThread, pois com a AsyncTask nós temos:

  • onPreExecute() - método invocado uma única vez, antes que o processamento em thread secundária se inicie. Método que ainda roda na thread principal.
  • doInBackground() - método invocado já em thread secundária. Fica em execução o tempo que for necessário. Isso assumindo que o aplicativo estará em foreground, primeiro plano, assim não há grandes chances de o algoritmo em doInBackground() ser abortado pelo sistema Android;
  • publishProgress() - se necessário o fornecimento de "progresso de execução" ao usuário, este método deve ser invocado dentro do algoritmo em doInBackground();
  • onProgressUpdate() - método que também roda na thread principal, como onPreExecute(), porém esse aqui é invocado sempre que há a invocação de publishProgress()onProgressUpdate() é comumente utilizado para apresentar em tela o progresso do processamento em doInBackground(). Boa prática para a experiência do usuário, tendo em mente que ele, o usuário, passa a entender que algo está em processamento e não há nada "travado", bug, no app;
  • onPostExecute() - método invocado assim que há o retorno, return, no método doInBackground(). Esse método executa na thread principal e é o último método invocado da instância única de AsyncTask.

Fluxo de execução de uma instância de AsyncTask

Thiengo, o que você quer dizer com "instância única de AsyncTask"?

Em resumo: que não é possível reutilizar uma mesma instância para várias invocações do algoritmo em doInBackground(). Se necessária uma nova invocação daquele algoritmo, deve-se criar uma nova instância de AsyncTask, digo, da subclasse de AsyncTask, pois está é abstrata.

A seguir um simples exemplo de um código AsyncTask:

public class OilAreaActivity extends AppCompatActivity {

@Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
...

CalculationOilArea task = new CalculationOilArea();
task.execute( firstOilType, secondOilType );
}


class CalculationOilArea extends AsyncTask<OilType, Integer, Float>{

@Override
protected void onPreExecute() {
super.onPreExecute();

/*
* Todo o algoritmo que deve ser executado
* antes do processamento em doInBackground().
* O algoritmo aqui roda em thread principal.
* */
...
}

@Override
protected Float doInBackground( OilType... types ) {

Float result = 0.0F;

/*
* Todo o algoritmo de execução em thread
* secundária, de background.
* */
...
publishProgress( progressInteger );
...

return result;
}

@Override
protected void onProgressUpdate( Integer... values ) {
super.onProgressUpdate( values );

/*
* Todo o algoritmo de atualização de progresso
* do script em execução em doInBackground().
* */
...
}

@Override
protected void onPostExecute( Float result ) {
super.onPostExecute( result );

/*
* Todo o algoritmo que deve ser executado assim
* que se finaliza o processamento em
* doInBackground(). O algoritmo aqui já roda
* em thread principal.
* */
...
}
}
}

 

Thiengo, uma dúvida: então eu posso assumir que a AsyncTask API inviabiliza o uso de instâncias de Thread e da API runOnUiThread?

De forma alguma. Cada API é de extrema utilidade em contextos, domínios de problemas, específicos.

Veja o cenário a seguir:

Ao final de uma comunicação remota utilizando a API Retrofit, no método de resultado desta API, método que já executa em thread principal, é necessário o trabalho com um banco de dados local para salvar a lista de dados retornada.

Isso para que o aplicativo também trabalhe offline.

Porém esse processamento de salvar dados em banco de dados local tende a ser pesado e precisa ocorrer em uma thread secundária, tendo em mente que os dados, já retornados do back-end Web, podem ser apresentados ao usuário enquanto eles são também salvos na base local.

Enfim, utilizar uma instância de Thread para a execução do banco de dados local no contexto acima é uma escolha muito mais inteligente do que criar uma instância de AsyncTask, onde somente o método doInBackground() seria realmente utilizado.

O cenário acima é somente para deixar claro que cada API tem a sua necessidade de acordo com o domínio de problema. As que não mais têm, foram removidas do SDK Android ou estão marcadas como depreciadas, ou seja, logo serão removidas.

Uma ressalva importante:

Na vídeo aula acima há uma conexão com um servidor remoto utilizando a API AsyncTask.

Bom, na época em que essa vídeo aula foi criada, em 2014, essa era uma excelente rota, uso de AsyncTask para comunicação com servidores remotos. Hoje em dia não mais, utilize APIs especificas para isso.

De qualquer forma, mesmo o vídeo sendo um pouco antigo, todo o conteúdo teórico e prático dele é ainda válido e a não recomendação de uso da AsyncTask API em contexto de comunicação remota não inviabiliza em nada a necessidade de estudo por completo dela.

Até porque no mundo de desenvolvimento Android há muito mais tipos de processamentos pesados do que somente o processamento de comunicação remota com servidor Web.

Antes de finalizar, vou deixar a seguir alguns links de outros conteúdos do Blog, com vídeos, que lhe colocarão em dia com o que há de atual no mundo do desenvolvimento Android:

E caso você tenha o desejo de aprender a criar aplicativos Android, ou evoluir nesta área, também com o conteúdo gratuito do Blog, então não deixe de acessar a lista de estudos em: Estudando Android - Lista de Conteúdos do Blog.

Não esqueça de se inscrever 📫 na lista de e-mails do Blog para receber os conteúdos Android, liberados semanalmente aqui.

Se inscreva também no canal do Blog no YouTube para acompanhar as últimas novidades disponibilizadas em vídeo aula.

Surgindo dúvidas ou dicas, pode colocar abaixo na área de comentários que logo eu lhe retorno.

Obs. : o link para download do projeto apresentado em vídeo se encontra logo abaixo no artigo, na seção "Download".

Abraço.

Eclipse IDE vs Android Studio IDE

Apesar de o conteúdo da vídeo aula acima estar utilizando o Eclipse IDE 😱, tudo que é apresentado, tanto a parte teórica quanto a parte prática, é ainda válido nos dias de hoje com o desenvolvimento Android utilizando o Android Studio 😁.

Ou seja, independente da linguagem oficial (Java, Kotlin, C ou C++), IDE ou framework que você esteja utilizando, o conteúdo acima é ainda muito útil.

AndroidX

Apesar do conteúdo sobre a AsyncTask ser um diferencial para qualquer nível de desenvolvedor Android.

Apesar disso eu também recomendo, assim que finalizado o projeto em sua própria instalação de IDE, que você o migre para o AndroidX.

Algo que pode ser feito com poucos cliques, como apresentado no tutorial a seguir: Migrar para o AndroidX.

Fonte

AsyncTask - documentação oficial Android

Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba grátis conteúdos Android sem precedentes!
Email inválido

Relacionado

Monetizando Sua APP Com o Google AdMob (Anúncios Mobile)Monetizando Sua APP Com o Google AdMob (Anúncios Mobile)Android
9-Patch no Android, Mantendo a Qualidade de Imagens de Background9-Patch no Android, Mantendo a Qualidade de Imagens de BackgroundAndroid
Notification no Android, Criando Notificações Com Toque e VibraçãoNotification no Android, Criando Notificações Com Toque e VibraçãoAndroid
AlarmManager no Android, Sua APP Executando Em Tempos DefinidosAlarmManager no Android, Sua APP Executando Em Tempos DefinidosAndroid

Compartilhar

Comentários Facebook

Comentários Blog (4)

Para código / script, coloque entre [code] e [/code] para receber marcação especifica.
Forneça seu nome válido.
Forneça seu email válido.
Forneça o comentário.
Enviando, aguarde...
Thiago (1) (0)
28/06/2018
Eai Vinícius, blz?

Eu fiz igual seu exemplo, porém estou com um problema na linha em que recebi o Bitmap. Está me retornando valor null esse cara --> BitmapFactory.decodeStream(input);
Tem como me dar uma luz??
Desde já obrigado.
Responder
Vinícius Thiengo (1) (0)
01/07/2018
Thiago, tudo bem aqui.

A principal luz que vou lhe dar é: para carregamento de imagens remotas, utilize alguma API específica somente para esta tarefa.

Digo isso, pois o seu problema foi na construção do Bitmap e não no uso da API AsyncTask.

APIs exclusivas para carregamento de imagens já fazem todo o trabalho pesado para nós desenvolvedores Android. A seguir deixo o link de algumas que já abordei aqui no Blog:

-> Universal Image Loader: https://www.thiengo.com.br/carregamento-e-cache-de-imagem-com-universal-image-loader-no-android

-> Fresco API: http://frescolib.org/

De qualquer forma, a que mais recomendo é a Picasso API, por ser simples e robusta: http://square.github.io/picasso/

Abraço.
Responder
Hendrix (1) (0)
16/12/2015
Parabéns pela AULA!
Me ajudou bastante. Obrigado
Responder
Vinícius Thiengo (0) (1)
16/12/2015
Vlw Hendrix.
Se for utilizar o AsyncTask para carregamento de imagem, prefira o Fresco (http://www.thiengo.com.br/lib-fresco-para-carregamento-de-imagens-com-gifs-e-webps-animados-material-design-android-parte-12 ) ou o Picasso (http://square.github.io/picasso/ ).

Para conexão Web na obtenção de dados da base remota, utilize o Retrofit 2.0 (http://www.thiengo.com.br/library-retrofit-2-no-android ). Abraço
Responder