Image
11.7.2016 1 Comments

Seriál: Programovanie v Androide pre začiatočníkov 3. časť / Aktivita a jaj životný cyklus

Väčšina aplikácií nielen pre mobilné, zariadenia, ale vo všeobecnosti pozostáva z niekoľkých obrazoviek. Na platforme Android sa tieto obrazovky nazývajú Activity. V správne navrhnutej aplikácii by jednotlivé aktivity mali fungovať samostatne. Mali by mať presne definované vstupy a výstupy. Prečo? Aby bolo možné z aplikácie zavolať aktivitu inej aplikácie a používateľovi sa to bude javiť ako kontinuálny proces, ako keby aktivita inej aplikácie bola integrálnou súčasťou aktivity, z ktorej je spustil.

Aplikácie pre Android sa skladajú z viacerých na sebe nezávislých komponentov – aktivít a služieb. Operačný systém sám určuje, kedy budú vytvorené inštancie aktivít, kedy budú odsunuté na pozadie, či zničené. Aktivita reprezentuje jednu obrazovku s používateľským rozhraním. V Java kóde je aktivita objekt odvodený od triedy Activity.

Aktivita je určitá analógia okna, prípadne dialógového okna v klasických Windows aplikáciách. Základnou úlohou aktivity je zobraziť používateľovi údaje z nižších vrstiev v požadovanej forme. Každá aktivita je potomkom triedy android.app.Activity. Aktivita reaguje na udalosti životného cyklu a  prekrýva príslušné metódy.

Väčšinou aktivita zaberá celú plochu displeja, ale nie je to pravidlo. Aktivitu je v prípade potreby možné definovať ako celobrazovkovú. Každá aktivita má vlastný životný cyklus a je potrebné počítať z tým, že inštancie aktivít a služieb môžu byť v odôvodnených prípadoch kedykoľvek odstránené. Napríklad ak začnú dochádzať systémové zdroje, tak systém sa pokúsi odstrániť nepoužívané komponenty.

Aktivita zodpovedá za uloženie svojho stavu, teda množinu údajov, ktoré tento stav definujú.

Jedna z aktivít je definovaná ako hlavná (main). Táto aktivita sa zobrazí po štarte aplikácie. Po spustení ďalšej aktivity sa predchádzajúca aktivita pozastaví, ale zostane v pamäti v pamäťovej oblasti nazývanej back stack. Do tejto oblasti je aktivita ukladá po spustení. Vtedy zároveň prevezme fokus, čiže príznak, že sa jedná o aktívnu aktivitu zobrazenú na displeji zariadenia.

Back Stack obsahuje informácie o aktuálne spustených aktivitách. Umožňuje používateľom jednoducho prechádzať tam a späť medzi aktivitami. Aktivity by mali byť modulárne v tom zmysle, že každá aktivita by mala podporovať jednu záležitosť, jednu funkcionalitu. Pod pojmom Back Stack úloha sa na platforme Android rozumie sada súvisiacich aktivít, ktoré  môžu, ale nemusia byť súčasťou tej istej aplikácie. Back stack je úložný priestor, ktorý má zásobníkovú štruktúru typu LIFO (Last In First Out).

Aktivita nemá verejne prístupný konštruktor, takže jej spustenie je možné ovplyvniť iba parametrom typu Bundle v metóde onCrete. Aktivita môže spúšťať inú aktivitu, vrátane aktivít  inej aplikácie.

Životný cyklus aktivity

Životný cyklus aktivity je definovaný metódami, ktoré sa spúšťajú v presne definovaných situáciách v určenom poradí.

Životný cyklus aktivity najlepšie pochopíte z diagramu. Má tri hlavné fázy

  • Aktivita na popredí - zobrazuje sa na displeji a má takzvaný fokus, to znamená, že interaguje s používateľom. Bežiace aktivity na popredí sú v stavoch Running, prípadne Resumed
  • Pozastavená aktivita – je stále v pamäti, je spravidla čiastočne viditeľná no stráca fokus, to znamená, že používateľ k nej nemá prístup. Typickým príkladom je prekrytie aktivity dialógom. V prípade akútneho nedostatku pamäti môže systém aplikáciu v tomto stave odstrániť.
  • Zastavená aktivita – je kompletne prekrytá inou aktivitou. Aktivita je však stále v pamäti, v oblasti back stacku, takže nie je problém sa k nej v prípade potreby vrátiť. V prípade nedostatku pamäti systém najskôr odstráni tieto aktivity a až potom ak nedostatok pamäti pretrváva prídu na radu aktivity v stave pozastavené

Ak používateľ potrebuje obnoviť aktivitu v stave pozastavená, alebo zastavená a používať ju na popredí, v takomto prípade dochádza k reštartu aktivity.

Ak je potrebné realizovať v niektorej fáze životného cyklu niektoré špecifické akcie, je potrebné prepísať jednu alebo viac týchto metód naviazaných na životný cyklus. Je potrebné mať na pamäti, že tieto metódy sa vzájomne prepájajú a taktiež, že aplikácie fungujú v súčinnosti s operačným systémom, ktorý ich životný cyklus často direktívne ovplyvňuje, napríklad odstráni aplikáciu, ktorá nie je na popredí v prípade akútneho nedostatku operačnej pamäti.

Schéma životného cyklu aktivity

Podnetom na spustenie aktivity môže byť ťuknutie používateľa na ikonu aplikácie, prípadne je táto aktivita explicitným, alebo implicitným cieľom nejakého zámeru (Intent). Nasledujúci popis priebehu životného cyklu aktivity je najlepšie sledovať na diagrame.

onCreate() 

Metóda sa prvý krát aktivuje po spustení aktivity. V tele metódy sa zatiaľ na pozadí vytvára používateľské rozhranie a konfigurujú sa premenné a objekty potrebné na beh aktivity. Po zavolaní metódy onCreate() je aktivita stále zastavená, neviditeľná a nekomunikuje s používateľom.   Kód metódy onCreate() vloží vývojové prostredie do hlavnej aktivity novovytvoreného projektu.

Metóda onCreate(Bundle savedInstanceState){…}  sa volá:

  • Pri prvom spustení aktivity,
  • Ak aktivita už bežala, ale bola prekrytá inou aktivitou a následne sa požívateľ  opäť vrátil k pôvodnej aktivite.
  • Operačný systém potreboval pamäť (pôvodný proces mohol byť odstránený)
  • Aktivita beží a je vynútená zmena resources, napríklad pri otočení displeja, pripojení, alebo odpojení hardvérovej klávesnice, zmene jazyka používateľského rozhrania a podobne.

V metóde sa obvykle rieši zavedenie layoutu a inicializácia prvkov view, nastavenie premenných, prípadne získanie dát z volajúceho Intentu.  Ako parameter je odovzdaný objekt Bundle s uloženým predchádzajúcim stavom activity (ak nejaký existuje).

onStart() a onResume()

Aktivita prechádza do popredia. V metóde onStart() sa realizujú činnosti potrebné k tomu aby bolo možné zobraziť používateľské rozhranie aktivity.  Rozdiel medzi metódami je zrejmý z diagramu.  OnStart() sa volá pri spúšťaní, ktoré nasleduje po predchádzajúcom zastavení aktivity.  Po spustení metódy onStart() obvykle nasleduje spustenie metódy onResume().  Metóda onResume() sa volá vtedy,  keď aktivita prechádza z pozadia do popredia.

onPause()

V prípade, ak je spustená iná aktivita, prechádza aktivita, ktorá bola predtým na popredí do pozadia. V tejto metóde je vhodné automaticky uložiť zmeny údajov, s ktorými aktivita pracovala, napríklad do databázy, súborov dokumentov a podobne.

Metóda sa volá ak aktivita prestane byť na popredí, napríklad pri prechode na inú aktivitu, pri zobrazení dialógu, po stlačení tlačidla HOME.

Po dobehnutí metódy onPause() môže byť proces zlkvidovaný

V metóde sa obvykle rieši  uloženie aktuálnych neobnoviteľných dát, ukončenie snímania údajov zo senzorov (GPS...), ukončenie všetkých animácií a operácií náročných na CPU, uvoľnenie zámkov typu screenlock, wakeLock a podobne.

Operácie realizované v metóde onPause() musia byť časovo nenáročné

onStop()

Volá sa pri zastavení aktivity z iného dôvodu než je nedostatok pamäti. Aktivita je stále v back stacku a užívateľ ju môže znova zobraziť na popredí. Vtedy sa volá metóda onRestart().

Metóda onStop() nemusí byť nikdy volaná.

onDestroy() 

Metóda sa volá pri ukončovaní životnosti aktivity, bez ohľadu na to či sa tak stane explicitne, alebo implicitne.

Metóda onDestroy() nemusí byť nikdy volaná.

Príklad – životný cyklus aktivity

Cieľom príkladu je ilustrovať, kedy nastávajú aké fázy životného cyklu aplikácie pri používaní zariadenia s operačným systémom Android. Vytvorte projekt aplikácie CyklusAktivity, pričom ako typ hlavnej aktivity vyberte Basic. Hlavnú aktivitu vhodne pomenujte, napríklad  StateChangeActivity.

Otvorte súbor StateChangeActivity.java s Java kódom aktivity. Zatiaľ jediná metóda ktorá sa vzťahuje na životný cyklus je metóda OnCreate (). Jej úlohou je volať super inštanciu triedy metódy pred nastavením používateľského rozhrania pre aktivitu. Budeme modifikovať túto metódu tak, aby sme získali ladiaci výstup cez diagnostické hlásenia na paneli LogCat vývojového prostredia Android Studio pri každom spustení. Využijeme triedu Log, ktorá potrebuje import android.util.Log.

Definujte textový reťazec, ktorý vás pri ladení aplikácie upozorní na zmenu stavu, aby ste vedeli, kde táto zmena nastala. Prvý takýto ladiaci text umiestnite do metódy onCreate. Aby sme mali viac stavov, treba prepísať niektoré ďalšie metódy, pričom každá z nich bude obsahovať príslušný ladiaci výpis. Tieto metódy môžete pridať ručne alebo vytvoriť pomocou klávesovej skratky Alt-Insert

import android.util.Log;
 
public class StateChangeActivity extends AppCompatActivity {
    private static final String LAD = "ZmenaStavu";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_state_change);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
 
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        Log.i(LAD, "OnCreate");
    }
 
    @Override
    protected void onStart() {
        super.onStart();  Log.i(LAD, "onStart");
    }
   
    @Override
    protected void onResume() {
        super.onResume(); Log.i(LAD, "onResume");
    }
 
    @Override
    protected void onPause() {
        super.onPause(); Log.i(LAD, "onPause");
    }
 
    @Override
    protected void onStop() {
        super.onStop(); Log.i(LAD, "onStop");
    }
    @Override
    protected void onRestart() {
        super.onRestart(); Log.i(LAD, "onRestart");
    }
    @Override
    protected void onDestroy() {
        super.onDestroy(); Log.i(LAD, "onDestroy");
    }
 
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.i(LAD, "onSaveInstanceState");
    }
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.i(LAD, "onRestoreInstanceState");
    }

Ladiace texty sa budú vypisovať do okna nástroja Android Monitor. Tento výstup môže byť nakonfigurovaný na zobrazenie všetkých, alebo filtrovaných informácií. Pomocou voľby Edit Filter Configuration v comboboxe pre výber typu filtra definujte nový filter pre logovanie.

Definovanie filtra pre logovacie výpisy do okna Android Monitor.

Následne spustite aplikáciu, najlepšie na fyzickom zariadení pripojenom k vývojárskemu počítaču cez USB. Po zobrazení prvých niekoľko riadkov svedčiacich o tom, že aplikácia bola spustená

onCreate
onStart
onResume

skúste chvíľu zo zariadením pracovať, napríklad stlačte tlačidlo Home.Vo výpise protokolu sa zobrazí postupnosť stavov

onPause
onSaveInstanceState
onStop

Protokol o zmenách stavu aktivity.

Príklad – ukladanie a obnovenie stavu aktivity

Budeme pokračovať v budovaní predchádzajúcej aplikácie, ktorá dokázala cez LogCat vypísať v okne Android Monitor zmeny stavu. Na ilustráciu možností ukladania aktuálnych údajov aktivity doplníme prvok EditText a budeme sledovať či a ako sa pri zmenách stavu zachovajú aktuálne používateľom zadané údaje

Používateľské rozhranie aktivity je  definované v súbore content_state_change.xml. Nájdete ho v hierarchii zložiek projektu app -> res -> layout. Definícia používateľského rozhrania aktivity obsahuje po vytvorení projektu prvok TextView  s preddefinovaným textom “Hello world!” Na paneli Palette rozviňte zložku Text Fields a umiestnite na plochu aktivity prvok PlainText.

V príklade už máme prepísané metódy onSaveInstanceState() a onRestoreInstanceState().

Prvok ExitText je v súbore ontent_state_change.xml definovaný takto

 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:id="@+id/editText"
 android:layout_centerVertical="true"
 android:layout_centerHorizontal="true"
 android:inputType="text"
 android:saveEnabled="false"
 android:width="200dp" />

nastavte mu ešte atribút android:saveEnabled="false", aby ste pre ilustráciu ako to funguje zakázali automatické ukladanie stavu. Spustite aplikáciu a zadajte do prvku EditText nejakú hodnotu. Zmenu stavu najjednoduchšie navodíte pootočením zariadenia. Všimnite si, že pri tomto nastavení, kedy ste zakázali automatické ukladanie stavu sa vami zadaný text pri potočení zariadenia vymaže.

Aby sme ukázali, ako to funguje, budeme napísaný text ukladať kódom. Pridajte do zdrojového kódu v súbore  tateChangeActivity.java import

import android.widget.EditText;

Metódu onSaveInstanceState doplňte o kód kde widgetu EditText priradíte podľa ID príslušný prvok používateľského rozhrania, získate z neho textový reťazec a uložíte ho.

@Override
protected void onSaveInstanceState(Bundle outState) {
     super.onSaveInstanceState(outState);
     Log.i(LAD, "onSaveInstanceState");
     final EditText textBox =(EditText) findViewById(R.id.editText);
     CharSequence sText = textBox.getText();
     outState.putCharSequence("UlozenyText", sText);
 }

V metóde  onRestoreInstanceState() text obnovíte

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    Log.i(LAD, "onRestoreInstanceState");
    final EditText textBox = (EditText) findViewById(R.id.editText);
    CharSequence sText = savedInstanceState.getCharSequence("UlozenyText");
    textBox.setText(sText);
}

Teraz zostane pri zmene stavu text zachovaný, presnejšie povedané obnoví sa.

Znovu pripomíname, že je to len ilustračný príklad v ktorom sme pre prvok EditText zakázali implicitné ukladanie zmeny stavu

Zobrazit Galériu

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 ...

1 Comments

  1. preklep reakcia na: Seriál: Programujeme pre Android 22 / Ukladanie a záloha údajov
    7.9.2016 13:09
    .. jaj (jej) zivotny cyklus ..
    Reagovať

Vyhľadávanie

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

Najnovšie videá