Životní cyklus aktivity
Aktivity jsou základním stavebním blokem aplikací pro Android a mohou existovat v řadě různých stavů. Životní cyklus aktivity začíná vytvářením instancí a končí zničením a zahrnuje mnoho stavů mezi. Když se změní stav aktivity, zavolá se příslušná metoda události životního cyklu, oznámí aktivitě nadcházející změny stavu a umožní spuštění kódu pro přizpůsobení této změně. Tento článek zkoumá životní cyklus aktivit a vysvětluje odpovědnost, že aktivita má během každé z těchto změn stavu součást dobře chované a spolehlivé aplikace.
Přehled životního cyklu aktivity
Aktivity představují neobvyklý koncept programování specifický pro Android. V tradičním vývoji aplikací je obvykle statická hlavní metoda, která se spustí pro spuštění aplikace. S Androidem se ale věci liší; Aplikace pro Android je možné spustit prostřednictvím jakékoli registrované aktivity v aplikaci. V praxi bude mít většina aplikací pouze konkrétní aktivitu, která je určena jako vstupní bod aplikace. Pokud se ale aplikace chybově ukončí nebo je ukončena operačním systémem, může se operační systém pokusit aplikaci restartovat při poslední otevřené aktivitě nebo kdekoli jinde v rámci předchozího zásobníku aktivit. Kromě toho může operační systém pozastavit aktivity, když nejsou aktivní, a uvolnit je, pokud je nedostatek paměti. Je třeba pečlivě zvážit, aby aplikace mohla správně obnovit svůj stav v případě restartování aktivity, zejména pokud tato aktivita závisí na datech z předchozích aktivit.
Životní cyklus aktivity se implementuje jako kolekce metod, které operační systém volá v průběhu životního cyklu aktivity. Tyto metody umožňují vývojářům implementovat funkce, které jsou nezbytné pro splnění požadavků na stav a správu prostředků svých aplikací.
Pro vývojáře aplikací je velmi důležité analyzovat požadavky každé aktivity, aby určil, které metody vystavené životním cyklem aktivity je potřeba implementovat. Pokud to neuděláte, může to vést k nestabilitě aplikace, chybovému ukončení, bloudu prostředků a případně i k podkladové nestabilitě operačního systému.
Tato kapitola podrobně zkoumá životní cyklus aktivity, včetně:
- Stavy aktivit
- Metody životního cyklu
- Zachování stavu aplikace
Tato část obsahuje také návod , který poskytuje praktické příklady efektivního ukládání stavu během životního cyklu aktivity. Na konci této kapitoly byste měli mít přehled o životním cyklu aktivity a o tom, jak ho podporovat v aplikaci pro Android.
Životní cyklus aktivity
Životní cyklus aktivity Androidu se skládá z kolekce metod vystavených v rámci třídy Activity, která vývojářům poskytuje architekturu pro správu prostředků. Tato architektura umožňuje vývojářům splnit jedinečné požadavky na správu stavu jednotlivých aktivit v rámci aplikace a správně zpracovávat správu prostředků.
Stavy aktivit
Operační systém Android rozhoduje aktivity na základě jejich stavu. To pomáhá Androidu identifikovat aktivity, které se už nepoužívají, což operačnímu systému umožňuje uvolnit paměť a prostředky. Následující diagram znázorňuje stavy, které může aktivita během své životnosti projít:
Tyto stavy mohou být rozděleny do 4 hlavních skupin následujícím způsobem:
Aktivní nebo spuštěné – Aktivity jsou považovány za aktivní nebo spuštěné, pokud jsou v popředí, označované také jako horní část zásobníku aktivit. To se považuje za aktivitu s nejvyšší prioritou v Androidu a operační systém ho v extrémních situacích zabije, například pokud se aktivita pokusí použít více paměti, než je v zařízení k dispozici, protože to může způsobit, že uživatelské rozhraní přestane reagovat.
Pozastaveno – Když zařízení přejde do režimu spánku nebo je aktivita stále viditelná, ale částečně skrytá novou, neplněnou nebo transparentní aktivitou, považuje se aktivita za pozastavenou. Pozastavené aktivity jsou stále aktivní, to znamená, že udržují všechny informace o státu a členech a zůstávají připojené ke správci okna. To je považováno za druhou aktivitu s nejvyšší prioritou v Androidu a operační systém ji zabije pouze v případě, že zabití této aktivity splní požadavky na prostředky potřebné k udržení stabilní a responzivní aktivity aktivní/spuštěné aktivity.
Zastaveno/na pozadí – aktivity, které jsou zcela skryté jinou aktivitou, se považují za zastavené nebo na pozadí. Zastavené aktivity se stále snaží zachovat jejich informace o stavu a členech co nejdéle, ale zastavené aktivity se považují za nejnižší prioritu těchto tří států a operační systém například nejprve ukončí aktivity v tomto stavu, aby splňovaly požadavky na prostředky vyšší priority.
Restartováno – Je možné, aby se aktivita, která je kdekoli od pozastavení do zastavení v životním cyklu, odebrala z paměti androidem. Pokud uživatel přejde zpět na aktivitu, je nutné ji restartovat, obnovit do dříve uloženého stavu a pak se uživateli zobrazit.
Opětovné vytvoření aktivity v reakci na změny konfigurace
Aby bylo důležité komplikovat, Android v kombinaci s názvem Změny konfigurace vyvolá ještě jeden klíč. Změny konfigurace jsou rychlé cykly zničení nebo opětovného vytvoření aktivity, ke kterým dochází, když se konfigurace aktivity změní, například když se zařízení otočí (a aktivita musí být znovu integrovaná v režimu na šířku nebo na výšku), když se zobrazí klávesnice (a aktivita se zobrazí s příležitostí ke změně velikosti samotného), nebo když je zařízení umístěné v doku, mimo jiné.
Změny konfigurace stále způsobují stejné změny stavu aktivity, ke kterým by došlo při zastavení a restartování aktivity. Aby se však zajistilo, že aplikace reaguje a funguje dobře během změn konfigurace, je důležité, aby byla co nejrychleji zpracována. Z tohoto důvodu má Android specifické rozhraní API, které lze použít k zachování stavu během změn konfigurace. Tento článek si probereme později v části Správa stavu v průběhu životního cyklu .
Metody životního cyklu aktivit
Sada Android SDK a architektura Xamarin.Android poskytuje výkonný model pro správu stavu aktivit v rámci aplikace. Když se změní stav aktivity, operační systém oznámí aktivitu, která volá konkrétní metody dané aktivity. Následující diagram znázorňuje tyto metody ve vztahu k životnímu cyklu aktivity:
Jako vývojář můžete zpracovávat změny stavu přepsáním těchto metod v rámci aktivity. Je však důležité si uvědomit, že všechny metody životního cyklu jsou volány ve vlákně uživatelského rozhraní a zablokují operační systém provádění další části práce uživatelského rozhraní, jako je skrytí aktuální aktivity, zobrazení nové aktivity atd. Kód v těchto metodách by měl být co nejkratší, aby se aplikace cítila dobře. Všechny dlouhotrvající úlohy by se měly spouštět ve vlákně na pozadí.
Pojďme se podívat na každou z těchto metod životního cyklu a jejich použití:
OnCreate
OnCreate je první metoda, která se má volat při vytvoření aktivity.
OnCreate
je vždy přepsán, aby se provedly všechny inicializace spuštění, které můžou být vyžadovány aktivitou, například:
- Vytváření zobrazení
- Inicializace proměnných
- Vytvoření vazby statických dat k seznamům
OnCreate
přebírá parametr Bundle, což je slovník pro ukládání a předávání informací o stavu a objektů mezi aktivitami Pokud sada nemá hodnotu null, znamená to, že aktivita se restartuje a měla by obnovit svůj stav z předchozí instance. Následující kód ukazuje, jak načíst hodnoty ze sady:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
string intentString;
bool intentBool;
if (bundle != null)
{
intentString = bundle.GetString("myString");
intentBool = bundle.GetBoolean("myBool");
}
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
}
Po OnCreate
dokončení bude Android volat OnStart
.
OnStart
OnStart je vždy volána systémem po OnCreate
dokončení. Aktivity mohou tuto metodu přepsat, pokud potřebují provádět jakékoli konkrétní úlohy přímo před tím, než se aktivita zobrazí, například aktualizace aktuálních hodnot zobrazení v rámci aktivity. Android bude volat OnResume
ihned po této metodě.
OnResume
Systém volá OnResume , když je aktivita připravena začít pracovat s uživatelem. Aktivity by měly tuto metodu přepsat, aby prováděly například tyto úlohy:
- Zvýšení frekvence snímků (běžný úkol při vývoji her)
- Spouštění animací
- Naslouchání aktualizacím GPS
- Zobrazení všech relevantních výstrah nebo dialogových oken
- Připojení externích obslužných rutin událostí
Například následující fragment kódu ukazuje, jak inicializovat fotoaparát:
protected override void OnResume()
{
base.OnResume(); // Always call the superclass first.
if (_camera==null)
{
// Do camera initializations here
}
}
OnResume
je důležité, protože jakákoli operace, která se provádí, OnPause
by měla být bez provedení OnResume
, protože je to jediná metoda životního cyklu, která je zaručena provést po OnPause
přenesení aktivity zpět do života.
OnPause
OnPause se volá, když se systém chystá vložit aktivitu na pozadí nebo když se aktivita stane částečně nejasnou. Aktivity by měly tuto metodu přepsat, pokud potřebují:
Potvrzení neuložených změn do trvalých dat
Zničení nebo vyčištění jiných objektů, které spotřebovávají prostředky
Ramp down frame rates and pausing animations
Zrušení registrace externích obslužných rutin událostí nebo obslužných rutin oznámení (tj. těch, které jsou svázané se službou). To musí být provedeno, aby se zabránilo nevracení paměti aktivity.
Podobně platí, že pokud aktivita zobrazila nějaká dialogová okna nebo výstrahy, je nutné je vyčistit metodou
.Dismiss()
.
Například následující fragment kódu uvolní kameru, protože aktivita ji nemůže používat při pozastavení:
protected override void OnPause()
{
base.OnPause(); // Always call the superclass first
// Release the camera as other activities might need it
if (_camera != null)
{
_camera.Release();
_camera = null;
}
}
Existují dvě možné metody životního cyklu, které budou volána po OnPause
:
OnResume
bude volána, pokud se aktivita vrátí do popředí.OnStop
bude volána, pokud je aktivita umístěna na pozadí.
OnStop
OnStop se volá, když se aktivita už uživateli nezobrazuje. K tomu dochází v případě, že dojde k některé z následujících situací:
- Začíná se nová aktivita a tato aktivita se pokrývá.
- Do popředí se přenese existující aktivita.
- Aktivita je zničena.
OnStop
nemusí být vždy volána v situacích s nedostatkem paměti, například když je Android hladověný pro prostředky a nemůže správně na pozadí aktivity. Z tohoto důvodu se při přípravě aktivity na zničení nejlépe nespoléhá OnStop
na zavolání. Další metody životního cyklu, které se můžou volat po tomto kroku, budou v OnDestroy
případě, že aktivita zmizí nebo OnRestart
pokud se aktivita vrátí k interakci s uživatelem.
OnDestroy
OnDestroy je konečná metoda, která je volána v instanci aktivity před zničením a zcela odstraněna z paměti. V extrémních situacích může Android zabít proces aplikace, který hostuje aktivitu, což způsobí OnDestroy
, že se nevyvolá. Většina aktivit tuto metodu neimplementuje, protože většina čištění a vypnutí byla provedena v těchto OnPause
metodách OnStop
. Metoda OnDestroy
je obvykle přepsána k vyčištění dlouhotrvajících úloh, které by mohly uniknout prostředkům. Příkladem může být vlákna na pozadí, která byla spuštěna v OnCreate
.
Po zničení aktivity nebudou volána žádné metody životního cyklu.
OnRestart
OnRestart se volá po zastavení vaší aktivity před dalším spuštěním. Dobrým příkladem by bylo, když uživatel stiskne tlačítko Domů při aktivitě v aplikaci. Když k tomu dojde OnPause
a pak OnStop
se metody volají a aktivita se přesune na pozadí, ale nezničí se. Pokud by uživatel pak aplikaci obnovil pomocí správce úloh nebo podobné aplikace, Android zavolá OnRestart
metodu aktivity.
Neexistují žádné obecné pokyny pro to, v jakém typu logiky by se mělo implementovat OnRestart
. Důvodem je to, že OnStart
je vždy vyvolána bez ohledu na to, zda se aktivita vytváří nebo restartuje, takže všechny prostředky vyžadované aktivitou by měly být inicializovány spíše než OnStart
OnRestart
.
Další metoda životního cyklu volaná po OnRestart
bude OnStart
.
Zpět vs. Domovská stránka
Mnoho zařízení s Androidem má dvě různá tlačítka: tlačítko Zpět a tlačítko Domů. Příklad je vidět na následujícím snímku obrazovky Androidu 4.0.3:
Mezi těmito dvěma tlačítky je malý rozdíl, i když se zdá, že mají stejný účinek jako umístění aplikace na pozadí. Když uživatel klikne na tlačítko Zpět, řekne Androidu, že je s aktivitou hotový. Android zničí aktivitu. Naproti tomu když uživatel klikne na tlačítko Domů, aktivita je pouze umístěna na pozadí – Android tuto aktivitu nezabije.
Správa stavu v průběhu životního cyklu
Když je aktivita zastavena nebo zničena, poskytuje systém příležitost uložit stav aktivity pro pozdější dosazování. Tento uložený stav se označuje jako stav instance. Android poskytuje tři možnosti pro ukládání stavu instance během životního cyklu aktivity:
Ukládání primitivních hodnot do známé sady
Dictionary
, kterou Android použije k uložení stavu.Vytvoření vlastní třídy, která bude obsahovat složité hodnoty, jako jsou rastrové obrázky. Android použije tuto vlastní třídu k uložení stavu.
Obejití životního cyklu změny konfigurace a zajištění úplné odpovědnosti za udržování stavu v aktivitě.
Tato příručka popisuje první dvě možnosti.
Stav sady
Primární možností pro uložení stavu instance je použití objektu slovníku klíč/hodnota, který se označuje jako Bundle.
Vzpomeňte si, že OnCreate
při vytvoření aktivity se metoda předává jako parametr sady, lze tuto sadu použít k obnovení stavu instance. Nedoporučuje se používat sadu pro složitější data, která nebudou rychle ani snadno serializovat páry klíč/hodnota (například rastrové obrázky); místo toho by se měla používat pro jednoduché hodnoty, jako jsou řetězce.
Aktivita poskytuje metody, které pomáhají s ukládáním a načítáním stavu instance v sadě:
OnSaveInstanceState – To je vyvoláno Androidem při zničení aktivity. Aktivity mohou tuto metodu implementovat, pokud potřebují zachovat jakékoli položky stavu klíče a hodnoty.
OnRestoreInstanceState – Tato metoda je volána po
OnCreate
dokončení metody a poskytuje další příležitost k obnovení stavu aktivity po dokončení inicializace.
Následující diagram znázorňuje použití těchto metod:
OnSaveInstanceState
Při zastavení aktivity se bude volat OnSaveInstanceState . Obdrží parametr sady, do kterého může aktivita uložit svůj stav. Když zařízení dojde ke změně konfigurace, může aktivita použít Bundle
objekt předaný k zachování stavu aktivity přepsáním OnSaveInstanceState
. Představte si například následující kód:
int c;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
this.SetContentView (Resource.Layout.SimpleStateView);
var output = this.FindViewById<TextView> (Resource.Id.outputText);
if (bundle != null) {
c = bundle.GetInt ("counter", -1);
} else {
c = -1;
}
output.Text = c.ToString ();
var incrementCounter = this.FindViewById<Button> (Resource.Id.incrementCounter);
incrementCounter.Click += (s,e) => {
output.Text = (++c).ToString();
};
}
Výše uvedený kód zvýší celé číslo pojmenované c
při kliknutí na tlačítko incrementCounter
, které zobrazí výsledek v pojmenovaném TextView
output
souboru . Když dojde ke změně konfigurace – například když se zařízení otočí – výše uvedený kód ztratí hodnotu c
, protože bundle
by to bylo null
, jak je znázorněno na obrázku níže:
Chcete-li zachovat hodnotu c
v tomto příkladu, může aktivita přepsat OnSaveInstanceState
, uložení hodnoty v sadě, jak je znázorněno níže:
protected override void OnSaveInstanceState (Bundle outState)
{
outState.PutInt ("counter", c);
base.OnSaveInstanceState (outState);
}
Když se teď zařízení otočí na novou orientaci, celé číslo se uloží do sady a načte se řádkem:
c = bundle.GetInt ("counter", -1);
Poznámka:
Je důležité vždy volat základní implementaci OnSaveInstanceState
, aby bylo možné uložit také stav hierarchie zobrazení.
Zobrazit stav
Přepsání OnSaveInstanceState
je vhodný mechanismus pro ukládání přechodných dat v aktivitě napříč změnami orientace, jako je například čítač v předchozím příkladu. Výchozí implementace se ale postará o ukládání přechodných OnSaveInstanceState
dat v uživatelském rozhraní pro každé zobrazení, pokud má každé zobrazení přiřazené ID. Řekněme například, že aplikace má EditText
element definovaný v jazyce XML takto:
<EditText android:id="@+id/myText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
EditText
Vzhledem k tomu, že má ovládací prvek přiřazenýid
, když uživatel zadá nějaká data a otočí zařízení, budou se data stále zobrazovat, jak je znázorněno níže:
OnRestoreInstanceState
OnRestoreInstanceState bude volána za OnStart
. Poskytuje aktivitu, která umožňuje obnovit jakýkoli stav, který byl dříve uložen do sady během předchozího OnSaveInstanceState
. Jedná se o stejný balíček, který je však poskytován OnCreate
.
Následující kód ukazuje, jak lze obnovit stav:OnRestoreInstanceState
protected override void OnRestoreInstanceState(Bundle savedState)
{
base.OnRestoreInstanceState(savedState);
var myString = savedState.GetString("myString");
var myBool = savedState.GetBoolean("myBool");
}
Tato metoda existuje, aby poskytovala určitou flexibilitu v případě, kdy by se měl obnovit stav. Někdy je vhodnější počkat na dokončení všech inicializací před obnovením stavu instance. Kromě toho může podtřída existující aktivity chtít obnovit pouze určité hodnoty ze stavu instance. V mnoha případech není nutné přepsat OnRestoreInstanceState
, protože většina aktivit může obnovit stav pomocí sady poskytované OnCreate
.
Příklad uložení stavu pomocí Bundle
příkazu , naleznete v návodu – uložení stavu aktivity.
Omezení sady prostředků
I když OnSaveInstanceState
usnadňuje ukládání přechodných dat, má určitá omezení:
Není volána ve všech případech. Když například stisknete Domů nebo Zpět , ukončíte aktivitu, nebude se
OnSaveInstanceState
volat.Sada předaná do
OnSaveInstanceState
souboru není určená pro velké objekty, jako jsou například obrázky. V případě velkých objektů je uložení objektu z OnRetainNonConfigurationInstance vhodnější, jak je popsáno níže.Data uložená pomocí sady jsou serializována, což může vést ke zpoždění.
Stav sady je užitečný pro jednoduchá data, která nepoužívají moc paměti, zatímco data instance bez konfigurace jsou užitečná pro složitější data nebo data, která jsou náročná na načtení, například z volání webové služby nebo složitého databázového dotazu. Data nekonfigurované instance se podle potřeby ukládají do objektu. Další část představuje OnRetainNonConfigurationInstance
způsob zachování složitějších datových typů prostřednictvím změn konfigurace.
Zachování složitých dat
Kromě zachování dat v sadě podporuje Android také ukládání dat přepsáním OnRetainNonConfigurationInstance a vrácením instance Java.Lang.Object
, která obsahuje data, která se mají zachovat. Existují dvě hlavní výhody použití OnRetainNonConfigurationInstance
k uložení stavu:
Objekt vrácený z
OnRetainNonConfigurationInstance
výkonu dobře s většími a složitějšími datovými typy, protože paměť uchovává tento objekt.Metoda
OnRetainNonConfigurationInstance
se volá na vyžádání a pouze v případě potřeby. To je úspornější než použití ruční mezipaměti.
Použití OnRetainNonConfigurationInstance
je vhodné pro scénáře, kdy je nákladné načíst data vícekrát, například při volání webové služby. Představte si například následující kód, který hledá Twitter:
public class NonConfigInstanceActivity : ListActivity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SearchTwitter ("xamarin");
}
public void SearchTwitter (string text)
{
string searchUrl = String.Format("http://search.twitter.com/search.json?" + "q={0}&rpp=10&include_entities=false&" + "result_type=mixed", text);
var httpReq = (HttpWebRequest)HttpWebRequest.Create (new Uri (searchUrl));
httpReq.BeginGetResponse (new AsyncCallback (ResponseCallback), httpReq);
}
void ResponseCallback (IAsyncResult ar)
{
var httpReq = (HttpWebRequest)ar.AsyncState;
using (var httpRes = (HttpWebResponse)httpReq.EndGetResponse (ar)) {
ParseResults (httpRes);
}
}
void ParseResults (HttpWebResponse httpRes)
{
var s = httpRes.GetResponseStream ();
var j = (JsonObject)JsonObject.Load (s);
var results = (from result in (JsonArray)j ["results"] let jResult = result as JsonObject select jResult ["text"].ToString ()).ToArray ();
RunOnUiThread (() => {
PopulateTweetList (results);
});
}
void PopulateTweetList (string[] results)
{
ListAdapter = new ArrayAdapter<string> (this, Resource.Layout.ItemView, results);
}
}
Tento kód načte výsledky z webu formátovaného jako JSON, parsuje je a pak výsledky zobrazí v seznamu, jak je znázorněno na následujícím snímku obrazovky:
Když dojde ke změně konfigurace – například když se zařízení otočí – kód tento proces zopakuje. Pokud chcete znovu použít původně načtené výsledky a nezpůsobovat zbytečné, redundantní síťová volání, můžeme výsledky OnRetainNonconfigurationInstance
uložit, jak je znázorněno níže:
public class NonConfigInstanceActivity : ListActivity
{
TweetListWrapper _savedInstance;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
var tweetsWrapper = LastNonConfigurationInstance as TweetListWrapper;
if (tweetsWrapper != null) {
PopulateTweetList (tweetsWrapper.Tweets);
} else {
SearchTwitter ("xamarin");
}
public override Java.Lang.Object OnRetainNonConfigurationInstance ()
{
base.OnRetainNonConfigurationInstance ();
return _savedInstance;
}
...
void PopulateTweetList (string[] results)
{
ListAdapter = new ArrayAdapter<string> (this, Resource.Layout.ItemView, results);
_savedInstance = new TweetListWrapper{Tweets=results};
}
}
Když se teď zařízení otočí, z vlastnosti se načtou LastNonConfiguartionInstance
původní výsledky. V tomto příkladu se výsledky skládají z string[]
obsahujících tweetů. Vzhledem k tomu OnRetainNonConfigurationInstance
, že vyžaduje vrácení Java.Lang.Object
, string[]
je zabalena do třídy, která podtřídy Java.Lang.Object
, jak je znázorněno níže:
class TweetListWrapper : Java.Lang.Object
{
public string[] Tweets { get; set; }
}
Například při pokusu o použití objektu TextView
vráceného z OnRetainNonConfigurationInstance
objektu dojde k úniku aktivity, jak je znázorněno následujícím kódem:
TextView _textView;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
var tv = LastNonConfigurationInstance as TextViewWrapper;
if(tv != null) {
_textView = tv;
var parent = _textView.Parent as FrameLayout;
parent.RemoveView(_textView);
} else {
_textView = new TextView (this);
_textView.Text = "This will leak.";
}
SetContentView (_textView);
}
public override Java.Lang.Object OnRetainNonConfigurationInstance ()
{
base.OnRetainNonConfigurationInstance ();
return _textView;
}
V této části jsme se dozvěděli, jak zachovat jednoduchá stavová data s daty Bundle
a zachovat složitější datové typy pomocí OnRetainNonConfigurationInstance
.
Shrnutí
Životní cyklus aktivity Androidu poskytuje výkonnou architekturu pro správu stavu aktivit v rámci aplikace, ale může být složité pochopit a implementovat. Tato kapitola představila různé stavy, že aktivita může projít během své životnosti, stejně jako metody životního cyklu, které jsou k těmto stavům přidružené. Dále byly poskytnuty pokyny týkající se toho, jaký druh logiky by se měl v každé z těchto metod provádět.