Despre ciclul de viata al unei aplicatii ar fi trebuit sa discut inainte de a crea prima aplicatie, insa am uitat! Pentru ca e mai bine mai tarziu decat niciodata, o sa dedic acest episod acestui subiect. Un Activity are un ciclu de viata care trebuie cunoscut, deoarece necunoasterea lui poate duce la erori in executia aplicatiei.
Vizionare placuta:
Pentru cine nu are rabdare sa urmareasca acest film, desi recomand vizionarea lui, 13 minute, voi rezuma in cateva randuri continutul lui:
Intr-o singura imagine, ciclul de viata al unei activitati (Activity) arata asa:
Pentru a vedea acest ciclu am creat o aplicatie foarte simpla, de fapt am reutilizat aplicatia creata in primele episoade, si am suprascris metodele corescpunzatoare etapelor prin care aplicatia trece. Asa cum se vede in film, pentur a include metodele respective am apelat la un automatism al eclipse: right click in fereastra de editare si din meniul deschis am ales Source si Override/Implement Methods. Din fereastra care se deschide, si care contine lista completa a metodelor pe care le pot suprascrie sau implementa, am ales metodele dorite, asa cum se vede din codul sursa urmator:
package eu.zeltera.test; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; public class Test_01Activity extends Activity { static final String TAG = "tutorial"; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.d(TAG, "onCreate"); } @Override protected void onRestart() { super.onRestart(); Log.d(TAG, "onRestart"); } @Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy"); } @Override protected void onPause() { super.onPause(); Log.d(TAG, "onPause"); } @Override protected void onResume() { super.onResume(); Log.d(TAG, "onResume"); } @Override protected void onStart() { super.onStart(); Log.d(TAG, "onStart"); } @Override protected void onStop() { super.onStop(); Log.d(TAG, "onStop"); } }
De fiecare data cand una dintre metodele suprascrise se executa voi scrie un mesaj in LogCat (m-am cam incurcat in film, initial am crezut, gresit, ca scriu in Console) folosind urmatoarea linie de cod: Log.d(TAG, “Mesaj”);. Aceasta metoda accepta un TAG, cu ajutorul caruia pot filtra mesajele din LogCat, care sunt destul de multe, astfel incat sa pot vedea numai mesajele care ma intereseaza. Vreau sa reamintesc, si e foarte important de retinut asta, la schimbarea orientarii telefonului care ruleaza aplicatia, fereastra (Activity) este distrusa si recreata, ceea ce presupune ca datele utilizatorului trebuiesc intr-un fel sau altul mentinute.
In film se poate vedea cum aplic un filtru in fereastra Logcat care sa imi filtreze mesajele afisate acolo si sa imi permita sa vad numai mesajele relevante pentru cazul dat.
Completare:
Dupa ce am termina de inregistrat si de scris acest articol, am incercat sa gasesc explicatia pentru ceea ce s-a intamplat in momentul in care am oprit aplicatia (stop) din Eclipse, si metoda onDestroy nu s-a executat. Ceea ce am gasit este ca singura metoda garantata ca se executa este onPause. Deci e o idee buna sa se includa in aceasta metoda codul care salveaza date, care pastreaza “application state” etc. O alta metoda care se executa tot timpul este onResume. Aici se pot folosi datele salvate in onPause.
Recomandarea este urmatoarea: onCreate se executa o singura data, si aici se pot initializa variabile. Metoda onResuma se executa de fiecare data cand aplicatia devine activa (inclusiv dupa onCreate) iar metoda onPause se executa, garantat, la iesirea din stadiu active!
In episodul urmator voi vorbi despre navigarea intre Activities, si voi introduce un concept nou numit Intent! Intre timp astept comentarii, sugestii, semnalare de greseli, sugestii de imbunatatire a acestei serii de tutoriale!
Bogdan says:
Cred ca trebuie delimitat mai bine cand doresti sa salvezi datele in metoda onPause deoarece onPause se apeleaza atat atunci cand de exemplu reorientezi telefonul dar si atunci cand iesi din aplicatie. Daca in onPause salvezi destul de multe date atunci nu cred ca e prea bine (timpul de executie cu siguranta va creste). Ori se salveaza date nu prea multe ori trebuie gasita o alta solutie, poate chiar un buton/menu de Exit care sa lanseze o salvare de date mai stufoase.
zeltera says:
Salvarea datelor nu ar trebui sa fie o operatiune foarte costisitoare, in mod normal cantitatea de date salvate e mica, iar daca folosesti sql e numai update in cazul in care e ceva ce trebuie schimbat. Pauza intervine destul de rar, de cate ori ti s-a intamplat tie sa te sune cineva in timp ce te jucai? Sa ai o salvare la 15 minute nu e asa de grav! Chiar si mai des.
Documentatia android spune ca metoda onPause este executata garantat, pe cand onStop nu! OS-ul poate decide sa iti inchida aplicatia fara sa te anunte, de exemplu daca aplicatia ta este in pauza si OS-ul se gandeste sa elibereze ceva memorie. In cauzl acesta, daca salvezi in onStop ai o mare problema.
Bineinteles, in functie de tipul aplicatiei si de cat de critic este sa nu ai pierderi de date, salvarea se face diferit!
bogdan says:
Am inteles ideea ta :)