Inzicht in Android Core: Looper, Handler, en HandlerThread

Android Core: Looper, Handler en HandlerThread

dit artikel behandelt Android Looper, Handler en HandlerThread. Deze behoren tot de bouwstenen van Android OS.

in mijn eigen ervaring heb ik ze tot voor kort in een zeer beperkte context gebruikt. Mijn use case betrof het verzenden van taken naar de main / ui thread, voornamelijk om de UI bij te werken vanaf een andere thread. De andere aspecten van de multi-threaded operatie werden behandeld via alternatieve manieren zoals ThreadPoolExecutor, IntentService, en AsyncTask.

MultiThreading en het uitvoeren van taken zijn oude onderwerpen. Java zelf heeft java.util.gelijktijdige pakket en Fork / Join framework om het te vergemakkelijken. Verschillende bibliotheken zijn geschreven om asynchrone operaties te stroomlijnen. RxJava is de meest populaire bibliotheek vandaag voor reactief programmeren en het ontwerpen van een asynchrone toepassing.

dus, waarom schrijf ik over de oude school?

Looper, Handler, en HandlerThread zijn de manier waarop Android de problemen van asynchrone programmering oplost. Ze zijn niet old school, maar een nette structuur waarop een complex android framework is gebouwd.

voor nieuwe ontwikkelaars is het sterk aanbevolen om de principes achter hen te begrijpen en ervaren moet men dit onderwerp opnieuw bekijken om de kleine details te herinneren.

ik heb ook een video tutorial gemaakt voor dit onderwerp, en ik raad ten zeerste aan om het te bekijken. Klik hier om nu te bekijken.

Use Cases:

  1. de hoofdthread in Android is gebouwd met een Looper en Handlers. Zo, het begrip ervan is essentieel om een niet-geblokkeerde responsieve gebruikersinterface te creëren.
  2. de ontwikkelaars die bibliotheken schrijven kunnen het zich niet veroorloven om bibliotheken van derden te gebruiken vanwege de grootte van de bibliotheek. Dus, voor hen, de beste optie is om de bestaande beschikbare bron te gebruiken. Het schrijven van eigen oplossing voor het kan niet altijd dat niveau van efficiëntie en optimalisatie te krijgen.
  3. hetzelfde argument kan ook worden aangevoerd voor ondernemingen / particulieren die SDK ‘ s verzenden. De klanten kunnen gevarieerde implementaties hebben, maar ze zullen allemaal de gemeenschappelijke android framework Api ‘ s delen.
  4. door ze volledig te begrijpen, zal de capaciteit om de Android SDK en pakketklassen in het algemeen te volgen, toenemen.

laten we de verkenning/revisie beginnen met een vragenlijst.

ik verwacht dat de lezer de basiskennis van java threads heeft. Als je nodig hebt, krijg dan een snel overzicht van java Thread en Runnable.

Wat is het probleem met java thread?

Java-threads worden eenmalig gebruikt en verdwijnen na het uitvoeren van de run-methode.

kunnen we dit verbeteren?

de draad is een tweesnijdend zwaard. We kunnen de uitvoering versnellen door de taken over uitvoeringsdraden te verdelen, maar kunnen het ook vertragen wanneer threads overmatig zijn. Draad creatie op zich is een overhead. Dus, de beste optie is om een optimaal aantal threads en hergebruik ze voor de uitvoering van taken.

Model voor herbruikbaarheid van draad:

  1. de thread wordt levend gehouden, in een lus via de run() methode.
  2. de taak wordt serieel uitgevoerd door die thread en wordt onderhouden in een wachtrij (MessageQueue).
  3. de thread moet worden beëindigd als u klaar bent.

Wat is de manier waarop de Android het doet?

het bovenstaande model is geïmplementeerd in de Android via Looper, Handler en HandlerThread. Het systeem kan worden gevisualiseerd als een voertuig zoals in de dekking van het artikel.

  1. MessageQueue is een wachtrij met taken genaamd berichten die moeten worden verwerkt.
  2. Handler onderzoekt taak in MessageQueue met Looper en voert deze ook uit wanneer de taak uit de MessageQueuekomt.
  3. Looper is een werkerdie een thread levend houdt, door MessageQueue loopt en berichten naar de corresponderende handler verzendt om te verwerken.
  4. uiteindelijk wordt Thread beëindigd door Looper ‘ s quit() methode aan te roepen.

een thread kan slechts één unieke Looper hebben en er kunnen veel unieke Handlers mee geassocieerd zijn.

Looper en MessageQueue aanmaken voor een Thread:

een thread krijgt een Looper en MessageQueue door Looper.prepare() aan te roepen na het draaien. Looper.prepare() identificeert de aanroepende thread, maakt een object Looper en MessageQueue aan en associeert het object thread met hen in opslagklasse ThreadLocal. Looper.loop()moet aangeroepen worden om de geassocieerde looper te starten. Op dezelfde manier moet looper expliciet worden beëindigd via 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(); } }

Handler aanmaken voor een Thread:

A Handler wordt impliciet geassocieerd met de thread die het instanteert via thread ’s Looper, maar we kunnen het expliciet aan een thread koppelen door de thread’ s looper in de constructor van de Handlerdoor te geven.

handler = new Handler() {@Overridepublic void handleMessage(Message msg) { // process incoming messages here // this will run in the thread, which instantiates it }};

het verzenden van berichten naar de MessageQueue via Handler kan op twee manieren gebeuren:

  1. Message: het is een klasse die verschillende nuttige methoden om te gaan met bericht gegevens definieert. Om een object te verzenden stellen we de OBJ variabele in.
Message msg = new Message();msg.obj = "Ali send message";handler.sendMessage(msg);

een gedetailleerd overzicht van de Message klasse is hier te vinden: https://developer.android.com/reference/android/os/Message.html

Runnable: een runnable kan ook geplaatst worden in de MessageQueue. Voorbeeld: een taak posten en uitvoeren in de hoofdthread.

new Handler(Looper.getMainLooper()).post(new Runnable() {@Overridepublic void run() { // this will run in the main thread }});

in het bovenstaande voorbeeld maken we een Handler aan en geven we Looper geassocieerd met de hoofdthread. Dit associeert deze handler met de hoofdthread. Wanneer we de Runnable plaatsen, wordt deze in de wachtrij geplaatst in de hoofd thread MessageQueue en vervolgens uitgevoerd in de hoofd thread.

Handler is in staat om bericht manipulatie op een breed scala van manieren, die hier kan worden gevonden: https://developer.android.com/reference/android/os/Handler.html

een eigen thread aanmaken en Lopper en MessageQueue opgeven is niet de juiste manier om het probleem aan te pakken. Android heeft dus HandlerThread(subklasse van Thread) geleverd om het proces te stroomlijnen. Intern doet het dezelfde dingen die wij hebben gedaan, maar op een robuuste manier. Gebruik dus altijd HandlerThread.

een van de manieren om de HandlerThread aan te maken is door het te subklassen en meestal zult u deze methode gebruiken.

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 } }; }}

opmerking: We hebben de Handler geïnstalleerd wanneer de onLooperPrepared() wordt aangeroepen. Dat Handler kan dus geassocieerd worden met dat Looper.

  1. Looper wordt alleen bereid nadat HandlerThread ‘ s start() wordt genoemd, d.w.z. nadat de thread loopt.
  2. A Handler kan worden geassocieerd met een HandlerThread, alleen nadat Looper is bereid.

andere manier om de HandlerThread aan te maken:

HandlerThread handlerThread = new HandlerThread("MyHandlerThread");handlerThread.start();Handler handler = new Handler(handlerThread.getLooper());

opmerking: HandlerThread moet myHandlerThread.quit() aanroepen om de bronnen vrij te maken en de uitvoering van de thread te stoppen.

ik stel voor de bovenstaande codes te oefenen, zodat u hun kleine details kunt begrijpen.

ik heb een voorbeeldproject gemaakt voor simulatie van postkantoren. Postkantoor is gebouwd op HandlerThread en klanten communiceren met de hulp van het postkantoor. Een Simulator klasse creëert weinig Client Bots en delegeren hun communicatie naar de hoofdactiviteit, die maakt het in een live feed.

de link naar dit voorbeeld

ik heb ook een video tutorial gemaakt voor dit onderwerp, en ik raad ten zeerste aan om het te bekijken. Klik hier om nu te bekijken.

laten we ook vrienden worden op Twitter, Linkedin, GitHub en Facebook.

leren is een reis, laten we samen leren!

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.