Fejlett Webes Technológiák II.

Slides:



Advertisements
Hasonló előadás
© Kozsik Tamás Különböző nyelvekhez igazítás Internationalization - i18n.
Advertisements

4. alkalom – Hálózat Kezelés
II. Grafikus felhasználói interfész
C++ programozási nyelv Gyakorlat hét
Programozás III KOLLEKCIÓK 2..
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Adatbányászati technikák (VISZM185)
Öröklődés 2..
© Kozsik Tamás Tömbök, kollekciók és egyéb alaposztályok.
© Kozsik Tamás Beágyazott osztályok A blokkstrukturáltság támogatása –Eddig: egymásba ágyazható blokk utasítások Osztálydefiníciók is egymásba.
© Kozsik Tamás Párhuzamosság A program egyszerre több mindent is csinálhat Lehetőségek: –Számítással egyidőben IO –Több processzor: számítások.
Bevezetés a Java programozásba
Öröklődés Polimorfizmus Csomagok Absztrakt osztályok, interfészek
Fájlkezelés, IO Kivételkezelés Belső osztályok
Osztályok Garbage collection.  általában minden osztálynak vannak adattagjai és/vagy metódusai ◦ adattagok megadása:  [láthatóság] [static] [final]
Vizuális modellezés Uml és osztálydiagram UML eszközök
Abstract osztályok és interface-ek Beolvasás és kiíratás 7. gyakorlat.
Ez a dokumentum az Európai Unió pénzügyi támogatásával valósult meg. A dokumentum tartalmáért teljes mértékben Szegedi Tudományegyetem vállalja a felelősséget,
Programozás II. 3. Gyakorlat C++ alapok.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 6. Gyakorlat const, static, dinamikus 2D.
Fejlett Programozási Technológiák II. Világos Zsolt 12. gyakorlat.
Fejlett Programozási Technikák 2.
Tömbök ismétlés Osztályok Java-ban Garbage collection
Az objektum-orientált tervezési alapelvek kritikai vizsgálata
A Java programozási nyelvSoós Sándor 1/17 Java programozási nyelv 4. rész – Osztályok II. Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai.
A Java programozási nyelvSoós Sándor 1/16 Java programozási nyelv 6. rész – Java a gyakorlatban Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai.
Java programozási nyelv 3. rész – Osztályok I.
A C++ programozási nyelvSoós Sándor 1/12 C++ programozási nyelv Gyakorlat - 8. hét Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet.
Java programozási nyelv 5. rész – Osztályok III.
Csomagok.
© Kozsik Tamás Csomagok. © Kozsik Tamás A program tagolása Típusdefiníciók (osztályok, interfészek) Metódusok Blokk utasítások Csomagok.
A Q-learning módszer alkalmazása NXT robotok irányítására.
Kivételkezelés.
P ROGRAMOZÁS C# - BAN Kivételkezelés. P ÉLDA I. Nullával való osztás miatt kapjuk a hibaüzenetet.
Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
1 Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
Léczfalvy Ádám MIDlet-ek.
A PHP 5 újdonságai Az OOP terén. Miről lesz szó? Osztályok kezelése – Új direktívák – Konstruktor – Destruktor Interfészek Kivételkezelés.
Hernyák Zoltán Programozási Nyelvek II.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
Java programozási nyelv Filekezelés
Java programozási nyelv Metódusok
Java programozási nyelv Adatbekérés konzolról
Generics Krizsán Zoltán. Bemutató A.NET 2.0 verziótól. A.NET 2.0 verziótól. Típusparaméter Típusparaméter Más nyelvben ez a template (sablon). Más nyelvben.
CUDA C/C++ programozás
Programozás III KIVÉTEL – CSOMAG. CSOMAGOK Az összetartozó osztályok és interfészek egy csomagba (package) kerülnek. A Java is csomagok halmaza: csomagokban.
Programozás III KOLLEKCIÓK.
Programozás III CSOMAG. CSOMAGOK Az összetartozó osztályok és interfészek egy csomagba (package) kerülnek. A Java is csomagok halmaza: csomagokban van.
Vizualizáció és képszintézis Sugárkövetés (Dart + GLSL) Szécsi László.
1Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Programozás I. 6. gyakorlat.
1Szegedi Tudományegyetem Természettudományi és Informatikai KarAntal Gábor Programozás I. 4. gyakorlat.
TÁMOP /1-2F JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam Osztályok, objektumok definiálása és alkalmazása. Saját.
Krizsán Zoltán, iit C# osztályok 2 Adattagok  Osztály hatáskörben definiált változó.  Formája: [attribútum] [módosító] típus azonosító [=kezdő érték][,
Párhuzamos programozás
a programegységek között
Algoritmusok és Adatszerkezetek I.
Hálózatkezelés Java-ban
Ghost Hunter Game logic/HUD.
Fejlett Webes Technológiák II.
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
Fejlett Webes Technológiák II.
B M Java Programozás 1. Gy: Java alapok IT A N Ismétlés ++
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
Thread és Task.
B M Java Programozás 5. Gy: Java alapok IT A N Adatkezelő 1.rész
Fejlett Webes Technológiák II.
Konverziós operátorok
Előadás másolata:

Fejlett Webes Technológiák II. Bilicki Vilmos 2002.10.28

A mai előadás tartalma: Hatékony MIDP programozás Mintaalkalmazás: Akvárium (véletlen számok, szálak, grafika)

Hatékony MIDP programozás Végrehajtás sebessége JAR fájl mérete Erőforrás használat Tapasztalt sebesség (felhasználó akció kezelés)

Végrehajtási sebesség Program végrehajtási sebesség Hálózati sebesség

Program végrehajtási sebesség A program idejének 90%-át kódjának 10%-ában tölti. Célszerű az egész kód optimalizálása helyett a gyenge pontokat felfedni Gondos tervezés és algoritmus választás nagyobb előnnyel jár mint a soronkénti optimalizálás Java programok több időt töltenek a könyvtári kódok végrehajtásával mint saját kódunk végrehajtásával (Telefon típusonként, verziónként különböző lehet a végrehajtási idő)

Program végrehajtási sebesség Mérése: Az emulátor-ban futó program máshogy viselkedhet mint a valós környezetben futó. Általános módszer: long startTime = System.currentTimeMillis(); doSomething(); long timeTaken = System.currentTimeMillis() - startTime; A zavaró hatások elkerülése érdekében érdemes lefuttatni a mérések előtt a szemétgyűjtőt: System.gc(); A telefon által szolgáltatott idő nem feltétlenül milliszekundum !

Program végrehajtási sebesség Grafikai műveletek: A magas szintű grafikai elemekkel nem kell foglalkoznunk. Foglalkoznunk kell viszont a Canvas osztállyal. (telefon, verzió függő) Általában több száz sort vagy téglalapot írhatunk a képernyőre másodpercenként. Célszerű csak azt a képernyő részt újrarajzolni amelyet frissíteni kell: Canvas.repaint(int x, int y, int width, int height); Általánosan használt eljárás ha a képernyő frissítés lassú: a memóriába rajzolunk és csak a végén tesszük ki a képernyőre (a szükséges területet)

Program végrehajtási sebesség Szemét gyűjtés: Ne hozzunk létre feleslegesen sok objektumot, próbáljuk a már meglévőket újrahasznosítani. Megváltoztathatatlan (immutable) objektumok problémája: Fontosak a kód megbízhatósága szempontjából Gyorsan feleslegessé válhatnak (nem adhatunk nekik új értéket) Hatékonyabb megváltoztatható objektumokat használni

Példa static String reverse(String s) { String t = ””; for(int a=s.length()-1;a>=0;a--) t += s.charAt(a); } return t;

Program végrehajtási sebesség Mivel a String objektum immutable minden egyes betű hozzáadás új objektumot hoz létre ! Érdemes a StingBuffer objektumot használni !

Példa static String reverse(String s) { StringBuffer t = new StringBuffer(s.length()); for(int a=s.length()-1;a>=0;a--) t.append(charAt(a)); } return t.toString();

Program végrehajtási sebesség Többszálúság: Segítségével meggyorsíthatjuk programunk futási sebességét (amíg az egy szál várakozik valamire a másik dolgozhat) Nincs garancia a preemtív multitaszking-ra ! Nekünk kell olyan programot írnunk amely nem önző (yield(), wait())

Példa try { while(!stopped) try{ doSomething(); synchronized(this) wait(500); } catch(InterruptedException e)

Program végrehajtási sebesség Hálózati sebesség Átviteli sebessége (nagy mennyiségű adatnál érdekes) Késleltetés (kis mennyiségű adatnál érdekes)

Program végrehajtási sebesség Nagy késleltetés (akár százszorosa a vezetékes hálózaténak (x ms)) Nehéz a valós idejű játékokat írni (vagy lehetetlen) Mindenképpen külön szálnak kell kezelnie a hálózatot A HTTP kérések számát minimalizálni kell (a weblapon lévő összes elemet egyszerre kell kérnie)

Program végrehajtási sebesség Ne használjunk komplex redundáns protokollokat (SOAP) Esetenként célszerű saját egyszerű protokollt használni (verzió!!)

JAR fájl mérete Miért kell csökkenteni a méretét? Gyorsabban letölthető (kb 1 másodperc kbyte-onként) Felső méret korlát 30 kbyte Az általánosan használt telefonok korlátos tárolási kapacitással rendelkeznek (180 kbyte) A felhasználók szeretnek egyszerre több programot is tárolni, használni

JAR fájl mérete Hogyan csökkentsük? Minden osztály saját fejléccel rendelkezik Minél kevesebb osztályt használni Egy osztály dolgonként (nem kell a MVC architektúrát megvalósítatnunk) Minél kevesebb interfészt használjunk (osztályként tárolódik) Névtelen csomagok használata – minden osztályunkat egy azonos nevű csomagba helyezve csak növeli a JAR fájl méretét Korlátozzuk a static elemeket – tárolása több helyet foglal mint a normál elemeké

JAR fájl mérete Használjunk Obfuscator programokat Módosítják a lefordított Java programot, hogy kiszűrjék a szükségtelen információkat (hosszú metódus, változó nevek …) Érthetetlenné teszik lefordított kódunkat Kb. 10% méretcsökkenés érhető el!

JAR fájl mérete Könyvtárak (libraries) Normál szoftver fejlesztésnél a gyakran használt dolgokat célszerű könyvtárakként megvalósítani. Itt nem célszerű követnünk ezt a módszert (a könyvtárak tárolása miatt). Célszerűbb a cut&paste módszer használata (JAR fájl tömörítve)

JAR fájl mérete Erőforrások: PNG képek Mérete jelentősen eltérhet a különböző eszközöknél ! Képek kombinálása egy fájlba (hatékonyabb tömörítés) g.setClip(x, y, FRAME_WIDTH, FRAME_HEIGHT); g.drawImage(fiveMenImage, x - FRAME_WIDTH * frameNumber, y, Graphics.TOP|Graphics.LEFT); frameNumber {0,1,2,3,4,3,2,1}

Erőforrások kezelése Heap memória A nem használt objektumokat szabadítsuk fel Csak akkor hozzuk létre a ritkán használt objektumokat amikor használjuk (Help screen) Figyeljünk oda a memória szivárgásra (nem használjuk az objektumot, de még van rá mutató referencia) NULL !

Erőforrások kezelése Hálózat kezelés: Csak akkor használjuk ha mindenképpen szükséges (ne küldjünk akkor is csomagokat ha nem változott semmi) Próbáljuk az események menetét megjósolni és csak akkor küldjünk csomagot ha a változás nem számításaink szerint következik be.

Érzékelt sebesség Mindég jelezzük a felhasználónak azt, hogy a MIDlet működik (hosszú számítás, hálózati kapcsolat, …) Reakcióidő, amíg a felhasználónak várakoznia kell a reakcióra. Nem szabad egy másodpercnél hosszabbnak lennie. megszakítható szálak használata (Cancel gomb) jelzés a felhasználónak arról, hogy valami történik

Érzékelt sebesség A késleltetések elrejtése splash screen alkalmazása (pl forgó fogaskerekek, …)

FishTank Nokia UI API használata UI transzparens képek képek manipulálása UI egy képernyő

Felépítése

Működése FishTankCanvas mint UI Elkülönített animáló szál (tick()) A mélység 5 szintre van osztva 0 a legközelebbi, 4 a legtávolabbi Három halfajta mely a Fish objektum létrehozásánál véletlenszerűen dől el. A halak véletlenszerűen mozognak Ha elérik az akvárium szélét akkor megfordulnak (Nokia UI API) A vízinövények az akvárium alján vannak, három különböző minta lehetséges. Minden bokor önállóan animált.

package example.fishtank; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class FishTankMIDlet extends MIDlet { private final FishTankCanvas canvas; public FishTankMIDlet() { canvas = new FishTankCanvas(this); } public void startApp() Display.getDisplay(this).setCurrent(canvas); canvas.start(); } public void pauseApp() { canvas.stop(); } public void destroyApp(boolean unconditional) void exitRequested() destroyApp(false); notifyDestroyed();

import javax. microedition. lcdui. ;import java. util import javax.microedition.lcdui.*;import java.util.Vector;import com.nokia.mid.ui.*; public class FishTankCanvas extends FullCanvas implements Runnable { static final int NUM_PLANES = 5; private static final int WEEDS_PLANE = 2; private static final int MILLIS_PER_TICK = 100; static int waterWidth, waterHeight; private final FishTankMIDlet parent; private final Vector fishes = new Vector(); private final Weeds weeds; private volatile Thread animationThread = null; public FishTankCanvas(FishTankMIDlet parent) this.parent = parent; waterWidth = getWidth(); waterHeight = (getHeight() * 15) / 16; weeds = new Weeds(); int numFishes = (waterWidth * waterHeight) / (35 * 35); if (numFishes > 20) { numFishes = 20; } for (int i = 0; i < numFishes; ++i) { fishes.addElement(new Fish()); } }

synchronized void start() { animationThread = new Thread(this); animationThread.start(); } synchronized void stop() { animationThread = null; } public void run() { Thread currentThread = Thread.currentThread(); try { while (currentThread == animationThread) { long startTime = System.currentTimeMillis(); tick(); repaint(0, 0, waterWidth, waterHeight); serviceRepaints(); long timeTaken = System.currentTimeMillis() - startTime; if (timeTaken < MILLIS_PER_TICK) synchronized (this) { wait(MILLIS_PER_TICK - timeTaken); } } catch (InterruptedException e)

private synchronized void tick() { for (int i = 0; i < fishes.size(); ++i) { Fish fish = (Fish)(fishes.elementAt(i)); fish.tick(); } } public void paint(Graphics g) { drawFishTank(g); } private synchronized void drawFishTank(Graphics g) { g.setColor(0, 255, 255); g.fillRect(0, 0, waterWidth, waterHeight); g.setColor(255, 128, 64); g.fillRect(0, waterHeight, waterWidth, getHeight()); for (int plane = 0; plane < NUM_PLANES; plane++) if (plane == WEEDS_PLANE) { weeds.draw(g); } for (int i = 0; i < fishes.size(); i++) Fish fish = (Fish)(fishes.elementAt(i)); if (fish.getZ() == plane) { fish.draw(g); }

public class Fish { private static final int TYPE_NUM = 3; private static final int FRAME_NUM = 2; private static final Image[][] fishImage; private static final int fishWidth, fishHeight; private static final Random random = new Random(); private final int type; private int frame; private int x, y, z; private int vx, vy; private int ticksSinceLastChangeX = 0; private int ticksSinceLastChangeY = 0; private int ticksSinceLastChangeD = 0; static { fishImage = new Image[TYPE_NUM][FRAME_NUM]; int i = 0; int k = 0; try for (i = 0; i < TYPE_NUM; i ++) for (k = 0; k < FRAME_NUM; k ++) { fishImage[i][k] = Image.createImage("/fish" + i + k + ".png"); } } catch (java.io.IOException e) { fishImage[i][k] = null; } fishWidth = fishImage[0][0].getWidth(); fishHeight = fishImage[0][0].getHeight();

public Fish() { type = rand(TYPE_NUM); frame = rand(FRAME_NUM); x = rand(FishTankCanvas.waterWidth - fishWidth); y = rand(FishTankCanvas.waterHeight - fishHeight); vx = rand(2) * 2 - 1; // -1 or 1 vy = rand(3) - 1; // -1, 0 or 1 z = rand(FishTankCanvas.NUM_PLANES); }

public void tick() { ticksSinceLastChangeX++; ticksSinceLastChangeY++; ticksSinceLastChangeD++; if ((ticksSinceLastChangeX > 20) && (rand(20) == 0)) vx = rand(2) * 2 - 1; // -1 or 1 ticksSinceLastChangeX = 0; } if (((vx < 0) && (x + vx < 0)) || ((vx > 0) && (x + fishWidth + vx > FishTankCanvas.waterWidth))) vx = -vx; ticksSinceLastChangeX = 0; if ((ticksSinceLastChangeY > 20) && (rand(20) == 0)) vy = rand(3) - 1; // -1, 0 or 1 ticksSinceLastChangeY = 0; if (((vy < 0) && (y + vy < 0)) || ((vy > 0) && (y + fishHeight + vy > FishTankCanvas.waterHeight))) if (rand(2) == 0) { vy = -vy; } else { vy = 0; }

if ((ticksSinceLastChangeD > 10) && (rand(10) == 0)) { z += rand(3) - 1; // -1, 0 or 1 if ((z < 0) || (z == FishTankCanvas.NUM_PLANES)) if (rand(2) == 0) z = (z < 0) ? 0 : z - 1; } else z = (z < 0) ? 1 : z - 2; ticksSinceLastChangeD = 0; x += vx; y += vy;

public void draw(Graphics g) { DirectGraphics dg = DirectUtils.getDirectGraphics(g); Image img = fishImage[type][frame]; if (img != null) if (vx < 0) dg.drawImage(img, x, y, (Graphics.LEFT | Graphics.TOP), DirectGraphics.FLIP_HORIZONTAL); } else dg.drawImage(img, x, y, (Graphics.LEFT | Graphics.TOP), 0); frame = (frame + rand(2)) % FRAME_NUM; int getZ() { return z; } static int rand(int scale) { return (random.nextInt() << 1 >>> 1) % scale; }

public class Weeds { private static final int PATTERN_NUM = 3; private static final int FRAME_NUM = 4; private static final Image[][] weedImage; private static final Random random = new Random(); private static final int weedHeight, weedWidth; private final int weedBunches; private final int frame[]; private final int pattern[]; private final int y; static { weedImage = new Image[PATTERN_NUM][FRAME_NUM]; int i = 0; int k = 0; try for (i = 0; i < PATTERN_NUM; i ++) for (k = 0; k < FRAME_NUM; k ++) { weedImage[i][k] = Image.createImage("/weed" + i + k + ".png"); } } catch (java.io.IOException e) { weedImage[i][k] = null; } weedWidth = weedImage[0][0].getWidth(); weedHeight = weedImage[0][0].getHeight();

public Weeds() { weedBunches = (FishTankCanvas.waterWidth - 1) / weedWidth + 1; pattern = new int[weedBunches]; frame = new int[weedBunches]; for (int i = 0; i < weedBunches; i ++) { int patternNum = Fish.rand(PATTERN_NUM); while ((i > 0) && patternNum == pattern[i-1]) { patternNum = Fish.rand(PATTERN_NUM); } pattern[i] = patternNum; frame[i] = Fish.rand(FRAME_NUM); } y = FishTankCanvas.waterHeight - weedHeight + 2; public void draw(Graphics g) Image img = null; for (int i = 0; i < weedBunches; i++) img = weedImage[pattern[i]][frame[i]]; if (img != null) g.drawImage(img, i * weedWidth, y, Graphics.LEFT | Graphics.TOP); frame[i] = (frame[i] + 1) % FRAME_NUM; } }}

Forrás: http://www.forum.nokia.com/main/1,35452,1_0,00.html