Entendendo a Thread Principal de Um App Android

Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog. Você receberá um email de confirmação. Somente depois de confirma-lo é que poderei lhe enviar os conteúdos exclusivos.

Email inválido.
Blog /Android /Entendendo a Thread Principal de Um App Android

Entendendo a Thread Principal de Um App Android

Vinícius Thiengo
(6319) (12)
Go-ahead
"Quanto tempo você deve tentar? Até chegar lá."
Jim Rohn
Kotlin Android
Capa do livro Desenvolvedor Kotlin Android - Bibliotecas para o dia a dia
TítuloDesenvolvedor Kotlin Android - Bibliotecas para o dia a dia
CategoriasAndroid, Kotlin
AutorVinícius Thiengo
Edição
Capítulos19
Páginas1035
Acessar Livro
Treinamento Oficial
Android: Prototipagem Profissional de Aplicativos
CursoAndroid: Prototipagem Profissional de Aplicativos
CategoriaAndroid
InstrutorVinícius Thiengo
NívelTodos os níveis
Vídeo aulas186
PlataformaUdemy
Acessar Curso
Receitas Android
Capa do livro Receitas Para Desenvolvedores Android
TítuloReceitas Para Desenvolvedores Android
CategoriaDesenvolvimento Android
AutorVinícius Thiengo
Edição
Ano2017
Capítulos20
Páginas936
Acessar Livro
Código Limpo
Capa do livro Refatorando Para Programas Limpos
TítuloRefatorando Para Programas Limpos
CategoriaEngenharia de Software
AutorVinícius Thiengo
Edição
Capítulos46
Páginas599
Acessar Livro
Quer aprender a programar para Android? Acesse abaixo o curso gratuito no Blog.
Conteúdo Exclusivo
Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog.
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.

Fontes

Visão geral dos processos e threads

Communicate with the UI thread

Better performance through threading

Thread (computação)

Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog.
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