Entendendo a Thread Principal de Um App Android

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 /Entendendo a Thread Principal de Um App Android

Entendendo a Thread Principal de Um App Android

Vinícius Thiengo
(8280) (12)
Go-ahead
"Sempre sonhe e mire mais alto do que você sabe que você pode fazer. Não se preocupe em ser melhor do que seus contemporâneos e antecessores. Tente ser melhor do que você mesmo."
William Faulkner
Kotlin Android
Capa do livro Mapas Android de Alta Qualidade - Masterização Android
TítuloMapas Android de Alta Qualidade - Masterização Android
CategoriasAndroid, Kotlin, Masterização, Especialização
AutorVinícius Thiengo
Edição
Ano2020
Capítulos11
Páginas166
Acessar Livro
Quer aprender a programar para Android? Acesse abaixo o curso gratuito no Blog.
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?

Main thread, ou Thread principal, ou Thread de interface, ou ainda Thread UI. Aqui vamos utilizar o termo "Thread principal" para um dos temas mais importantes para aqueles que já estão ou vão entrar no mundo de desenvolvimento de aplicativos Android.

Se você já trabalhou com linguagens de programação que têm boas APIs para processamento paralelo, então certamente você sabe o que é uma thread. O Java e o Kotlin são linguagens que têm excelentes APIs para execuções em concorrência.

Em resumo, uma thread, em computação, é:

Uma forma de um processo dividir a si mesmo em duas ou mais tarefas que podem ser executadas concorrencialmente.

No Android, principalmente devido às duas principais linguagens oficiais, Java e Kotlin, serem linguagens JVM, nós podemos "usar e abusar" de threads.

Porém é de extrema importância conhecer a Thread principal, isso, pois é nela que é permitido, por exemplo, a atualização de componentes visuais, componentes que estão em tela.

Diagrama de Thread principal e Thread de background no Android

Note que, saber o que é e como utilizar a Thread principal no Android é tão importante quanto conhecer por completo as APIs Activity e Intent, por exemplo.

A seguir vou apresentar um rápido roteiro para tentar internalizar em sua mente a importância da Thread principal:

Em um aplicativo Android de cálculos matemáticos complexos foi exigido de você que uma determinada função fosse invocada em uma thread secundária (também conhecida como thread de background), utilizando a API Thread (que implementa de Runnable - como o "mundo" deseja), pois o processamento dessa função é lento e assim haveria o risco de travar, por alguns segundos, a interface do usuário.

O resultado dessa execução deverá ser impresso em um TextView.

Você, como excelente programador que é, fez tudo como solicitado pelo engenheiro de software do projeto. Mas para apresentar o resultado, como a função de cálculo já estava dentro da atividade, você simplesmente colocou no final dessa função, ainda dentro da execução de Thread.run(), a linha de código que acertava o resultado dentro do TextView, como a seguir: tvResult.setText( "Resultado cálculo: " + result ).

Adivinha? Exception! 😰

Por que?

Porque no Android é somente na Thread principal que componentes visuais podem ser atualizados. Alias, processamentos que podem travar a tela, mesmo que por poucos segundos, devem ocorrer fora da Thread principal, caso contrário, exceção novamente.

Na vídeo aula acima temos um exemplo mais completo e passo a passo para você entender em definitivo o que é e como utilizar, acessar, a Thread principal no Android.

Preste atenção na classe Handler, na conexão com a Internet e na permissão de conexão com a Internet. Esses são pontos importantes para o total entendimento, em aula, do funcionamento da Thread principal.

Desde já deixo claro que o modelo de conexão com a Internet utilizado no vídeo acima não é nem mesmo de perto recomendado para ser utilizado no desenvolvimento Android. Adotei esse em projeto para facilitar o entendimento da Thread principal.

Para conexões remotas, utilize APIs específicas, que fazem todo o trabalho pesado para o desenvolvedor do aplicativo.

Assim que você terminar está aula e entender por completo o que é e como utilizar a Thread principal no Android, eu fortemente recomendo que você parta para o estudo da API runOnUiThread(). Acredite, isso será um baita complemento à vídeo aula acima.

Antes de finalizar, vou deixar abaixo alguns links de outros conteúdos aqui do Blog, também com vídeos, que lhe colocarão em dia com o que há de novo no mundo do desenvolvimento Android:

E caso você tenha o desejo de aprender a criar apps 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, em primeira mão, os conteúdos Android exclusivos liberados semanalmente aqui.

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

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 Thread Principal ainda estar atual e ser de grande importância 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.

Fontes

Visão geral dos processos e threads

Communicate with the UI thread

Better performance through threading

Thread (computação)

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

Classe Intent e o Conceito de Pilha em AndroidClasse Intent e o Conceito de Pilha em AndroidAndroid
Enviando e Recebendo Dados Entre Activities em AndroidEnviando e Recebendo Dados Entre Activities em AndroidAndroid
Entendendo e Utilizando IntentFilter no AndroidEntendendo e Utilizando IntentFilter no AndroidAndroid
Assinando Uma APP Android e Publicando na Play StoreAssinando Uma APP Android e Publicando na Play StoreAndroid

Compartilhar

Comentários Facebook

Comentários Blog (12)

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...
03/02/2017
Refiz a aplicação com AsyncTask, depois de executar o app encerra.
Qual seria o problema?


package br.exemplothreadprincipal;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class MainActivity extends Activity {
public ImageView iv;
    public ProgressBar progressBar;
    public Button button;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
        button = (Button) findViewById(R.id.botao);
        iv = (ImageView) findViewById(R.id.imagem);
        progressBar = (ProgressBar)findViewById(R.id.progressBar);
    }

    public void disableprogressbar(){
        progressBar.setVisibility(View.GONE);
    }

    public void setView(Bitmap bitmap){
        iv.setImageBitmap(bitmap);
    }

    public void baixarImagemWeb(View view) {
        Download download = new Download();
        download.execute();
    }
    private class Download extends AsyncTask<ImageView, ImageView, Void> {

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

        @Override
        protected Void doInBackground(ImageView... params) {
            try {

                URL url = new URL("http://www.thiengo.com.br/img/system/logo/thiengo-80-80.png ");
                HttpURLConnection connection;
                connection = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);
                connection.connect();
                InputStream input = connection.getInputStream();
                final Bitmap imagem = BitmapFactory.decodeStream(input);

                Log.i("livro", "baixou imagem.");
                setView(imagem);
            }
            catch (MalformedURLException e) {
                e.printStackTrace();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            disableprogressbar();
        }
    }
}
Responder
Vinícius Thiengo (0) (0)
03/02/2017
Victor, tudo bem?

De acordo com a assinatura de seu AsyncTask: Download extends AsyncTask<ImageView, ImageView, Void>

A invocação de execute() por meio de uma instância de Download, essa invocação deve ter como parâmetro um ImageView. Seria assim: download.execute( iv );

Mas acredito essa não ser a melhor opção para seu código. Partindo do algoritmo que você colocou aqui eu fiz algumas alterações, veja se a versão do link a seguir funciona melhor para ti: http://pastebin.com/KNKEu8Er

Note que o download de imagem do vídeo aqui é somente para apresentar o trabalho com Thread, pois para carregamento de imagem você deve mesmo utilizar libraries como as seguintes:

Picasso: http://square.github.io/picasso/
Universal Image Loader: http://www.thiengo.com.br/carregamento-e-cache-de-imagem-com-universal-image-loader-no-android
Fresco: http://www.thiengo.com.br/lib-fresco-para-carregamento-de-imagens-com-gifs-e-webps-animados-material-design-android-parte-12

Abraço.
Responder
03/02/2017
Shown Vinícius , ainda estou domindo os paramentro do AsyncTask, deu tudo certo. E parabéns pelos seus vídeos.
Responder
Rodolfo Lima Jesus (1) (0)
31/10/2015
Parabéns pelos tutorias, comecei aprender android a pouco tempo e posso dizer que aprendi muito com seus posts. Desculpa te fazer essa pergunta por aqui, mas você já fez algum tutorial sobre fazer login em um site via programação, sem api? Se não fez, fica a dica. Estou quebrando a cabeça para fazer isso, pois não tem nada claro na internet para estudar.

Abs.
Responder
Vinícius Thiengo (0) (0)
31/10/2015
Vlw a dica Rodolfo, ainda não tenho esse vídeo. Abraço
Responder
Lucas P (1) (0)
01/07/2015
Olá, Gostei muito do tutorial, mas estou com problema ao tentar implementar Handler, ele não lista método post
Responder
Vinícius Thiengo (0) (0)
02/07/2015
Fala Lucas, blz?
Está utilizando o handler do import: android.os.Handler ? Pois testei aqui e o método post foi listado sem problemas. Tente com esse import, pois há um outro: java.util.logging.Handler que não é o correto para o caso acima. Abraço
Responder
31/01/2015
Cada atividade tem um thread principal. bom saber. Parabéms e obrigado.
Responder
pedrobmm52 (0) (0)
27/08/2014
esse final antes das vari?veis serve pra que?
Responder
Vinícius Thiengo (0) (0)
27/08/2014
Fala Pedro, blz?
Qual ponto especifico do vídeo (tempo) vc está falando? Abraço
Responder
27/08/2014
Blz, estou dizendo quando você declarou o nome "final" antes da váriavel
Responder
Vinícius Thiengo (0) (0)
27/08/2014
A sim, então, onde eu declarei o Bitmap imagem precisa de final para que eu possa acessar a mesma variável na instanciação anônima da classe Runnable, senão não vai! Abraço
Responder