Image
29.6.2016 0 Comments

Programujeme pre Android /7.časť

V tejto časti seriálu sa zameriame na implementáciu tzv. poskytovateľov, resp. vyhodnocovačov obsahu (content providers, resolvers) a takisto komponentov (tried), ktoré s nimi určitým spôsobom súvisia. Pretože používanie výrazov poskytovateľ, resp. vyhodnocovač môže viesť k istým nejasnostiam, v našich článkoch budeme používať ich anglické ekvivalenty. Provider a ďalšie nevyhnutné triedy zahrnieme do vzorovej aplikácie planovac_v2.

planovac_v2

Na obr. 1 je zobrazený grafický výstup aplikácie planovac_v2 v porovnaní s výstupom predchádzajúcej verzie. Aj napriek tomu, že rozdiely grafických výstupov sú zanedbateľné, štruktúra zdrojového kódu oboch aplikácií sa v mnohom odlišuje (obr. 2). Hlavným dôvodom zmien bola implementácia providera na prístup k databáze. Táto zmena si následne vynútila zmeny ostatných častí pôvodného kódu vrátane reštrukturalizácie a umiestnenia kódu jednotlivých tried do nových balíčkov contentprovider a database.

Grafický výstup aplikácií planovac_v1 a planovac_v2 (jediný viditeľný rozdiel je označený červenou)

dB_helper.java - SQLiteOpenHelper - contract classes

Jedna z čŕt objektovo orientovaného programovania je aj tzv. zapuzdrenie členských konštánt, resp. premenných = vlastností tried (properties) a takisto členských funkcií = metód tried do ich „vnútra" (local space). Triedy následne poskytujú prístup k svojmu vnútornému priestoru, resp. k údajom, ktoré spravujú (vrátane údajov uložených v databázach), cestou verejne prístupných vlastnostní a metód (public). Tým vytvárajú vzťahy čiže kontrakty medzi svojím vnútorným a okolitým prostredím (global space). Vznikajú tak tzv. kontraktné, resp. pomocné triedy (contract, helper classes).

Jedna z nich je aj abstraktná trieda SQLiteOpenHelper, ktorá je vzorom (pattern) na implementáciu tried a ich metód určených na vytvorenie, otvorenie a upgrade databáz. V rámci našej aplikácie sme kontraktnú triedu rozširujúcu SQLiteOpenHelper implementovali pomocou triedy dB_helper. Podľa odporúčaní sme kód zodpovedný za vytvorenie (onCreate) a upgrade (onUpgrade) konkrétnej tabuľky s názvom ulohy umiestnili do samostatnej triedy tbl_ulohy. Tu je definovaný aj výraz SQL na vytvorenie novej databázy (tabuľky). Otvorenie (vytvorenie, resp. upgrade) databázy s možnosťou zápisu sa realizuje neskôr v rámci providera, konkrétne jeho metódy onCreate(), a to vykonaním metódy getWritableDatabase().

Content Providers

Patria medzi štyri základné typy aplikácií písaných pre OS Android. Majú rovnaké postavenie ako aktivity, služby a prijímače oznámení. Ich existenciu uvádzame priamo do manifestu, kde súčasne definujeme bezpečnostné pravidlá na ich používanie.

Každý provider sám seba identifikuje pomocou tzv. autority (authority). Autorita je základná časť tzv. jednotného identifikátora zdroja (URI - Uniform Resource Identifier) daného providera. URI sa používa ako náhrada adresy zdroja, ktorý chceme použiť. Autorita providera musí byť rovnako ako názov programového balíčka našej aplikácie jedinečná (unique). Preto je vhodné, ak je táto základná časť URI rovnaká ako názov balíčka aplikácie.

Úlohou providerov je vytvárať rozhranie medzi vrstvou údajov (uložených najčastejšie v databáze = data layer) a aplikačnou vrstvou (application layer). Štruktúra providerov predstavuje abstrakciu štruktúry údajov (databáz). Providery sa teda navonok javia ako databázy. Jedna z ich hlavných úloh je sprístupniť inak neprístupné interné údaje (databázy) ostatným aplikáciám. Rovnakú úlohu plnia aj tzv. natívne providery, ktoré poskytujú prístup k „systémovým" údajom (napr. hovorom, kontaktom, multimédiám, kalendáru...) nielen pre systémové, ale aj pre všetky ostatné aplikácie.

Implementácia providera v aplikácii planovac_v2

Aplikácie žiadajú providery o prístup k údajom spravovaným nimi pomocou resolverov, ktoré sú priradené ku kontextu každej aktivity. Náš resolver sme získali v rámci triedy MainActivity, a to vykonaním metódy getContentResolver().

Programový kód providera sme umiestnili do triedy dB_contentprovider. Na jeho začiatku sme definovali „povinnú" konštantu CONTENT_URI. Následne sme využili služby triedy UriMatcher, ktorá je určená na analýzu URI a determináciu formátu požiadavky zaslanej resolverom. Definovali sme tak formát URI dvoch základných požiadaviek týkajúcich sa:

  1. všetkých riadkov, resp. záznamov (records) tabuľky,
  2. konkrétneho riadka tabuľky.

V ďalšom sme implementovali metódy query() a getType(). Prvá z nich využíva služby triedy SQLiteQueryBuilder určené na vytvorenie výrazu SQL v závislosti od konkrétnej formy URI. Druhá z nich vracia MIME (Multipurpose Internet Mail Extensions) typ údajov, ktoré ponúka náš provider. Rovnako ako v prípade dvoch odlišných formátov URI treba rozlíšiť MIME typ údajov pre prípad požiadavky týkajúcej sa všetkých riadkov a konkrétneho riadka tabuľky.

V neposlednom rade sme v rámci kódu nášho providera definovali transakčné metódy na vloženie (insert), zmazanie (delete) a zmenu (update) údajov uložených v databáze. Vo všetkých prípadoch sme o vykonaných zmenách informovali resolver pomocou metódy notifyChange().

Android-obr1.jpg

Štruktúra zdrojového kódu aplikácií planovac_v1 a planovac_v2 (zmenené časti sú označené červenou)

CursorLoader

Na prácu s údajmi uloženými v databázach slúži trieda Cursor. Tá je ukazovateľom (pointer) na množinu údajov (result set), ktorá je výsledkom riešenia zaslanej požiadavky. Kurzor je zároveň manažérom danej množiny údajov.

Pretože operácie (transakcie) vykonávané s údajmi uloženými v databázach sú časovo náročné, je vhodné, aby sa vykonávali mimo hlavného programového vlákna (main thread), resp. používateľského rozhrania (UI - User Interface) aplikácie. Na zjednodušenie procesu synchronizácie práce kurzorov s UI aplikácií boli do Android 3.0 (API level 11) a takisto do Android Support Library doplnené tzv. nahrávače (loaders).

Loadery sú určené na asynchrónnu prácu so zdrojmi údajov a ich monitorovanie. V rámci aktivít a fragmentov sú dostupné prostredníctvom triedy LoaderManager, a to vykonaním metódy getLoaderManager(), resp. getSupportLoaderManager(). LoaderManager spravuje životný cyklus loaderov, medzi ktoré patrí aj CursorLoader.

CursorLoader poskytuje asynchrónny manažment kurzora, prostredníctvom ktorého sú riešené požiadavky zaslané danému provideru. Na to, aby implementácia takéhoto loadera pracovala správne, musíme definovať obsah nasledujúcich troch abstraktných metód rozhrania LoaderManager.LoaderCallbacks:

  1. onCreateLoader() - inicializácia loadera, špecifikácia parametrov požiadaviek zasielaných resolverom,
  2. onLoadFinished() - ukončenie asynchrónneho riešenia požiadavky (kurzor ukazuje na údaje),
  3. onLoaderReset() - reštart loadera (údaje nie sú viac k dispozícii).
Zobrazit Galériu
Autor: Marek Sopko

Nechajte si posielať prehľad najdôležitejších správ emailom

Mohlo by Vás zaujímať

ITPro

Linux súkromne i pracovne v2.0 (14. časť): Small Business Server

09.11.2016 14:57

Pojem Small Business Server (malý firemný server) začala používať spoločnosť Microsoft ešte v roku 2000 na označenie servera, ktorý ­dokázal plniť úlohy niekoľkých samostatných serverov. Aplikačná vrs ...

ITPro

Industry 4.0: Fikcia alebo už realita?

09.11.2016 14:52

Štvrtá priemyselná revolúcia je pomenovanie rozsiahlych zmien prudko vstupujúcich do súčasného priemyslu. Nositeľom týchto zmien je digitalizácia výroby a optimalizácia všetkých podnikových procesov v ...

ITPro

Vývoj aplikácií UWP pre Xbox One II.

09.11.2016 14:47

V predošlej časti sme ukázali postup, ako si ­vytvoriť vývojársky účet a aktivovať vývojársky režim na hernej konzole Xbox One, aby ste mohli testovať svoje aplikácie. Výhodou hernej konzoly Xbox je v ...

Žiadne komentáre

Vyhľadávanie

Kyocera - prve-zariadenia-formatu-a4-s-vykonom-a3

Najnovšie videá