Přejít k navigační liště

Zdroják » Mobilní vývoj » Vyvíjíme pro Android: Epilog

Vyvíjíme pro Android: Epilog

Dnešním dílem končí seriál Vyvíjíme pro Android. Zrekapitulujeme, co jsme se naučili, opravím několik chyb z předchozích dílů a odkážu vás na další informační zdroje.

První díl seriálu Vyvíjíme pro Android, v němž jsme si nainstalovali a nastavili vývojové prostředí, vyšel 15. 6. 2012. Tehdy byla ještě nejnovější verze Androidu 4.0 Ice Cream Sandwich a nejnovější verze ADT pluginu do Eclipse byla 18.

Potom jsme se seznámili se základy vývoje, pověděli si něco o surovinách, Intentech a jednotkách a pak následoval dvojdíl o vestavěných View.

Načež jsme se od uživatelského rozhraní částečně přesunuli k různým typům ukládání dat. Nejprve to byla SQLite databáze, k níž jsme připojili fragmenty. V tomto dílu jsem také udělal první chybu, již jsem po nějaké době objevil. Po SQLite jsme se věnovali preferencím, menu a vlastnímu Adapteru. Zde jsem zapomněl přidat jeden řádek kódu. Pak jsme od ukládání dat na jeden díl odskočili k Intentům, Intent filtrům a permissions, ale jen proto, abychom si připravili půdu pro následující článek o content providerech. Tím jsme vyčerpali naši datovou sekci.

Po content providerech přišel na řadu díl, v němž jsme si vysvětlili životní cyklus activit a fragmentů a naučili se pracovat s dialogy. Ten byl následován dílem o stylování a designu.

V díle o notifikacích, broadcast receiverech a internetu jsme zužitkovali velkou část našich předchozích znalostí a vytvořili jsme reálnou aplikaci. Tu jsme potom v díle o Play Store a obecně o tom, jak dostat aplikaci mezi lidi zabalili, podepsali a nahráli na Google Play Store.

A pak už následuje dnešní díl, v němž jsem právě všechno shrnul, stručně vám povím o některých věcech, na něž nevyšlo místo, opravím dvě výše zmíněné chyby a tím seriál uzavřu.

Možná ho ale neuzavřu definitivně. V tuhle chvíli (ale znám se a mé plány podléhají větším fluktuacím než kvantová pole) předpokládám, že bych jednou za půlrok/rok napsal shrnující článek o tom, co se událo (pokud se něco událo), tedy nové verze Androidu či ADT pluginu a tak podobně, obzvláště, pokud to nějak zneplatní to, o čem jsme si v seriálu povídali.

Android

Když seriál začal, byl nejnovější verzí Androida „čtyřkový” Ice Cream Sandwich (API 15). Během těch tří měsíců stihla vyjít nová verze, Android 4.1 Jelly Bean (API 16). Z našeho pohledu asi nejzajímavější změnou byly notifikace, jimž jsme se věnovali v předminulém dílu. Dále jsem se o novinkách krátce zmínil ve článku Intenty, Intent filtry a permissions a ve zprávičce Byl představen Android 4.1 Jelly Bean.

Kromě nové verze API vyšla i nová verze ADT pluginu (a obecně SDK), aktualizovaný návod, jak založit projekt, jsem připnul ke článku o content providerech.

Vyplývá z toho to, co jsem nastínil v prvním díle, a tedy, že co vám říkám teď, nemusí být už za půl roku úplně pravda. Android je sice zpětně kompatibilní, ale aplikace napsaná pro Gingerbread vypadá na ICS prostě špatně. Pokud si píšete aplikace jen tak občas pro sebe, nemusíte to řešit. Pokud chcete vaše výtvory dát k dispozici většímu množství lidí, je potřeba změny sledovat.

Z rychlého vývoje Androidu však můžete i těžit. Pokud se dokážete dost rychle seznámit s novou verzi a přijít s funkční aplikací jí přizpůsobenou, bude to pro vás rozhodně velká konkurenční výhoda (v případě nově přidaných API dokonce přicházíte na prázdný trh).

Android každopádně není C nebo C++ (a koneckonců i Java, tam jsou tak konzervativní, až jim ujíždí vlak). Mění se nástroje, mění se samotná platforma a pokud chcete být nejlepší nebo alespoň dobří, nezbude vám, než změny sledovat.

Cílová zařízení

Píšete-li aplikaci, uvědomte si, že vaším cílovým zařízením (většinou) není jen telefon, popřípadě tablet. Android je i v televizích, ve fotoaparátech, pravděpodobně bude na Google Glass a tak dále. Hardware, na němž vaše aplikace poběží, nemusí mít vždy dotykový displej, nebo může mít ještě navíc hardwarovou klávesnici, nějaký trackball či jinou opičárnu. Bude se aplikace dobře ovládat na všech těchto rozdílných zařízeních? ( View nabízí šikovnou možnost, jak pracovat s focusem a pořadím elementů, v jakém focus dostanou.)

Testování

Ačkoli na nich běží ten stejný základ (Android), i jednotlivé androidí telefony se od sebe hodně liší. Ať už hardwarově – od (ne)přítomnosti různých vymožeností, jako je fotoaparát, hardwarová klávesnice, projektor přes senzory (gyroskop, …) až po různé typy displeje (SuperAMOLED zobrazí barvy úplně jinak než obyčejné LCD) –, či softwarově (tady můžu jmenovat různé grafické nadstavby).

Univerzální rada by byla „Kupte všechno a na všem to otestujte,” ale toho nejsou schopni ani v těch největších korporacích. Pokud pracujete jako vývojář pro Android někde ve firmě, pokuste se prosadit nákup nějakého reprezentativního vzorku androidích zařízení. Pokud jste chudí, většinou bohatě postačí i emulátor a Androidy vašich kamarádů. Myslete ovšem na rozdíly už při vývoji, a pokud je pro vás hodně důležitý design, vězte, že zelená je na některých Androidech modrá a na jiných žlutá.

Pokud máte trochu peněz, doporučuju koupit nějaký levný obyčejný, ne-příliš-výkonný tablet a nějaký levný, obyčejný ne-příliš-výkonný telefon (platí to i pro webové vývojáře). Na vašich nadupaných nejnovějších peckách hladce poběží i ta nejnáročnější aplikace. Ale vaši uživatelé budou mít mnohem levnější a obyčejnější telefony/tablety. Budou mít nižší výkon, horší displej s pomalejší odezvou, méně kvalitní fotoaparát, mizerný mikrofon a praskající reproduktor. Dobrá aplikace funguje i v takových podmínkách.

Testujte

Pokud programujete jednorázovou aplikaci, nemají testy smysl (respektive samozřejmě mají, ale obejdete se bez nich). Stejně tak u jednoduché utilitky. Ale jakmile se vám aplikace rozroste a nedejbože bude hrozit, že ji budete muset v budoucnu ještě nějak upravovat, opravdu stojí za to opatřit testy minimálně ty třídy a metody, kvůli jejichž implementaci jste museli něco studovat (teď mluvím například o různých parserech dat z internetu apod.). O testování androidích aplikací chystám článek, jednou na Zdrojáku určitě vyjde.

Hodnotné komentáře

Ačkoli to tak není vždy, když pod mými články probíhala diskuse, byla vždy k věci a velmi často hodnotná. Pokud máte s něčím problém, možná se to v diskusi už vyřešilo. A i kdyby ne, pod všemi svými články mám nastavené sledování komentářů, tak se když tak zeptejte, a pokud budu vědět, odpovím.

diskusi pod předchozím článkem se joozef zeptal na to, jak funguje zpoplatnění aplikace, dovolím si na vlákno odkázat, myslím, že je zajímavé.

Errata

Jak už jsem naznačil, vím o dvou chybách, jichž jsem se v předchozích dílech dopustil.

Ze článku Preference, menu a vlastní Adapter

Tahle chyba je triviální. Pouze jsem u třídy BookshelfActivity v metodě onDestroy() zapomněl zavolat onDestroy() rodiče. Takže stačí přidat řádek

super.onDestroy();

Ze článku Fragmenty a SQLite databáze

Stejně jako předchozí chyba pramení tato z toho, že jsem nevyzkoušel, jak se aplikace chová při změně rotace displeje. Nechtěl jsem věci ještě více komplikovat, a tak jsem vytvořil třídu SingleNoteFragment tak, že id poznámky, již má zobrazit, dostane v konstruktoru. Dokud není Activity (a tím pádem i Fragment) zničena a pak vytvořena znovu, není žádný problém. Ale ve chvíli, kdy se Android pokusí sám znovuvytvořit SingleNoteFragment, setká se s neúspěchem.

Správně by se pro nastavení všech argumentů měla použít metoda setArguments(), jež jako parametr přijímá nějaký Bundle. Ten Bundle potom získá metodou getArguments(). V praxi se, aby se Activity nemusely pokaždé potýkat s Bundly, používá statická továrnička, která převezme potřebné parametry, z nich vytvoří Bundle, vytvoří Fragment a Bundle mu předá. Správně bych měl předání argumentu v SingleNoteFragment-u řešit takto:

private static final String KEY_URI = "uri";

public static SingleNoteFragment newInstance(Uri uri) {
    Bundle bundle = new Bundle();
    bundle.putParcelable(KEY_URI, uri);

    SingleNoteFragment f = new SingleNoteFragment();
    f.setArguments(bundle);

    return f;
}

private Uri getUri() {
    return (Uri) getArguments().getParcelable(KEY_URI);
}

Konstruktor můžeme smazat, protože se používá jen ten implicitní, bez argumentů. Všechna použití instanční proměnné uri zaměníme za volání getUri() a při vytváření instance SingleNoteFragment-u použijeme místo

Fragment f = new SingleNoteFragment(uri);

následující řádek (samozřejmě s tím, že parametr uri zaměníme za parametr, který jsme předtím předávali konstruktoru):

Fragment f = SingleNoteFragment.newInstance(uri);

Android umí Bundle s argumenty uchovat, i když se instance Fragmentu dočasně zničí. Používejte tedy určitě tuto možnost.

Co se do seriálu nevešlo

Je to už asi trochu klišé, ale pro Android neexistuje (nebo já o ničem nevím) zrovna moc dobrých a přitom alespoň přiměřeně aktuálních příruček. Proto je potřeba jakýkoli průzkum začínat na stránkách Android Developers. Jak jsme ale i sami zjistili, jejich články nejsou vždy nejaktuálnější, o některých věcech se zmiňují málo a o některých se pro jistotu vůbec nezmiňují. Pokud nepomůže ani API Reference (v níž je často u třídy opravdu rozsáhlá dokumentace, ukázky kódu, vysvětlení atd., mnohdy lepší než v API Guides), nezbývá než použít Google, jestli někdo už podobný problém měl a nenapsal o něm něco někam na blog.

Velmi šikovným zdrojem bývá také Stack Overflow, které navíc, jak psal Filip Hráček, monitorují i samotní zaměstnanci Googlu. Určitě se nebojte zeptat na cokoli, pokud tedy umíte anglicky.

Docela pěkné tutoriály jsem objevil na stránkách Larse Vogely. Dokonce je zvládá mít aktualizované.

Knihy bych začátečníkům příliš nedoporučoval, neboť s tím, jak dlouho trvá vydat knihu (nedejbože přeložit ji) a jak rychle se vyvíjí Android, jsou informace v knize prakticky vždy zastaralé.

Původně jsem plánoval, že tady odkážu i na nějaký svůj blog o vývoji pro Android. Během psaní seriálu jsem i narazil na plno malých problémů, které sice nemělo smysl komponovat do článků, ale krátkou zmínku + kód by si někde na blogu určitě zasloužily. Nicméně jsem jednoduše nenašel sílu blog si naprogramovat (upravit RS ze svého Zápissníku, o němž jsem na Zdrojáku už psal), a tak jediné, co sem můžu napsat je: Možná se k blogu někdy dostanu, pokud máte zájem být upozorněni, sledujte mě na Twitteru, dejte si můj Zápissník do RSS nebo občas mrkněte na můj autorský profil tady na Zdrojáku.

Testování

Testování se velmi dopodrobna věnuje oficiální dokumentace. Vysvětluje, jak vlastně v Eclipse (i mimo Eclipse) testovat, jak vytvářet testy pro activity, services i broadcast receivery.

Debugging

Potřebujete debugovat androidí aplikaci? Některé základy už asi znáte, ale v oficiální dokumentaci je debugování věnován celý oddíl.

AVD

Android Emulator jsou mimo jiné popsány všechny klávesové zkratky, které můžete na AVD použít. Zde si dovolím některé vypsat:

Klávesová zkratka Popis
HOME Klávesa HOME emuluje telefonní tlačítko Home.
F2 Zobrazí menu.
ESC Escape znamená tlačítko zpět.
F7 F7 zastupuje vypínací tlačítko.
Ctrl+F11 Změnit orientaci displeje (přepnout na následující).
Ctrl+F12 Změnit orientaci displeje (přepnout na předchozí).
F8 Vypnout připojení k internetu, telefonní síti atd.

Best Practices

V API Guides je skrytá i kapitola Best Practices. Její články se věnují například tomu, jak vytvořit aplikaci tak, aby neměla dlouhé odezvy, bezpečnosti či obecným tipům, které by měly aplikace na Androidu dodržovat. V posledním článku je ke každému bodu i diskuse, já přeložím jen jednotlivé body (některým jsme se už věnovali):

  • Neztrácejte data, používejte onSaveInstanceState() a ostatní metody životního cyklu.
  • Pro zveřejnění dat použijte content providery.
  • Nevyrušujte uživatele, použijte notifikace.
  • Náročnější výpočty dělejte v jiném vlákně.
  • Activity není applet. Pro každý úkon mějte separátní Activity, ne jednu, která zvládne všechno.
  • Vaše styly by měly dědit od systémových motivů a stylů.
  • Vytvořte UI tak, aby fungovalo na různých displejích.
  • Předpokládejte, že internetové připojení je pomalé.
  • Nespoléhejte se na přítomnost dotykového displeje či HW klávesnice.
  • Šetřete baterii.

Závěr

Pokud jste dočetli až sem, gratuluji. Máte seriál za sebou. Zdaleka nevíte všechno, ale víte a umíte toho dost na to, abyste byli schopni vytvořit prakticky jakoukoli jednodušší aplikaci za předpokladu, že si dokážete různé případné konkrétní API najít (což určitě dokážete).

Doufám, že se vám seriál líbil a že jste se v něm něco nového naučili. Snažil jsem se psát pokud možno přístupnou formou, tak, aby i začátečník pochopil, ale zároveň aby si i pokročilejší přišli na své. Psaní mě bavilo a vážím si pozitivních reakcí a podpory, ale vážím si i veškeré konstruktivní kritiky.

Teď si na nějakou dobu dám od psaní pauzu a budu se věnovat jiným věcem, ale nemyslím, že to vydržím dlouho, a tak se těším zase brzy na Zdrojáku při dalších článcích (nejen) o Androidu na shledanou.

Tip na konec

Androidích vývojářů je v ČR málo, ale to neznamená, že o vás bude zájem, když se nikdo nedozví, že existujete. Nejlepší cesta je prostě programovat. Programujte věci, které se vám samotným hodí, i tehdy, když už něco takového existuje. Zaplaťte si vývojářský účet na Play Store a své aplikace tam nahrajte. Dejte o nich vědět, i v České republice máme internetové magazíny o Androidu (omlouvám se všem, na které jsem zapomněl). Určitě rády vydají vaši zprávičku nebo napíší recenzi vaší aplikace. A i kdyby ne, své portfolio aplikací na Play Store můžete použít jako referenci.

Pokud umíte psát, pište o Androidu. U nás (ale ono i ve světě) je takový nedostatek článků o vývoji pro Android, že se muselo vzít za vděk i těmi mými (a mnozí by to dokázali mnohem lépe, mnozí toho mnohem více vědí). Trh je tedy víceméně prázdný a je jednoduché být vidět. A když jste vidět, nabídky se určitě budou jen hrnout (tak, a teď aby to začalo platit i u mě :D).

Nejdůležitější ale je dělat to, co vás baví. Peníze pak přijdou samy.

Komentáře

Subscribe
Upozornit na
guest
17 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
Lenoch

Dobrý den, děkuji ze výtečný seriál, neuvažujete o vydání v offline verzi (např. v pdf) ?

hawran.diskuse

wget?
:-)

Přezdívka

Také bych se přimlouval za offline verzi. Bylo by to přinejmenším velmi pohodlné :)

andrej.k

aj ja dakujem za pekny serial.

j3nda

diky za serial! :) je ctitelny a vlastne me nakopl zmenit php -> javu/resp. android.

zaroven se mi zalibila zminka o vydavani obcasniku ohledne zmen na androidni scene. takze bych se primlouval za nejaky souhrn ala softwarova sklizen na rootu :D

hezky vikend. j3.

jabu

Také se přimlouvám za off-line verzi…

Raven

Také bych se přimlouval za PDF knihu.

zmt

díky :)

Thanatos

A co jako android app. Klidně bych za ní dolar či dva dal ;-)

Dr.LuckyLuke

Zdravím.

Díky za super seriál. Díky němu jsem si začal hrát s programováním na Androidu. Mám ale menší problém, snažím se psát si vlastní aplikaci na základě tohoto seriálu a trošku mě zmátlo použití Uri u SingleNoteFragment-u. Buď jsem slepý, nebo jsem to dokonale nepochopil, ale řekněte mi někdo prosím, jak z jednoduchého „long id“ mám udělat ono Uri a naopak jak si ve fragmentu zase to id vytáhnout, ať vím, která poznámka se zobrazuje.

jiri.vrany

V tomhle konrétním případě je použití Uri zbytečný overkill. Stačí aby konstruktor továrna pro SingleNoteFragment očekávala přímo kýžené id. Její definice by tedy měla vypadat cca takhle: public static SingleNoteFragment newInstance(long noteId). Do Bundle pak nevkládáme Parcelable ale přímo ten long (putLong).

Metoda getUri se pak může změnit přímo na getNoteId (pozor getId je jedna z metod fragmentu, kterou necheme přepsat). No a opět místo getParcelable použijeme getLong. No a použití je pak už jednoduché. Připadá mi, že lámat long do URI stringu a pak ho zase parsovat zpět je zbytečné.

Lukas

no, to by aj mna zaujimalo

Lukas

Ahoj
Jiri, zaujal ma tvoj prispevok, ale nie som schopny to dotiahnut do konca. Mohol by si ten kod trochu rozpisat prosim?

Pavel

Ahoj :) Seriál se mi líbil, jen občas mi nějaké věci přišli trochu zmatené kdybych je už neznal ale jinak se mi seriál velmi líbil. Jediné co sám říkáš, že se nevešlo je testování, což je škoda, protože si myslím že serial by určitě zasloužil alespoň jednu kapitolu o testovaní.

Vlado

nazdar konecne aspon niekdo kdo vysvetlil co a ako. S androidom to myslim vazne kupil som si aj knihu ale v skratke stoji za P*** vsetko robim podla tej knihy a nakoniec mi to aj tak nejde a ze ak vam to nejde pravdepodobne ste nespravili vsetko podla pokinov, tak sa vradte spet a pakujte lekciu. A ze pre zaciatocnikov :D som samouk tak je to kusa nafaka ale ako vravim fakt chvalim o/ len tak dalej

Vitek

Co se týče předávání toho id.. ano uri je zbytečné stačí nechat id, ale konstruktor nahradíme metodou newInstance, takto:

private static final String KEY_LONG = "long";
public static SingleNoteFragment newInstance(long noteId) {
    Bundle bundle = new Bundle();//vytvoříme bundle
    bundle.putLong(KEY_LONG, noteId);//předáme mu id

    SingleNoteFragment f = new SingleNoteFragment();//vytvoříme fragment
    f.setArguments(bundle);//nastavíme fragmentu bundle s id
    return f;
}

Místo metody getUri bude getNoteId:

private long getNoteId() {
    return (long) getArguments().getLong(KEY_LONG);
}//metoda pro zjištění id poznámky

Všechna použití instanční proměnné id zaměníme za volání getNoteId() a při vytváření instance SingleNoteFragment-u použijeme místo: Fragment f = new SingleNoteFragment(id); NÁSLEDUJÍCÍ:

Fragment f = SingleNoteFragment.newInstance(id);

Vitek

Jinak moc pěkný seriál děkuji autorovi. Učím se z něj :-)

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.