Forstå Android Kjerne: Looper, Handler og HandlerThread

Forstå Android Kjerne: Looper, Handler Og HandlerThread

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:

  1. hovedtråden I Android er bygget med en Looper og Handlers. Så forståelsen av det er viktig å skape et ublokkert responsivt BRUKERGRENSESNITT.
  2. 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.
  3. 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.
  4. 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:

  1. tråden holdes i live, i en løkke via den run() – metoden.
  2. oppgaven utføres serielt av denne tråden og opprettholdes i en kø (MessageQueue).
  3. 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, Handlerog HandlerThread. Systemet kan visualiseres for å være et kjøretøy som i artikkelens omslag.

  1. MessageQueue er en kø som har oppgaver kalt meldinger som skal behandles.
  2. Handler enqueues oppgave i MessageQueue bruker Looper og utfører dem også når oppgaven kommer ut av MessageQueue.
  3. Looper er en arbeider som holder en tråd i live, går gjennom MessageQueue og sender meldinger til den tilsvarende handler for å behandle.
  4. Endelig Thread blir avsluttet ved å ringe Looper ‘ s quit() 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:

  1. 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.

  1. Looper er bare forberedt etter At Handlerthreads start() kalles dvs. etter at tråden er i gang.
  2. a Handler kan knyttes til en HandlerThread, bare etter at den er Looper 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!

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert.