
W poprzednim wpisie krótko przedstawiłem wam czym jest
Thread. Z jego pomocą możemy dużo zdziałać, jednak od razu pisząc program możemy zauważyć pewną jego wadę - niektóre części aplikacji przed jego uruchomieniem musimy zablokować, tak aby nie zmieniły swojego stanu. Nie możemy również w łatwy sposób dostać się do innych fragmentów programu, co może być dla nas problematyczne, bo
Thread często będzie wykonywał jakieś cięższe prace. Aby pozbyć się takich dolegliwości, Android potrafi obsługiwać pewną funkcjonalność jaką są
MessageHandlery.
Informacja: Nie radzisz sobie z kodem? Coś Ci nie wychodzi lub nie działa? Zgubiłeś się? W tym miejscu zobaczysz pełen kod aplikacji, a tutaj go pobierzesz na dysk.
1. Handler
Jak pisałem,
Handler umożliwia wysyłanie i przetwarzanie wiadomości (jak i obiektów
MessageQueue powiązanych z
Runnable). Każdy pojedynczy
Handler jest połączony z wątkiem (tym, w którym zostaje stworzony) i w nim zostają przetwarzane wiadomości, które w końcu trafiają do naszego
Handlera.
O co chodzi z tymi wiadomościami? Są to proste komunikaty, w których albo możemy przesyłać całe dane do przetworzenia, albo wybrane identyfikatory. Przykładowo,
Handler może czekać na wiadomość z liczbą jeden. Jeżeli taką dostanie (to znaczy odbierze i rozpozna), wykona określoną przez nas czynność. Co ważne, nasze rozpisane zadanie nie zostanie uruchomione wcześniej, tylko dokładnie wtedy kiedy dojdzie wiadomość.
Pojedyncze komunikaty możemy wysyłać przez konstruowanie wiadomości typu
Message (lub
EmptyMessage).
Przykład wykorzystania? Nasz
Thread może na przykład coś pobierać czy wczytywać. Gdy skończy, wynik (poprzez
Message) możemy przesłać do naszego
Handlera, który w następnym kroku coś wykona, nawet niekoniecznie w naszym obecnym
Activity.
2. Tworzymy Hander z Threadem
Stwórzmy jakiś prosty przykład zastosowania/wykorzystania
Handlera w aplikacji. Skopiujmy naszą wczorajszą klasę, zmieńmy jej nazwę oraz wklejmy ponownie do projektu - zróbmy po prostu jej kopię w aplikacji. Nie będziemy tworzyć ponownie szablonów i pisać kodu nowego wątku, tylko skorzystamy z tego co już mamy. Starą-nową klasę nazwijmy
View_Handler.
Najpierw dodajmy prostego
Handlera do programu, nie zmieniając niczego wcześniej w aplikacji:
package com.example.moja.pierwsza.aplikacja;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;
public class View_Handler extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_thread);
final TextView tv1 = (TextView) findViewById(R.id.tV_thread);
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
new Thread(new Runnable() {
public void run() {
tv1.setText("Thread został uruchomiony!");
}
}).start();
}
}
Nic trudnego. Tworzymy naszego
Handlera, po czym w nim umieszczamy metodę oczekującą i obsługującą nadchodzące wiadomości. Tutaj możemy stworzyć rozpoznawanie tego co otrzymujemy i wykonać odpowiednie działania. W naszym przykładzie zmienimy jedynie
TextView na kolejną liczbę.
package com.example.moja.pierwsza.aplikacja;
import android.R.integer;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;
public class View_Handler extends Activity {
TextView tv1;
Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_thread);
tv1 = (TextView) findViewById(R.id.tV_thread);
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
tv1.setText(msg.obj.toString());
}
};
new Thread(new Runnable() {
public void run() {
try {
int przesylanaliczba = 0;
while (przesylanaliczba < 10) {
// Próbujemy uśpić thread na dwie sekundy, abyśmy
// widzieli jego działanie
Thread.sleep(2000);
// Tworzymy nową wiadomość
Message wiadomosc = new Message();
// Dodajemy treść, używamy jednego z dostępnych pól w Message
wiadomosc.obj = przesylanaliczba;
// Zwiększamy liczbę o kolejną
przesylanaliczba++;
// Oczywiście wysyłamy na końcu naszą wiadomość do Handlera
handler.sendMessage(wiadomosc);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
I oto cała magia. Kolejne kroki opisałem od razu przy kodzie, abyście wiedzieli co się dzieje.
Handlery to bardzo przydatna część w aplikacji, i jeżeli dobrze jej użyjemy, to zapewnimy sobie całą garść ciekawych funkcjonalności.

Ps. Czyta to ktoś? ;) Jeżeli tak, to możecie podawać swoje pomysły i propozycje, spróbuję pomóc!