HTML

HTML

A BME Távközlési és Médiainformatikai Tanszék hallgatói és oktatói blogja az Android platformról.

Facebook

Friss topikok

  • édesebb élet: www.gsmbutik.hu/sony-xperia-xz2-tukrozodes-es-uva-uvb-mentes-uvegfolia-tempered-glass (2018.05.18. 01:30) Kutatók éjszakája - 2014
  • lajthabalazs: Nem admoboztam azóta. Hétfőn lesz egy elóadás az Ericssonos Android klubbon, ahol lesz szó a témár... (2011.12.03. 07:09) Reklám-tapasztalatok
  • A Tata: szeretnék érdeklődni, hogy nem diák is jelentkezhet-e ilyen tanfolyamra; akár programozói előképze... (2011.02.03. 16:51) Újévi gyorstalpaló 2. - Adatok
  • lajthabalazs: 80 requestnél jött egy reklám, aztán semmi. Most 120 requestem volt, és két telefonon is 3G-n is ... (2011.02.02. 20:52) Don't download!
  • EvilHedgehog: Tanulságos. Ezért nem raktam én sem főzött ROM-ot a Galaxy S-re pedig csábító volt... (2011.01.29. 10:29) Softkeyboard

Linkblog

Itt a Halloween, jönnek az élőhalott Appok

2010.10.29. 21:47 lajthabalazs

Néha még a legjobb hibakezelés sem akadályozza meg, hogy kilépjünk a biztonságos állapotok teréből. A Droidfoci demón sok kellemetlenséget okozott, hogy egyes játékosokat mintha gonosz szellem szállta volna meg. Az izgalom hevében sokáig észre sem vettük, csak olyan volt, mintha laggolna a hálózat. Aztán egy nyugodtabb pillanatban sikerült izolálni a hibát.

A jelenséget röviden így lehetne leírni: a pályán két játékos áll, 1-es és 2-es. Az 1-es játékos saját karakterét irányítja. 2-es játékos saját karakterét és 1-es karakterét is irányítja. Amikor erre rádöbbentünk, azonnal kizártuk a szerver oldali hibát: az egyik játékos két játékos nevében is küldött csomagokat.

Hogy fordulhat ez elő, hiszen az alkalmazás csak egy példányban fut?! Először azt hittem, hogy azért, mert két forrásból került fel az alkalmazás, a Market-ről, és a debug linken keresztül. De ma este sikerült újra előidéznem a hibajelenséget, egyetlen kliens-példánnyal. A játékhoz csatlakozás után le kell állítani a WiFi hálózatot, majd lecsatlakozni, visszaállítani a hálózatot, és csatlakozni. A mikéntet megoldva koncentrálhattam a hogyanra. Mi történhetett az alkalmazásban, ami lehetővé tette, hogy két csomagküldő Activity fusson. Vagyis igazából tetszőleges, mivel a fenti procedúrát ismételve sikerült egy harmadik, majd egy negyedik árnyékjátékost is létrehoznom.

A socketet az onCreate() metódusban nyitottam. Tehát ennek kellett többször meghívódnia, ez alátámasztja, hogy adott aktivity-nek több példányban kellett jelen lennie. A közismert életciklus diagram alapján az onCreate csak akkor hívódik meg, ha az Activity előzőleg teljesen meghalt. Akkor viszont hogy küldözgethet a régi Activity csomagokat? Miután egy Settings/Applications/Running Applications/DroidFoci/Force Stop -pal véget vetettem a nemkívánatos viselkedének, nekiálltam kiegészíteni a kódomat, hátha megtudok valamit e misztikus hibáról. Triviális hely volt vizsgálataim kiindulópontjául az onDestroy() függvényt választani. Ami a logbejegyzéseim tanusága szerint szépen le is futott. Ennek ellenére vígan működött a DatagramSocket-em, amire egyedül a halott Activity-ben volt referencia.

No de az Activity tartalmazott egy belső osztályt! Ez az osztály regisztrálta be magát a szenzorhoz, és mint nem statikus osztály, titkon referenciát hordozot az őt tartalmazó Activity példányra. Ezért bár lefut az onDestroy, mégsem szabadul fel az Activity, és így megmaradhatott meg a Socket is.

A következő kérdés, hogy akkor miért működött egyáltalán jól az alkalmazás, ha a bezárni vélt Activity tovább folytatja a futást? Hát nem működött jól. A tanszéki tesztek során a szerver még nem használta újra az azonosítókat, így ha valaki kilépett, a háttérben hiába folytatódott az üzenetküldés, a szerver eldobta azokat, mert nem tartozott az azonosítóhoz játékos, így a csomagok észrevétlenek maradtak. Amikor az új kód a játékosok számát használta a játékos azonosítására, akkor kezdtem a számokat újrahasznosítani, hogy a demo-n ne jelenjenek meg 3 órányi futás után háromjegyű számok a játékosokon. Viszont ezt otthon csak egyedül teszteltem. Utána pedig a demo alatt nem léptünk ki a telefonokkal, jártak kézről kézre. Egészen addig, amíg a router fel nem adta. Ekkor kezdődtek a bajok, megszakadt a kapcsolat, jöttek a hibák, és kiléptünk, visszaléptünk. Néhány készülék zsebbe került a még futó szenzor-vizsgálóval. Aztán amikor kiosztották az azonosítóját, a játékos mindig leesett (értsd a pálya egyik oldalvonalán pattogott). Mivel lefele esett, azt hittük, szerverhiba, rosszul értelmezett csomag, nullával osztás, vagy valami hasonló, gyógyítás közben a zsebből valakinek odaadtuk a telefont, aki vagy játszott, vagy megölte az alkalmazást és újraindította, és a probléma megszűnt.

De mi a megoldás? Az onDestroy-ban nekünk kell bezárni a Socket-et, amit nyitottunk, igazából erre való a "Destruktor" - ami ha destruktor lenne, akkor nem is merült volna fel a hiba, vagyis nem így. Persze ezzel sem oldódik meg egészen a probléma, hiszen a szenzor-eseményre továbbra is reagál majd a View, csak nem tudja elküldeni a csomagot. Igazából ez még gonoszabb hibát eredményez, hiszen nem is látjuk, hogy halmozódnak az eseménykezelők, így sikerül memory leak-et csinálni az arra egyébként alkalmatlan Java nyelven. A View-t nem kényszeríthetjük a leiratkozásra kívülről, hiszen az objektum-orientáltságnak köszönhetően nincs ráhatásunk az objektum belső működésére.

Egyetlen lehetőségünk, hogy bízunk abban, hogy a View írója gondoskodik az eseménykezelők leregisztrálásáról. De mikor is? A View-nak nincs onDestroy függvénye. Ahhoz, hogy konzisztensek maradjunk tehát nem a konstruktorban kell jelentkeznünk eseménykezelésre, hanem az onAttachedToWindow() metódusban. És a metódus párjában, az onDetachedFromWindow()-ban kell leiratkoznunk. De elegánsabb, ha ezek után a szenzorkezelést az Activity-re bízzuk.

A fentiekből okulva holnap ki is javítom azt a fránya Ronaldo-t.

Szólj hozzá!

Címkék: eseménykezelés android activity életciklus ondetroy datagramsocket onattachedtowindow

A bejegyzés trackback címe:

https://edudroid.blog.hu/api/trackback/id/tr962408805

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása