Denne Artikkelen dekker Android Looper, Handler og HandlerThread. Disse er blant byggesteinene I Android OS.
i min egen erfaring har jeg brukt dem i en svært begrenset sammenheng til nylig. Min brukstilfelle involverte å sende oppgaver til hoved / ui-tråden, først og fremst for å oppdatere BRUKERGRENSESNITTET fra en annen tråd. De andre aspektene ved multi-threaded operasjonen ble håndtert gjennom alternative måter som ThreadPoolExecutor, IntentService og AsyncTask.
MultiThreading og oppgave som kjører er gamle fag. Java selv har java.util.samtidig pakke Og Gaffel / Bli med rammeverk for å lette det. Flere biblioteker er skrevet for å effektivisere asynkrone operasjoner. RxJava er det mest populære biblioteket i dag for reaktiv programmering og utforming av en asynkron applikasjon.
Så hvorfor skriver jeg om den gamle skolen?
Looper
, Handler
, og HandlerThread
Er Android måte å løse problemene med asynkron programmering. De er ikke gamle skolen, men en pen struktur som et komplekst android-rammeverk er bygget på.
for nye utviklere anbefales det å forstå prinsippene bak dem, og erfarne bør besøke dette emnet for å huske de mindre detaljene.
jeg har også laget en videoopplæring for dette emnet, og jeg anbefaler å se det. Klikk her for å se nå.
Brukstilfeller:
- hovedtråden I Android er bygget med en
Looper
ogHandlers
. Så forståelsen av det er viktig å skape et ublokkert responsivt BRUKERGRENSESNITT. - utviklerne som skriver biblioteker, har ikke råd til å bruke tredjepartsbiblioteker på grunn av bibliotekstørrelsen. Så for dem er det beste alternativet å utnytte den eksisterende tilgjengelige ressursen. Skrive egen løsning for det kan ikke alltid få det nivået av effektivitet og optimalisering.
- det samme argumentet kan også gjøres for bedrifter / enkeltpersoner som sender Ut Sdk-Er. Klientene kan ha varierte implementeringer, men alle vil dele de felles android framework Apier.
- Forstå dem fullt vil forbedre kapasiteten til å følge Android SDK og pakke klasser generelt.
La oss starte utforskningen/revisjonen med et spørreskjema.
jeg forventer at leseren har grunnleggende forståelse av java-tråder. Hvis du trenger, så få en rask oversikt over java Tråd og Runnable.
Hva er problemet med java-tråden?
Java-tråder er engangsbruk og dør etter å ha utført sin kjøremetode.
Kan vi forbedre det?
Tråden er et tveegget sverd. Vi kan øke hastigheten på utførelsen ved å distribuere oppgavene mellom tråder av utførelse, men kan også redusere det når tråder er i overkant. Trådopprettelse i seg selv er en overhead. Så det beste alternativet er å ha et optimalt antall tråder og gjenbruke dem for oppgaver.
Modell for gjenbruk av tråder:
- tråden holdes i live, i en løkke via den
run()
– metoden. - oppgaven utføres serielt av denne tråden og opprettholdes i en kø (MessageQueue).
- tråden må avsluttes når den er ferdig.
Hva Er Android ‘ s måte å gjøre det?
ovennevnte modell er implementert i Android via Looper
, Handler
og HandlerThread
. Systemet kan visualiseres for å være et kjøretøy som i artikkelens omslag.
-
MessageQueue
er en kø som har oppgaver kalt meldinger som skal behandles. -
Handler
enqueues oppgave iMessageQueue
brukerLooper
og utfører dem også når oppgaven kommer ut avMessageQueue
. -
Looper
er en arbeider som holder en tråd i live, går gjennomMessageQueue
og sender meldinger til den tilsvarendehandler
for å behandle. - Endelig
Thread
blir avsluttet ved å ringe Looper ‘ squit()
metode.
En tråd kan bare ha en unik Looper og kan ha mange unike Behandlere knyttet til den.
Opprette Looper og MessageQueue For En Tråd:
en tråd får en Looper
og MessageQueue
ved å ringe Looper.prepare()
etter at den har kjørt. Looper.prepare()
identifiserer kalletråden, oppretter et Looper
og MessageQueue
– objekt og knytter thread
til dem i ThreadLocal
lagringsklasse. Looper.loop()
må kalles for å starte den tilknyttede looper. På samme måte må looper
avsluttes eksplisitt gjennom looper.quit()
.
class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here // this will run in non-ui/background thread } }; Looper.loop(); } }
Opprette Handler For En Tråd:
A Handler
blir implisitt knyttet til tråden som instansierer den via trådens Looper
, men vi kan eksplisitt knytte den til en tråd ved å sende trådens looper
i konstruktøren til Handler
.
handler = new Handler() {@Overridepublic void handleMessage(Message msg) { // process incoming messages here // this will run in the thread, which instantiates it }};
Sende meldinger til MessageQueue
via Handler
kan gjøres med to moduser:
-
Message
: det er en klasse som definerer ulike nyttige metoder for å håndtere meldingsdata. For å sende et objekt setter vi obj-variabelen.
Message msg = new Message();msg.obj = "Ali send message";handler.sendMessage(msg);
Detaljert oversikt over Message
klasse finner du her: https://developer.android.com/reference/android/os/Message.html
Runnable
: en runnable kan også bli lagt ut i MessageQueue
. Eks: postering og kjøring av en oppgave i hovedtråden.
new Handler(Looper.getMainLooper()).post(new Runnable() {@Overridepublic void run() { // this will run in the main thread }});
i eksemplet ovenfor oppretter vi en Handler
og gir Looper
knyttet til hovedtråden. Dette knytter denne handler til hovedtråden. Når vi legger inn Runnable
, blir den i kø i hovedtrådens MessageQueue
og deretter utført i hovedtråden.
Handler er i stand til melding manipulasjon i en rekke måter, som kan finnes her: https://developer.android.com/reference/android/os/Handler.html
Å Lage en egen tråd og gi Lopper
og MessageQueue
er ikke den riktige måten å håndtere problemet på. Så, Android har gitt HandlerThread
(underklasse av Thread
) for å effektivisere prosessen. Internt gjør det de samme tingene som vi har gjort, men på en robust måte. Så bruk alltid HandlerThread
.
En av måtene å opprette HandlerThread er å underklasse det og mesteparten av tiden vil du bruke denne metoden.
private class MyHandlerThread extends HandlerThread { Handler handler; public MyHandlerThread(String name) { super(name); } @Override protected void onLooperPrepared() { handler = new Handler(getLooper()) { @Override public void handleMessage(Message msg) { // process incoming messages here // this will run in non-ui/background thread } }; }}
Merk: Vi har startet Behandleren når onLooperPrepared()
kalles. Så, det Handler
kan knyttes til det Looper
.
-
Looper
er bare forberedt etter At Handlerthreadsstart()
kalles dvs. etter at tråden er i gang. - a
Handler
kan knyttes til enHandlerThread
, bare etter at den erLooper
er utarbeidet.
Annen måte å opprette HandlerThread På:
HandlerThread handlerThread = new HandlerThread("MyHandlerThread");handlerThread.start();Handler handler = new Handler(handlerThread.getLooper());
Merk: HandlerThread må ringe myHandlerThread.quit()
for å frigjøre ressursene og stoppe utførelsen av tråden.
jeg vil foreslå å praktisere kodene ovenfor, slik at du kan forstå de små detaljene.
jeg har laget et eksempelprosjekt For Postkontor simulering. Postkontoret er bygget på HandlerThread Og Klienter kommunisere med Hjelp Av Postkontoret. En Simulatorklasse skaper få Klientboter og delegerer kommunikasjonen Til Hovedaktiviteten, noe som gjør den i en live feed.
lenken til Dette Eksemplet
jeg har også laget en videoopplæring for dette emnet, og jeg anbefaler å se det. Klikk her for å se nå.
La Oss også bli venner På Twitter, Linkedin, Github og Facebook.
Læring er en reise, la oss lære sammen!