23D

Posts Mentioning RSS
Komentáře | Klávesové zkratky
  • Michal Gron 2:24 pm on August 4, 2010 Permalink
    Tagy: , AIR, ,   

    PMD = Project Mess Detector 

    PMD je nástroj, ktorý skenuje zdrojový kód a hľadá v ňom možné problémy ako:

    • nevhodný dizajn – prázdne try—catch—finaly/switch bloky …
    • mŕtvy kód – nepoužívané lokálne premenné, parametre a privátne metódy …
    • neoptimálny kód – nové inštancie v slučkách …
    • prekomplikované výrazy – nepotrebné if výrazy, vnorené for cykly …
    • duplicitný kód – copy-paste kód znamená copy-paste bugs

    Podľa tvorcov PMD skratka nemá žiadny význam, ale minimálne jedna výstižná sa nájde: “Project Mess Detector”.

    Prečo používať PMD?

    • S PMD dokážeme posúdiť kvalitu kódu na základe jednoduchých pravidiel. Ako povedal Tom DeMarco, “nevieme kontrolovať to čo nevieme merať”.
    • Nielen junior vývojári majú svoje drobné “zlozvyky”. PMD včas odhalí nevhodný dizajn kódu a pomože nám túto úlohu zautomatizovať.
    • PMD vie či vývojári dodržiavajú interné code guidelines a dohodnuté štandardy.

    FlexPMD

    FlexPMD je klon PMD určený pre ActionScript 3 a MXML. Okrem všeobecných PMD pravidiel obsahuje pravidlá špecifické pre Flex SDK, Cairngorm, AsDocs, MXML, Bindings, CSS, Events atď.
    FlexPMD sa dá spustiť napríklad z príkazovej riadky, Ant skriptu, Eclipse, z Mac OSX Automator alebo Maven-om (http://opensource.adobe.com/wiki/display/flexpmd/How+to+invoke+FlexPMD).
    Výsledný report s porušeniami pravidiel (súbor vo formáte XML) sa dá interpretovať viacerými spôsobmi (http://opensource.adobe.com/wiki/display/flexpmd/How+to+interpret+results):

    image

    priamo v Eclipse prostredí,

    image

    v Hudson-e

    image

    alebo v prehliadači (http://opensource.adobe.com/svn/opensource/flexpmd/bin/flex-pmd-violations-viewer.html).

    Best practices

    Zvoľte si pravidlá, ktoré vám vyhovujú

    Povolenie všetkých pravidiel spôsobí vytvorenie obrovského reportu, z ktorého veľké množstvo porušení aj tak nebude dôležitých. Prehrabávanie sa tisíckami riadkov reportu pre pár výnimiek asi čoskoro prestane baviť. Začnite s bežnými kategóriami pravidiel a neskôr pridávajte ďalšie. Šikovný nástroj od Adobe vypľuje naklikaný RuleSet: http://opensource.adobe.com/svn/opensource/flexpmd/bin/flex-pmd-ruleset-creator.html.

    Používajte IDE plugin

    Používať PMD v IDE je príjemnešie ako prepínať medzi HTML reportom a IDE tam a späť. Vo väčšine IDE, klik na výnimku v reporte spôsobí skok na konkrétny problémový riadok v kóde.

    Nesnažte sa dosiahnúť 0 výnimiek

    Snahou nie je dosiahnúť prázdny report, ten má len Chuck Norris. Vždy budú existovať v projekte výnimky, ktoré pravidlá porušia.

    Literatúra:

    1. PMD, http://pmd.sourceforge.net/
    2. FlexPMD, Adobe, http://opensource.adobe.com/wiki/display/flexpmd/FlexPMD
    3. Hudson, http://hudson-ci.org/
    4. Improving Project Quality with PMD, Tom Wheeler, http://jnb.ociweb.com/jnb/jnbJun2004.html
     
  • Michal Gron 2:51 am on July 30, 2010 Permalink
    Tagy: , AIR, ,   

    Jednotné nastavenia mxmlc kompilátora 

    Kedysi moje nastavenie vyzeralo nejako takto:

    -locale en_US 

    Po čase sa rozrástlo na:

    -locale en_US -keep-generated-actionscript -incremental -optimize=false 
    -keep-as3-metadata+=Collaborative,Keywords 
    -define=APPLICATION::debug,true -define=APPLICATION::release,false 

    Vynásobím si počet zmien za rok krát počet vývojových strojov, prirátam jeden integračný server a dostanem desiatky úprav kompilačných argumentov, desiatky duplicitných informácií, ktoré sú roztrúsené po celom development department. Každá ďalšia zmena mi pripomína, že musím napísať e-mail s oznamom o zmene, že na polovici strojov to budem musieť prísť upraviť osobne a ešte sa prihlásiť na server, nájsť všetky miesta v ant-ových skriptoch kde sa nastavujú ďalšie kompilačné parametre (unit-testy, mapy pokrytia …). Pri najlepšom je to pár hodín roboty.

    Našťastie sa to celé dá spríjemniť na jeden jediný svn commit a v budúcnosti už nemusíme nastavovať každý stroj zvlášť, základné nastavenia mxmlc budú konzistentné a my ostaneme DRY.

    1. Vytvoríme app-config.xml. Súbor kopíruje štruktúru východzieho konfiguračného súboru sdk/3.5.0.12683a/frameworks/flex-config.xml avšak nemusí byť kompletný a stačí ak bude obsahovať len nastavenia, ktoré chceme zmeniť.

    <?xml version="1.0"?>
    <flex-config>
        <
    compiler>
            <
    define>
                <
    name>APPLICATION::debug</name>
                <
    value>false</value>
            </
    define>
            <
    define>
                <
    name>APPLICATION::release</name>
                <
    value>true</value>
            </
    define>
            <
    keep-as3-metadata>
                <
    name>Bindable</name>
                <
    name>Managed</name>
                <
    name>ChangeEvent</name>
                <
    name>NonCommittingChangeEvent</name>
                <
    name>Transient</name>
                <
    name>Collaborative</name>
                <
    name>Keywords</name>
            </
    keep-as3-metadata>
            <
    keep-generated-actionscript>true</keep-generated-actionscript>
            <
    optimize>false</optimize>
            <
    incremental>true</incremental>
        </
    compiler>
    </
    flex-config

    2. Necháme si prejsť mráz po chrbte a posledný krát nastavíme na všetkých strojoch kompilačné argumenty vývojového prostredia:

    -load-config+=app-config.xml 

    3. Pri budúcej zmene kompilačných argumentov stačí editovať xml súbor a zmeny rozdistribuovať cez svn.

    Literatúra:

    1. Xavi Beumala (Technical Architect, Adobe), Streamlining your Flex project environment, http://www.adobe.com/devnet/flex/articles/flex_streamline_project_environment_print.html

     
  • Viktor Bezděk 4:00 am on November 19, 2009 Permalink
    Tagy: , AIR, , , , opaque, průhledné okno, transparent   

    Transparentní okna v AIRové aplikaci s Flex SDK 4 

    Dnes jsem potřeboval vytvořit AIRovou miniaplikaci, která má vlastní chrome, jenže WindowedApplication (respektive Window/NativeWindow) ve Flex SDK 4 nemá property backgroundAlpha. Jak tedy na transparentní pozadí?

    Řešení není nijak závratně složité. Nejdříve je třeba nastavit v AIR Application Descriptoru hodnotu systemChrome na none a transparent na true. Tohle se nijak neliší od předchozí verze SDK. Stejně jako dříve je třeba nastavit v tagu WindowedApplication několik hodnot:

    • type na NativeWindowType.LIGHTWEIGHT
    • systemChrome na NativeWindowSystemChrome.NONE
    • transparent na true
    • showStatusBar na false
    • showTitleBar na false
    • opaqueBackground na null

    Poté je třeba vytvořit nový skin pro komponentu WindowedApplication nejjednodušší řešení je udelat si kopii defaultního skinu a z ní odmazat pozadí, které tam mít nechceme. Výsledný skinClass pak vypadá zhruba takto:

    <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
        alpha.disabledGroup="0.5" >
    
        <fx:Metadata>
          [HostComponent("Object")]
        </fx:Metadata>
    
        <fx:Script>
            static private const exclusions:Array = ["backgroundRect", "bgFill", "contentGroup", "statusText"];
            override public function get colorizeExclusions():Array {return exclusions;}
        </fx:Script>
    
         <s:states>
            <s:State name="normal" />
            <s:State name="disabled" stateGroups="disabledGroup" />
            <s:State name="normalInactive" stateGroups="inactiveGroup" />
            <s:State name="disabledInactive" stateGroups="disabledGroup, inactiveGroup" />
        </s:states>
    
        <!-- layer 2: content + status bar -->
        <s:Group left="0" right="0" top="0" bottom="0" minHeight="24" minWidth="0" >
            <s:layout>
                <s:VerticalLayout gap="0"/>
            </s:layout>
    
            <!-- content -->
            <s:Group id="contentGroup" width="100%" height="100%" minHeight="0" minWidth="0"/>
    
            <!-- status bar -->
            <s:Group id="statusBar" width="100%" minHeight="24" >
                <!-- status text -->
                <s:SimpleText id="statusText" top="2" bottom="2" left="10" right="10" verticalAlign="middle"
                    fontSize="10" color="0x585858" width="100%" truncation="1" />
            </s:Group>
        </s:Group>
    
    </s:SparkSkin>

    Tento vytvořený skin pak předejte WindowedApplication a vše je hotové.

    Připomínám, že tento článek je psaný v době, kdy je Flex SDK 4 ve verzi beta 2. Ve finální verzi se může leccos změnit.

     
  • Michal Metlička 4:22 am on November 17, 2009 Permalink
    Tagy: , AIR,   

    Betaverze Adobe Flash Player 10.1 a AIR 2.0 na Labs ke stažení 


    Na Adobe Max 2009 v Los Angeles jsme představili připravované verze Flash Player 10.1 a Adobe AIR 2. Nyní konečně můžeme tyto verze poskytnout na testování i našim uživatelům a hlavně vývojářům.

    Jedná se o nesmírně významnou verzi pro Adobe. Flash Player 10.1 je první verze, která podporuje nejenom všechny tři hlavní operační systémy (je to poprvé, co uvádíme všechny 3 verze zcela simultánně), ale hlavně v rámci Open Screen Project budeme spolu s našimi partnery postupně uvádět FP 10.1 i pro mobilní telefony a další zařízení.

    Co je v Flash Player 10.1 a AIR 2.0 nového?

    • Podpora multi-touch a gest
    • Global error handler (umožňuje jednotně zpravovat a řešit všechny chyby vznikající při běhu aplikace)
    • Lokální přístup k mikrofonu (můžete nahrávat znuk z mikrofonu, aniž byste jej museli nejprve odesílat na server)
    • Podpora hardwarového dekódování videa ve formátu H.264 na platformách Windows, mobilních zařízeních nebo přenosných počítačích netbook.

    Další novinky specifické pro AIR:

    • Native process API (umožňuje aplikacím v AIR 2.0 komunikovat s jinými aplikacemi na počítači uživatele)
    • Mass Storage Device Detection (AIR 2.0 aplikace může přímo púřistupovat k datům uloženým na USB klíčence nebo na vaší videokameře)
    • Open document API (AIR aplikace má přístup k informacím o tom, jaká aplikace je přiřazena danému typu souboru a může tuto aplikaci vyvolat)
    • Vylepšená podpora sockets (rozšířené možnosti pro P2P aplikace)
    • Nová verze WebKit, která obsahuje rychlejší zpracování JavaScriptu a podporuje HTML5 a CSS3

    Chcete-li vědět více o novinkách, které tyto produkty přináší, podívejte se na stránky s funkcemi a vlastnostmi na Adobe Labs (AIR 2.0, Flash Player 10.1). Také doporučuji další weby s informacemi: Adobe TV, případně Blog Christiana Cantrella (Product Managera AIR 2.0)

    Nové betaverze se snaží zachovat maximální kompatibilitu z předchozími verzemi, ale vzhledem k tomu že se jedná o betaverze – mohou občas nastat potíže. Betaverze si můžete stáhnout zde:

    Adobe AIR2

    Adobe Flash Player 10.1

    Posted in Adobe, Flash, Obecné Tagged: Adobe, AIR, Flash
     
  • Viktor Bezděk 12:15 am on October 15, 2009 Permalink
    Tagy: , AIR, AUG, , , , , tutorial   

    Soutěž s Adobe User Group Czech o software od Adobe za $2100 – pravidla, podmínky a zadání 

    Na včerejším UG meetingu byla vyhlášena soutěz o software od Adobe za $2100. V tomto článku naleznete podrobné informace o tom, jak se soutěže zůčastnit, co se může, co se naopak nesmí a jaká jsou pravidla. Zadání je natolik volné, že se může zůčastnit téměř každý, nemeškejte tedy a ukažte co ve vás je!

    Témata soutěže

    Nemohli jsme se rozhodnout pro jedno konkrétní téma, tak jsme jich připravili hned několik,  abyste si mohli vybrat to, které vám nejvíce sedne.

    • Tutoriál
      • Může být na jakékoli téma. Jedinou podmínkou je, že musí být určený na technologie Adobe z kategorie Flash Platform. V úvahu tedy připadá Flash, Flex, Flash Catalyst, Pixel Bender apod. Samozřejmé je, že tutoriál může využívat více těchto technologií. Není přípustné, aby tutoriál byl kopie něčeho co už je na internetu.
    • Vizualizace dat či zvuku ve Flash Playeru
      • Nemyslím, že je třeba cokoli dodávat. Snad jen, že je možné využívat OpenSource frameworky, ale není přípustné modifikovat již existující vizualizaci. Pro zařazení do soutěže je nutné dát k dispozici světu zdrojové kódy.
    • Nejpůsobivější AIR aplikace
      • Autorem aplikace musíte být výhradně vy. Lze používat jakékoli frameworky. Není přípustné používat cizí kód, nebo prezentovat aplikaci vytvořenou podle tutoriálu. Pro zařazení do soutěže je nutné dát k dispozici světu zdrojové kódy.
    • Nejpůsobivější Facebook aplikace
      • Autorem aplikace musíte být výhradně vy. Lze používat jakékoli frameworky. Není přípustné používat cizí kód, nebo prezentovat aplikaci vytvořenou podle tutoriálu. Pro zařazení do soutěže je nutné dát k dispozici světu zdrojové kódy.
    • Nejpůsobivější RTMP aplikace
      • Autorem aplikace musíte být výhradně vy. Lze používat jakékoli frameworky. Není přípustné používat cizí kód, nebo prezentovat aplikaci vytvořenou podle tutoriálu. Pro zařazení do soutěže je nutné dát k dispozici světu zdrojové kódy.

    Po skončení soutěže zdrojové kódy umístíme na Google Code, kde budou zdarma k dispozici každému zájemci.

    Pravidla

    • Zúčastnit se může každý člen Adobe UG Czech. Pokud členem nejste, můžete se jím snadno stát.

    Jak bude probíhat výběr vítěze

    • Každý zůčastněný musí svou práci odevzdat do 31.12.2009
    • Ze všech odevzdaných prací vedení UG vybere 1-2 práce z každé kategorie. Jejich autory informujeme o nominaci.
    • Tyto práce se budou prezentovat na lednovém UG meetingu – pokud autor práce nebude na UG meetingu přítomen, je automaticky diskvalifikován.
    • Účastníci UG meetingu budou hlasovat, která z prací je nejlepší.
    • Autor práce s nejvíce hlasy se stane vítězem soutěže.

    Výhra

    • Výhrou je, jak již bylo několikrát zmíněno, jeden kus software od Adobe dle vlastního výběru v maximální hodnotě $2100
    • Nemůže se jednat o enterprise software (Flash Media Server, Connect Pro …)
    • Nemůže se jednat o upgrade (např. na Master Collection)
    • Výherci bude dodán emailem odkaz na stažení software a licenční číslo. Není možné dodat boxovanou verzi.

    Hotové příspěvky posílejte na  můj e-mail ja (zavinac) viktorbezdek (tecka) cz.

    Budeme se těšit s čím příjdete.

     
  • Michal Gron 12:13 pm on March 22, 2009 Permalink
    Tagy: , AIR, , ,   

    Začíname s Picasa Web API 

    Čo je to Picasa Web Albums Data API?

    Pod týmto označením sa skrýva rozhranie, ktoré umožňuje integrovať službu Picasa Web Albums (ďalej len PWA) do vašich webov a aplikácií. Rozhranie umožňuje vytvárať albumy, zasielať a sťahovať obrázky, komentáre k obrázkom a tisíc ďalších vecí.

    Niektoré z mála vecí, ktoré využívajú PWA Data API:

    • Aplikácie na jednoduché uploadovanie obrázkov zo zariadení, desktopových aplikácií a ostatných webových služieb
    • Mobilný klienti na prezeranie a uploadovanie obrázkov do PWA
    • Integrácia PWA s blogovacími nástrojmi k jednoduchému zdielaniu obrázkov na vašich blogoch
    • Digitálne foto rámiky

    Pre stručný prehľad je k dispozícii video:

    Domovská stránka PWA Data API: http://code.google.com/apis/picasaweb/

    A čo je to Picasa Flash API?

    Pod týmto názvom sa skrýva klientské rozhranie, ktoré umožňuje čo najjednoduchšie pristupovať priamo k PWA pomocou Flash Player-a. Picasa Flash API (ďalej len PFA) je read-only Actionscript 3 rozhranie k Picasa Web Albums. Umožňuje listovať v používateľských albumoch, obrázkoch, komentároch, tagoch alebo vyhľadávať obrázky v Picasa komunite.

    Domovská stránka Picasa Flash API: http://code.google.com/p/picasaflashapi/

    Aký je teda rozdiel?

    • Picasa Web Albums Data API je rozhranie k službe Picasa Web Albums od Google.
    • Picasa Flash API je Flash/Flex knižnica.
    • Pomocou Picasa Flash API posielate requesty z Flash Player-a na Picasa Web Albums Data API rozhranie.
    • Picasa Web Albums Data API žije na serverovej strane Google, Picasa Flash API beží u klienta.

    Ako s tým súvisí Picasa?

    Výborná otázka. Picasa je desktopový klient pre Mac, Linux alebo Windows. Picasa slúži na jednoduchú a rýchlu organizáciu, úpravu a odovzdávanie vašich fotografií na web. Áno, Picasa je tiež len klient (a naviac výkonný), ktorý okrem iných vlastností, možností a funkcií taktiež využíva Picasa Web Albums Data API napr. k odovzdávaniu obrázkov na web.

    Prezeranie a vyhľadávanie

    Poďme si to hneď všetko vyskúšať :). Každý url request smerom na PWA má nasledovnú schému:

    http://<api_url>/<collection_type>/<projection_type>/<context>?<parameters>

    Začnime s jednoduchým receptom - zoznamom používateľových albumov. Nato aby sme získali tento zoznam potrebujeme nasledovné ingrediencie:

    1. Adresa Picasa Web Albums Data API:

    Môžeme použiť adresu "http://picasaweb.google.com/data" alebo jej alias "http://photos.googleapis.com/data". Ja radšej používam tú druhú. Dôvodom je crossdomain.xml súbor, ktorý musí byť načítaný do Flash Player-a pred akýmkoľvek iným requestom smerom na PWA (knižnica to spraví automaticky za vás). Týmto si zabezpečíme, že PWA neodmietne našeho klienta a Flash Player spracuje PWA odpoveď. Viac k tejto téme je popísané tu. A keďže crossdomain.xml súbor sa nachádza na http://photos.googleapis.com/data/crossdomain.xml, používam radšej ten druhý tvar. Ak by sme pristupovali k PWA cez prvú adresu, môžeme listovať pomocou PFA aj privátne albumy v prípade, že sme prihlásený cez browser do google účtu, pretože koláčik obsahuje adresu http://picasaweb.google.com/data a PWA nám vráti aj naše vlastné privátne albumy.

    2. Collection type:

    Keďže PFA je read-only, budeme používať iba "/feed". Collection type "/media" by sme využili pri zápise dát z klienta smerom na server, napríklad pri aktualizácii alebo pri odovzdávaní fotografií.

    3. Projection type:

    Máme opať niekoľko možností. V prípade, že použijeme "/base", odpoveď z PWA bude základný Atom feed bez akýchkoľvek rozširujúcich elementov. Tento typ projekcie je read-only. My však chceme dostať z PWA aj dodatočné informácie o fotografiách ako napr. ich veľkosť, adresy náhľadov atď. a preto budeme používať Projection type "/api". Ak by nám Google v budúcnosti umožnil zapisovať do PWA z Flash Player-a, Projection type "/api" je nato pripravené (read-write).

    4. Context:

    Posledná prísada je hodnota, ktorá definuje aké zdroje chceme na PWA používať. Podľa tohto kontextu rozdeľujeme requesty na:

    • User-based feed: /user/<userid>
    • Contacts-based feed: /user/<userid>/contacts
    • Album-based feed: /user/<userid>/albumid/<albumid>
    • Photo-based feed: /user/<userid>/albumid/<albumid>/photoid/<photoid>
    • Community search feed: /all
    • Featured photos feed: /featured

    Po správnom zmiešaní ingrediencií pre zoznam albumov užívateľa dostaneme nasledovné url: http://photos.googleapis.com/data/feed/api/user/thisispinkfu

    PWA nám odpovie nasledovne (skrátene kvôli prehľadnosti):

    <feed ...>
        <
    id>http://photos.googleapis.com/data/feed/api/user/thisispinkfu</id>
        
    <title>thisispinkfu</title>
        ...
        <
    entry>
            <
    id>http://photos.googleapis.com/data/entry/api/user/thisispinkfu/albumid/5296410852174025857</id>
            
    ...
            <
    category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/photos/2007#album"/>
            <
    title>Pinholes</title>
            <
    summary>Sharan STD-35 and Diana pinholes</summary>
            .
            .
            .
        </
    entry>
        <
    entry>
        ...
        </
    entry>
        ...
    </
    feed
    Albumy sa vracajú späť v <entry> elementoch, kde každý <entry> element obsahuje metadáta k albumu ako napr. počet fotografií v albume, náhľad albumu, názov atď...

    Aby ste nemuseli pracne vytvárať url requesty na PWA a následne parsovať štrúdle odpovedí, pomôže vám Picasa Flash API, ktorá za vás request vytvorí, sparsuje odpoveď a vráti ju zabalenú v pekne otypovanom objekte :)

    Zoznam albumov by sme pomocou PFA získali nasledovne:

    // vytvorime instanciu servisu
    var service PicasaService = new PicasaService();

    // zavolame servisnu metodu, ktora vrati responder
    // responder vysle pri uspesnej odpovedi z PWA data event
    var responder PicasaResponder service.albums.list("thisispinkfu");
        
    responder.addEventListener(PicasaDataEvent.DATAonGetAlbumsComplete);

    // po uspesnej odpovedi
    function onGetAlbumsComplete(evt PicasaDataEvent) : void
    {
        
    var item AlbumEntry;

        
    // prejdeme vsetky <entry>
        
    for(var int 0evt.data.entries.lengtha++)
        
    {
            item 
    evt.data.entries[a] as AlbumEntry;
            
    // a vypiseme nazov albumy a jeho linku na picasaweb stranku
            
    trace(item.title.value " (" item.links[1].href ")");
        
    }
    Výstupom z funkcie je zoznam albumov s ich názvom a priamou linkou na picasaweb stránku:
    (GEThttp://photos.googleapis.com/data/feed/api/user/thisispinkfu
    Pinholes (http://picasaweb.google.com/thisispinkfu/Pinholes)
    Redscale (http://picasaweb.google.com/thisispinkfu/Redscale)
    Stockholm (http://picasaweb.google.com/thisispinkfu/Stockholm)
    Instants (http://picasaweb.google.com/thisispinkfu/Instants)
    ... 
    Ďalšími možnosti PWA je napríklad:
    • vyhľadávanie obrázkov s v komunite na základe query a napr. tagov
    • použitie geografických hraníc pre obmedzenie výsledkov vyhľadávania na určitú zemepisnú oblasť
    • limitovanie vyhľadávania na "obľúbené" fotografie

    V stručnosti sme si spravili prehľad čo je to Picasa Web Albums Data API, čo je to Picasa Flash API, načrtli sme ich možnosti a obmedzenia a vytvorili krátky príklad, ako získať zoznam všetkých albumov od Picasaweb používateľa.

    Nakoniec už len krátky odkaz na nádherný screen saver, ktorý využíva Picasa Flash API:
    http://www.inspirit.ru/exchange/ascii_saver/

     
  • Michal Metlička 3:26 pm on March 7, 2009 Permalink
    Tagy: , AIR, , Jiné blogy   

    Redesignovaný blog Toma Krchy – FlashRealtime.com 


    FlashRealtime.comVzhledem k mé dlouhé absenci budou možná mé příspěvky pro některé z vás trochu neaktuální, ale stejně chci postupně psát o událostech, které v posledních měsících proběhly a stojí za upozornění.

    Tomáš Krcha je platformním evangelistou Adobe Systems a má na starosti rozvoj developerské platformy Flash, Flex, AIR a souvisejících technologií. Na jeho blog Flashrealtime.com už odkazuji nějakou dobu, ale mezitím došlo k jeho významnému redesignu (nový design je podle mně skvělý a stojí z zhlédnutí). Tom píše o zajímavých novinkách, lidech a projektech a zaměřuje se hlavně na komunitu vývojářů. Tom patří do týmu, který má na starosti celou Evropu, takže je celkem logické, že blog přešel postupně do angličtiny.

    Další možností je sledovat portál Flashplatform.cz, který agreguje články řady významných českých vývojářů, kteří využívají technologie Adobe.

    Posted in Adobe, Flash, Jiné blogy Tagged: Adobe, AIR, Flash, Flex
     
  • Michal Gron 4:00 am on February 25, 2009 Permalink
    Tagy: , AIR, ,   

    Flex Live Event 

    Počas dvoch hodín prebehnú krátke prezentácie na tému od Flash Lite cez Flex, AIR až po Data Services. Prezentácie sú orientované ako pre začiatočníkov, tak aj pokročilých používateľov so zameraním na konkrétne využitie v praxi (best practices, case studies).

    Všetci sú srdečne pozvaní, registrácia na toto podujatie nie je potrebná.

    Viac informácií sa nachádza na stránke Slovakia FUG

     


    View Larger Map

     
  • tygl 8:30 am on December 6, 2008 Permalink
    Tagy: , AIR, , ,   

    Logování ve Flexu II. 

    Minule (Logovani ve flexu) byla popsána tvorba a princip logovacího API Flexu. Dnes navážu pokračováním v tomto tématu, konkrétně půjde o vytvoření vlastního Log Targetu. Vlastní Log Target umožňuje přizpůsobení výstupu z Logerru k obrazu svému, což je dnešním cílem.

    Než bude ukázána praktická část vytvoření a práce s vlastním Log Targetem, bylo by dobré popsat princip spoluprace mezi Loggerem a Log Targetem.

    Zprávy, které odesíláme pomocí metod poskytovaných Loggerem (debug(), info(), error(), …), jsou “vysílány” jako Event událost, konkrétně LogEvent. Aby Log Target tyto zprávy mohl přijímat, musí nastavit na daném Loggeru listener na událost LogEvent.LOG. Nastavení listeneru na tuto událost probíhá automaticky a odchycená událost je předána do metody logEvent( event:LogEvent ), která přijatou událost zpracuje, zformátuje a odešle na výstup.

    Máme tento kód:

    var logTarget:ILoggingTarget = new TraceTarget();
    logTarget.includeLevel = true;
    logTarget.includeDate = true;
    // .....
    logTarget.filters = ["my.class.foo.*"];
     
    // samotna registrace Log Targetu do spravce loggeru
    Log.addTarget( logTarget );

    Při zavolání Log.addTarget() dojde k registraci zadaného Log Targetu. Metoda addTarget() zjistí, jaké kategorie zpráv bude registrovaný Log Target přijímat. Správce Loggerů projde filtry (logTarget.filters = ["mu.class.foo.*"] ) právě registrovaného Log Targetu a porovnává je s registrem kategorií Loggerů. Pokud najde Logger, který poskytuje zprávy jež Log Target chce, zavolá Log Target a předá mu informaci o nalezeném Loggeru. Log Target na předaném loggeru nastaví výše zmíněný listener na událost LogEvent.LOG. Od této chvíle Log Target přijímá zprávy odesílané daným Loggerem.

    Vlastní Log Target

    Flex poskytuje tyto vestavěné Log Targety:

    • TraceTarget - vhodný pro základní logování, jako výstup je použita trace() konzole.
    • MiniDebugTarget - umožnuje přesměrovat výstup do jiného SWF souboru, pomocí LocalConnection.
    • LineFormattedTarget - základní Log Target, který nikam neposílá výstup a je často používán jako “taťka” pro vlastní loggery.

    LineFormattedTarget je základním stavebním kamenem při tvorbě vlastního Log Targetu. Poskytuje základní metody, potřebné pro logování událostí. Sám o sobě vychází z třídy AbstractTarget, která definuje základní metody pro správu a příjem událostí z Loggerů. Rozdíl mezi nimi je ten, že LineFormattedTarget definuje metodu, pro základní formtováný výstup, čímž nám práci ulehčí. Kdežto AbstractTarget žádný výstup nedefinuje a je nutné si výstup formátovat osobně.

    Na samotném začátku, při vytváření vlastního Log Targetu, stojíme před rozhodnutím z jaké třídy vycházet. Chceme-li pouze využít možnosti ukládání zpráv do souboru, popř. odesílání pomocí LCDS tak doporučuji vycházet z třídy LineFormattedTarget, protože pak stačí implementovat metodu internalLog(), která provádí samotný formátovaný výstup a přesměrovat na libovolný výstup.

    Pokud však máme nároky vyšší, např. chci mít vlastní vlastní výstupní formát (např. datum, čas, aj.) tak již doporučuji sáhnout po metodě AbstractTarget. Bylo by možné použít i LineFormattedTarget, ale bylo by nutné implementovat nejméně dvě metody, jednu navíc z mx_internal namespace. LineFormattedTarget přijme událost do metody logEvent, zformátuje a zavolá metodu internalLog(), která provede samotné odeslání na výstup.

    Ukázka použití LineFormattedTarget

    Zadání problému:

    Mějme AIR aplikaci a zprávy o jejím běhu chceme zaznamenávat do zadaného souboru.

    Řešení:

    Pro tento případ se hodí použití třídy LineFormattedTarget, protože nemáme žádné požadavky na formát zprávy a je tedy možné použít výchozí formátování.

    Naše třída bude vypadat např. takto:

    package
    {
        import flash.filesystem.File;
        import flash.filesystem.FileMode;
        import flash.filesystem.FileStream;
     
        import mx.core.mx_internal;
        import mx.logging.targets.LineFormattedTarget;
     
        use namespace mx_internal;
     
        public class CustomLogger extends LineFormattedTarget
        {
           private var _file:File;
           private var _fileStream:FileStream;
     
        	public function CustomLogger()
        	{
                super();
     
                // chceme logovat dotohoto souboru, musime jej tedy otevrit pro zapis
    	    _file = new File( "C:\\flexLog\\log.txt" );
                _fileStream = new FileStream();
                _fileStream.open( _file, FileMode.APPEND);
        	}
     
        	override mx_internal function internalLog(message:String):void
        	{
                // prijatou zpravu zapisujeme do souboru
                _fileStream.writeMultiByte( message + "\n", 'iso-8859-1' );
        	}
     
        }
    }

    Výstup v log souboru bude asi takovýto:

    12/6/2008 13:58:37.293 [DEBUG] my.class.logger.Main Button click
    12/6/2008 13:58:37.421 [DEBUG] my.class.logger.Main Button click
    12/6/2008 13:58:47.852 [DEBUG] my.class.logger.Main Button click

    Tímto jsme vytvořili vlastní Log Target, který si ponechává všechny možnosti nastavení a zároveň se nemusíme starat o formátování zprávy.

    Ukázka použití AbstractTarget

    Problém:

    Mějme stejné zadání z předchozí ukázky, avšak tentokrát je požadavek na formát zprávy. Zprávu je nutné zapisovat ve formátu “DATE|TIME|LEVEL|CATEGORY@MESSAGE“, protože log zprávy budou následně zpracovány jiným softwarem. Zároveň je nutné, aby byl vytvořen jedinečný soubor pro každé spuštění aplikace.

    Řešení:

    V tomto případě bude lepší jako základ použít třídu AbstractTarget, protože máme daný přesný formát zprávy a zároveň je nutné implementovat i vlastní metodu prozápis.

    Třída bude vypadat např. takto:

    package
    {
        import flash.filesystem.File;
        import flash.filesystem.FileMode;
        import flash.filesystem.FileStream;
     
        import mx.logging.AbstractTarget;
        import mx.logging.ILogger;
        import mx.logging.LogEvent;
     
        public class CustomLogger2 extends AbstractTarget
        {
           private var _file:File;
           private var _fileStream:FileStream;
     
        	public function CustomLogger2()
        	{
                super();
     
    	    _file = new File( "C:\\flexLog\\log.txt" );
                _fileStream = new FileStream();
                _fileStream.open( _file, FileMode.APPEND);
        	}
     
            /**
             * metoda, ktera zpracovava prijate LogEvent udalosti
             */
        	override public function logEvent(event:LogEvent):void
        	{
        	    var date:Date = new Date();
        	    var message:String = "";
     
        	    // vlozime datum
        	    message += Number(date.getMonth() + 1).toString() + "." +
                           date.getDate().toString() + "." +
                           date.getFullYear().toString();
     
                // separator
                message += "|";
     
                // vlozime cas
                message += padTime(date.getHours()) + ":" +
                            padTime(date.getMinutes()) + ":" +
                            padTime(date.getSeconds()) + "." +
                            padTime(date.getMilliseconds(), true);
                //separator
                message += "|";   
     
                // vlozime uroven
                message += LogEvent.getLevelString( event.level );
     
                // separator
                message += "|";
     
                // vlozime kategorii loggeru, ktery poslal zpravu
                message += ILogger( event.target ).category;
     
                // separator
                message += "@";
     
                // vlozime obsah prijate zpravy
                message += event.message;
     
                // zapiseme zformatovanou zpravu do souboru
                log( message );
        	}
     
            /**
             * metoda prevzata z LineFormattedTarget, upravuje zobrazeni vterin
             */
            private function padTime(num:Number, millis:Boolean = false):String
            {
                if (millis)
                {
                    if (num &lt; 10)
                        return "00" + num.toString();
                    else if (num &lt; 100)
                        return "0" + num.toString();
                    else
                        return num.toString();
                }
                else
                {
                    return num &gt; 9 ? num.toString() : "0" + num.toString();
                }
            }
     
            /**
             * metoda zajisti vytvoreni jedinecneho jmena souboru
             * (pro jednoduchost neresi jakekoli konflikty, ktere by mohly
             * vzniknout, pokud by se aplikace spustila 2x v ten samy cas)
             */
            private static function _createLogName():String
            {
                var date:Date = new Date();
     
                return 'log_' + date.getTime() + '.log';
            }
     
            /**
             * metoda zapisuje zpravu do log souboru
             */
            protected function log( message:String ):void
            {
                _fileStream.writeMultiByte( message + "\n", "iso-8859-1" );
            }
        }
    }

    Výstup v log souboru bude vypadat asi takto:

    12.6.2008|14:50:51.069|DEBUG|my.class.logger.Main@Button click
    12.6.2008|14:50:51.359|DEBUG|my.class.logger.Main@Button click

    Vytvořili jsme tedy Log Target, ktery zaznamenavá zprávy dle zadání.

    Závěr

    Možností jak logovat je spousta, snažil jsem se (snad úspěšně) popsat jak využít kvalitního logovacího API, které poskutuje Flex. Log Targety nejsou omezené pouze na zápis do souboru, lze taktéž data rozesílat pomocí LCDS Messaging protokolů, popř. pomocí DataServices zapisovat do databáze. Možností je spousta a je těžké je všechny obsáhnout, ale i tak doufám, že jsem poskytl základní návod, jak správně logovat.

     
  • tygl 6:30 am on December 1, 2008 Permalink
    Tagy: , AIR, , ,   

    Logování ve Flexu 

    Osobně považuji logování v aplikaci za jednu z nejdůležitějších funkcí. Logování jednotlivých akcí zpřehlední jednoduché “debugování”, popř. dokáže odhalit špatnou posloupnost akcí. Ve flashi, kde je asynchronní volání na denním pořádku se to může stát hned.

    Dříve jsem si na logování napsal vlastní třídu, jednalo se o klasický singleton, který měl pár metod, které byly převážně statické. Stěžejní metodou byla metoda “log( msg:String, level:LoggerLevelEvent )”. Z popisu je jasné, že se předávaly dva parametry. Prvním byl text zprávy, druhým úroveň, která říkala, zda jde o zprávu debug, info, error, aj. Výstup byl prováděn na klasický trace output nebo do souboru, popř. obojí. Taktéž bylo možné zprávy filtrovat, protože jsem si zavedl konvenci, že na začátku každé zprávy byl název třídy, která zprávu posílala.

    Vše fungovalo krásně, až do chvíle kdy jsem přišel na to, že jsem vynalezl kolo. Po pozdějším zjištění, hodně šišaté kolo. Místo, abych se nejdříve koukl do manuálu jsem si za par minutách napsal něco, co je už napsáno bylo. Řeč je o balíčku “mx.logging.*”. Jo, objevil jsem ameriku.

    mx.logging.*

    Nebudu zde citovat manuál balíčku mx.logging.*. Zároveň také neřeknu nic nového, co by nebylo popsáno v manuálu, konkrétně kapitola: Using the logging API.

    Stručně řečeno. Logování se dělí na tři části: “Logger -> Log Target -> Log Destination”. Flex jako takový logovací API nevyužívá, vyjímku tvoří pouze třídy: mx.rpc.*, mx.messaging.*, mx.data.* , které pomocí tohoto API zasílají informace o své činnosti.

    Logger

    Logger je v podstatě singleton, který poskytuje metody pro logování v danné kategorii. Veškeré Loggery jsou soustředěny a spravovány jednou třídou, konkrétně jde o třídu mx.logging.Log. Tato třída poskytuje rozhraní na jejich vytváření a taktéž poskytuje metody na registraci “Log targetů”.

    Chci-li získat Logger, pro vlastní kategorii, tak to vypadá asi takto:

    // definice balíčku a třídy my.class.foo.Bar
    // ....
    private var _log:ILogger = Log.getLogger('myCategory');
    //....

    Log.getLogger(’myCategory’) provede vytvoření zadané kategorie myCategory. Jako název lze volit libovolný textový řetězec, ale je dobré držet nějaký standard. Je doporučeno kategorii zadávat jako plný název třídy, napr.: my.class.foo.Bar. Na základě názvu kategorie můžeme následně logované zprávy filtrovat.

    Mám li vytvořený logger, mohu začít zasílat zprávy, např. takto:

    // definice balíčku a třídy
    // ....
    private var _log:ILogger = Log.getLogger('my.class.foo.Bar');
     
    public function Bar():void
    {
      _log.debug('In constructor.');
      initClass();
    }
     
    private function initClass():void
    {
      _log.info('InitClass');
    }
     
    private function doLogEvent( eventName:String ):void
    {
      _log.log(LogEventLevel.DEBUG, "some info from event {0}", eventName );
    }
     
    private function doError( errorMsg:String, partName:String ):void
    {
       if( Log.isError() ) {
         _log.error("Oou, we have a problem. Message: '{0}' from part: '{1}' ", errorMsg, partName );
       }
    }
    //....

    Jak je vidět, Logger poskytuje 5 základních metod a jednu obecnou metodu log(), která poskytuje možnost logovat zprávy i na vlastní úrovni.

    • info( message:String, …rest ) - odpovídá zprávě na úrovni LogEventLevel.INFO
    • debug( message:String, …rest ) - odpovídá zprávě na úrovni LogEventLevel.DEBUG
    • warn( message:String, …rest ) - odpovídá zprávě na úrovni LogEventLevel.WARN
    • error( message:String, …rest ) - odpovídá zprávě na úrovni LogEventLevel.ERROR
    • fatal( message:String, …rest ) - odpovídá zprávě na úrovni LogEventLevel.FATAL
    • log( level:Int, message:String, …rest )

    Všechny poskytované metody umožnují ve zprávách nahrazování parametrů, tj. pomocí syntaxe {x}, kde x je pořadové číslo dodatečného parametru (…rest).

    V metodě doError() je použita další vlastnost třídy Log. Použitá konstrukce zajistí to, že zpráva bude do loggeru odeslána pouze za předpokladu, že je úrověn přijímaných zpráv vyžží než úroveň danné zprávy. K dispozici jsou metody na zjištění všech stavů: isInfo(), isDebug(), isError(), isFatal(), isWarn().

    Log Target

    Zjednodušeně a ve zkratce řečeno, je to v příjemce zpráv z loggerů. Z vestavěných Log Targetů je nejpoužívanější TraceTarget, ktery jako výstup používá stejnou konzoli jako příkaz trace(). Dále pak máme k dispozici MiniDebugTarget a LineFormattedTarget (nejlepší taťka pro psaní vlastních log targetů).

    Každý Log Target umožnuje filtrovat přijímané zprávy pomocí vlastnosti filters, která jako hodnotu přijímá pole textových řetězců, které specifikují kategorie, které daný Log Target chce. Složitě řečeno, ale příklad vysvětlí.

    &lt;?xml version="1.0" encoding="utf-8"?&gt;
    &lt;mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
     creationComplete="init()"&gt;
     &lt;mx:Script&gt;
      &lt;![CDATA[
       //  .... imports ...
     
       private function init():void
       {
        var logTarget:ILoggingTarget = new TraceTarget();
     
        // chci přijímat pouze zprávy z těchto kategorií
        logTarget.filters = ["my.class.foo.*", "mx.rpc.*" ];
     
        // Vlastnost level určuje maximální úrověn přijímaných zpráv
        // Posloupnost úrovní je takováto (číslo vedle názvu vyjadřuje hodnotu úrovně):
        // LogEventLevel.FATAL (1000)
        // LogEventLevel.ERROR (8)
        // LogEventLevel.WARN (6)
        // LogEventLevel.INFO (4)
        // LogEventLevel.DEBUG (2)
        // LogEventLevel.ALL (0)
        //
        // Zprávy jsou přijímány od zadané úrovně nahoru, tj. pokud zadám:
        // logTarget.level = LogEventLevel.WARN
        // bude target přijímat pouze zprávy typu WARN, ERROR, FATAL
        //
        // V tomto případě chci přijímat všechny druhy zpráv
        logTarget.level = LogEventLevel.ALL;
     
        // jak budou jednotlivé položky odděleny, napr: datum : errorLevel : errorMessage
        logTarget.fieldSeparator = " : ";
     
        // ve zprávě chci zahrnout nazev ktergorie, ze které zpráva přišla
        logTarget.includeCategory = true;
     
        // ve zprávě chci vidět datum a čas vzniku zprávy
        logTarget.includeTime = true;
        logTarget.includeDate = true;
     
        // ve zprávě chci vidět úroveň zprávy
        logTarget.includeLevel = true;
     
        // zaregistrujeme logTarget do seznamu Loggerů
        Log.addTarget( logTarget );
     
        var myBar:Bar= new Bar();
        myBar.doLogEvent( "myClass" );
        myBar.doError( "myClass", "first" );
       }
     
      ]]&gt;
      &lt;/mx:Script&gt;
    &lt;/mx:WindowedApplication&gt;

    Výstup do konzole bude např. takovýto:

    12/1/2008 : [DEBUG] : my.class.foo.Bar : In constructor.
    12/1/2008 : [INFO] : my.class.foo.Bar : InitClass
    12/1/2008 : [DEBUG] : my.class.foo.Bar : Some info from event LogEvent
    12/1/2008 : [ERROR] : my.class.foo.Bar : Oou, we have a problem. Message: 'LogEvent' from part: 'LogEventLevel'

    Log Destination

    Poslední část je nejjednodušší. Pouze určuje, kam má Log Target odeslat formátovaný výstup přijaté zprávy. Může to být soubor, SharedObject, databáze, prostě cokoli. Toto je již v režii daného Log Targetu.

    Závěrem

    Nepopsal jsem zde úplně všechny možnosti logovacího API, ale jako základ by to mohlo stačit. Největší výhodu tohoto přístupu jsem si však nechal na později, konkrétně jde o vytvoření vlastního Log Targetu. Doufám, že popis byl srozumitelný a snad se to bude někomu hodit.

     

© 2009 Buzzboot Corp.

c
publikovat nový odkaz
j
přeskočit na další
k
předchozí
r
reagovat
e
editovat
o
zobrazit/skrýt komentáře
t
skočit nahoru
l
přihlásit se
h
zobrazit nápovědu
esc
zrušit