Você está na página 1de 6

Threads em Android

Quando um componente de aplicao inicia e a aplicao no tem outros componentes rodando,


o sistema Android inicia outro processo Linux para a aplicao com uma single thread de
execuo. Por padro, todos os componentes da mesma aplicao rodam em um mesmo
processo e thread (chamada thread principal). Se um componente de aplicao inicia e existe um
processo para aquela aplicao (pois outro componente da aplicao j existe), ento o
componente iniciado dentro do processo e usa a mesma thread de execuo. Contudo, voc
pode fazer com que diferentes componentes em sua aplicao rodem em processos separados e
poder tambm criar threads adicionais para quaisquer processos.
Quando uma aplicao lanada o sistema cria uma thread de execuo para aquela aplicao,
chamada de thread principal. Essa thread muito importante pois ela encarregada de fazer o
gerenciamento dos processos subsequentes. Ela tambm chamada de UI Thread ou Thread de
Interface.
O sistema NO cria uma thread separada para cada instncia de um componente. Todos os
componentes que rodam em um mesmo processo so instanciados na mesma UI Thread e as
chamadas a cada componente que o sistema faz so despachadas a partir dessa thread.
Consequentemente, mtodos que respondem a chamadas callback do sistema (como
onKeyDown()) sempre rodam na UI Thread do processo.
Por conta disso, quando um usurio toca um boto na tela, a UI Thread de sua aplicao envia
um evento touch para o widget que ento modifica seu estado para pressionado e posta uma
requisio dizendo que invlido. A UI Thread retira da fila a requisio e notifica o widget que
ele tem de ser redesenhado ( quando vemos a imagem do boto como pressionado).
Quando sua aplicao realiza trabalho intensivo em resposta a uma interao do usurio, uma
thread simples pode comear a ter uma resposta pobre a no ser que voc faa implementaes
em sua aplicao. Especificamente, se tudo est rodando na UI Thread, realizar longas tarefas
como um acesso a rede ou banco de dados por bloquear toda a interface da sua aplicao
enquanto essa tarefa estiver rodando. Pior, a aplicao pode demorar tanto a responder que o
sistema Android poder entender que ela est travada e mostrar a mensagem de "application not
responding". O usurio ento ter de decidir se sair da aplicao ou se a desinstala.

Worker thread
Com o modelo de thread nica mostrada acima, vital que a responsividade de sua interface de
aplicao no bloqueie a UI Thread. Se as operaes que so realizadas no so instantneas

ento voc deve se certificar de cri-las em threads separadas (threads backgroud ou worker
threads).

Por exemplo, abaixo est um cdigo de um listener click que faz o download de uma imagem em
uma thread separada e a mostra dentro de um ImageView:

public void onClick(View v) {


new Thread(new Runnable() {
public void run() {
Bitmap b = loadImageFromNetwork("http://example.com/image.png");
mImageView.setImageBitmap(b);
}
}).start();
}

Inicialmente, parece ser um cdigo perfeito, j que ele cria uma nova thread e manuseia a
operao de rede. No entanto, ele viola a segunda regra do modelo de thread nica: no acessar
a toolkit de interface do Android de fora da UI Thread. Esse exemplo modifica um ImageView a
partir de um Worker Thread ao invs da UI Thread.

Para corrigir esse problema, o Android oferece diversas maneiras de acessar a UI Thread de
outras threads. Aqui a lista de alguns mtodos que podem ajud-lo nessa tarefa:

Activity.runOnUiThread(Runnable)

View.post(Runnable)

View.postDelayed(Runnable, long)

Por exemplo, voc poder corrigir o cdigo acima usando o mtodo View.post(Runnable):

public void onClick(View v) {


new Thread(new Runnable() {
public void run() {

final Bitmap bitmap =


loadImageFromNetwork("http://example.com/image.png");
mImageView.post(new Runnable() {
public void run() {
mImageView.setImageBitmap(bitmap);
}
});
}
}).start();
}

Agora sua implementao est em modo thread-safe: a operao de rede realizada em uma
thread separada enquanto a ImageView manipulada pela UI Thread.

Iremos construir um exemplo bem simples onde realizado o download de uma imagem, o
sistema exibe uma mensagem para o usurio durante o download e a imagem exibida ao
trmino do processo.

Criar projeto no ADT: prjDownloadImagem

Insira um ImageView no Activity, com o ID imgView

Deixar o com.prjdownloadimagem.view.MainActivity.java da seguinte forma:

private static final


String URL="http://i909.photobucket.com/albums/ac294/simonvinicius/ROCKNTECH1/androidrobot1.jpg";

private ProgressDialog dialog;


private Handler handler = new Handler();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download);
//Exibe mensagem ao usurio
dialog = ProgressDialog.show(this, "Exemplo", "Buscando
imagem,aguarde!",false,true);
//Chama funo downloadImage passando a URL como parametro
downloadImagem(URL);
}

private void downloadImagem(final String urlImg) {

//Cria uma nova Thread


newThread(){
@Override
public void run(){

try {
// Faz o download da imagem
URL url = new URL(urlImg);
InputStream imputStream = url.openStream();

final Bitmap btImagem = BitmapFactory.decodeStream(imputStream);


imputStream.close();
atualizaTela(btImagem);
}catch (MalformedURLException e) {
return;
}catch(IOException e){
Log.e("Erro ao fazer o download", e.getMessage(),e);
}
}
}.start();
}

//Utiliza um handler para atualizar a tela

private void atualizaTela(final Bitmap imagem) {


handler.post(new Runnable() {
@Override
public void run() {
// Fecha a janela de mensagem ao usurio
dialog.dismiss();
ImageView imgView = (ImageView) findViewById(R.id.imgView);
imgView.setImageBitmap(imagem);
}});
}
}

Você também pode gostar