Az Android Core megértése: Looper, Handler és HandlerThread

Understanding Android Core: Looper, Handler és HandlerThread

ez a cikk az Android Looper, Handler és HandlerThread programokkal foglalkozik. Ezek az Android OS építőkövei közé tartoznak.

saját tapasztalataim szerint a közelmúltig nagyon korlátozott kontextusban használtam őket. A használati esetem során feladatokat küldtem a fő / ui szálra, elsősorban a felhasználói felület bármely más szálból történő frissítésére. A többszálú működés egyéb aspektusait alternatív módon kezelték, mint például a ThreadPoolExecutor, az IntentService és az AsyncTask.

a MultiThreading és a task running Régi témák. Maga a Java rendelkezik java-val.util.egyidejű csomag és Fork / Join keretrendszer annak megkönnyítése érdekében. Számos könyvtárat írtak az aszinkron műveletek egyszerűsítésére. RxJava a legnépszerűbb könyvtár ma reaktív programozás és tervezése egy aszinkron alkalmazás.

szóval, miért írok a régi iskoláról?

Looper, Handler, a HandlerThread pedig az Android módja az aszinkron programozás problémáinak megoldására. Nem régi iskola, hanem egy ügyes struktúra, amelyre egy összetett android keret épül.

az új fejlesztők számára erősen ajánlott megérteni a mögöttük álló elveket, és a tapasztalt embereknek újra meg kell vizsgálniuk ezt a témát, hogy emlékezzenek a kisebb részletekre.

én is létrehozott egy videót bemutató ebben a témában, és én nagyon ajánlom, hogy nézd meg. Kattintson ide a megtekintéshez.

Használati Esetek:

  1. az Android fő szála Looperés Handlers. Tehát a megértése elengedhetetlen egy nem blokkolt reszponzív felhasználói felület létrehozásához.
  2. a könyvtárakat író fejlesztők a könyvtár mérete miatt nem engedhetik meg maguknak, hogy harmadik féltől származó könyvtárakat használjanak. Tehát számukra a legjobb megoldás a meglévő rendelkezésre álló erőforrás felhasználása. A saját megoldás írása nem mindig kapja meg ezt a hatékonyságot és optimalizálást.
  3. ugyanez az érvelés az SDK-kat szállító vállalatok/magánszemélyek esetében is megfogalmazható. Az ügyfelek változatos implementációkkal rendelkezhetnek, de mindegyikük megosztja a közös android keretrendszer API-kat.
  4. ezek teljes megértése növeli az Android SDK és a csomagosztályok általános követésének képességét.

kezdjük a feltárást/felülvizsgálatot egy kérdőívvel.

elvárom, hogy az olvasó az alapvető ismereteket a java szálak. Ha szüksége van, akkor kap egy gyors áttekintést java szál és futtatható.

mi a probléma a java szál?

a Java szálak csak egyszer használhatók, és a futtatási módszer végrehajtása után elpusztulnak.

tudunk javítani rajta?

a szál kétélű kard. Felgyorsíthatjuk a végrehajtást azáltal, hogy a feladatokat elosztjuk a végrehajtás szálai között, de lelassíthatjuk azt is, ha a szálak meghaladják. A szál létrehozása önmagában egy felső. Tehát a legjobb megoldás az, ha optimális számú szálat használunk, és újra felhasználjuk őket a feladatok végrehajtásához.

modell a menet újrafelhasználhatóságához:

  1. a szál életben marad, egy hurokban a run() módszerrel.
  2. a feladatot az adott szál sorozatosan hajtja végre, és egy sorban (MessageQueue) tartja fenn.
  3. a szálat le kell állítani, ha kész.

mi az Android módja ennek?

a fenti modell végre az Android via Looper, Handler, és HandlerThread. A rendszer megjeleníthető, hogy jármű legyen, mint a cikk borítóján.

  1. MessageQueue egy sor, amely feladatokat nevezett üzeneteket kell feldolgozni.
  2. Handler enqueues feladat a MessageQueue segítségével Looperés végrehajtja őket, amikor a feladat jön ki a MessageQueue.
  3. Looper egy munkás, amely életben tartja a szálat, hurkol a MessageQueue – en keresztül, és üzeneteket küld a megfelelő handler – nek a feldolgozáshoz.
  4. végül Thread megszűnik a Looper quit() metódusának meghívásával.

egy szálhoz csak egy egyedi hurok tartozhat, és sok egyedi kezelő társítható hozzá.

Looper és MessageQueue létrehozása egy szálhoz:

egy szál Looper és MessageQueue számot kap a Looper.prepare() meghívásával a futtatása után. Looper.prepare() azonosítja a hívó szálat, létrehoz egy Looper és MessageQueue objektumot, és társítja a thread – et velük a ThreadLocal tárolási osztályban. Looper.loop() meg kell hívni, hogy indítsa el a kapcsolódó looper. Hasonlóképpen, a looper – et kifejezetten a looper.quit() – on keresztül kell befejezni.

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

kezelő létrehozása egy szálhoz:

a Handler implicit módon kapcsolódik ahhoz a szálhoz, amely a szál Looper – en keresztül példányosítja, de kifejezetten egy szálhoz köthetjük, ha átadjuk a szál looper – ét a Handler konstruktorában.

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

üzenetek küldése a MessageQueue keresztül Handler lehet tenni két mód:

  1. Message: ez egy osztály, amely különféle hasznos módszereket határoz meg az üzenetadatok kezelésére. Egy objektum elküldéséhez az obj változót állítjuk be.
Message msg = new Message();msg.obj = "Ali send message";handler.sendMessage(msg);

a Message osztály részletes áttekintése itt található: https://developer.android.com/reference/android/os/Message.html

Runnable: a futtatható is írt a MessageQueue. Például: feladat feladása és futtatása a fő szálban.

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

a fenti példában létrehozunk egy Handler – et, és megadjuk a fő szálhoz társított Looper – et. Ez társítja ezt a kezelőt a fő szálhoz. Amikor elküldjük a Runnable – et, a fő szál MessageQueue – jében sorba kerül, majd végrehajtja a fő szálban.

a kezelő sokféle módon képes az üzenetek manipulálására, ami itt található: https://developer.android.com/reference/android/os/Handler.html

saját szál létrehozása és a Lopper és a MessageQueue megadása nem a megfelelő módszer a probléma kezelésére. Tehát az Android a HandlerThread(Thread alosztálya) biztosítja a folyamat egyszerűsítését. Belsőleg ugyanazokat a dolgokat teszi, mint mi, de robusztus módon. Tehát mindig használja a HandlerThreadértéket.

a HandlerThread létrehozásának egyik módja az alosztályozás, és legtöbbször ezt a módszert fogja használni.

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

megjegyzés: a kezelőt a onLooperPrepared() meghívásakor példányosítottuk. Tehát, hogy Handlerlehet társítani, hogy Looper.

  1. Looper csak a HandlerThread start() meghívása után készül, azaz a szál futása után.
  2. a Handler társítható a HandlerThread – hoz, csak a Looper elkészítése után.

a HandlerThread létrehozásának másik módja:

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

Megjegyzés: HandlerThread kell hívni myHandlerThread.quit(), hogy felszabadítsa a forrásokat, és állítsa le a végrehajtását a szál.

azt javaslom, hogy gyakorolja a fenti kódokat, így megértheti az apró részleteket.

létrehoztam egy Példaprojektet a Posta szimulációjához. Posta épül HandlerThread és az ügyfelek kommunikálni segítségével a Posta. A szimulátor osztály létrehoz néhány kliens botok és delegálni a kommunikációt a MainActivity, amely teszi, hogy egy élő takarmány.

a link erre a példára

én is létrehozott egy videót bemutató ebben a témában, és én nagyon ajánlom, hogy nézd meg. Kattintson ide a megtekintéshez.

legyünk barátok a Twitteren, a Linkedin-en, a Githubon és a Facebook-on is.

a tanulás egy utazás, tanuljunk együtt!

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.