Google I/O’da tanฤฑtฤฑlan ve aslฤฑnda biz Android geliลtiricileri oldukรงa heyecanlandฤฑran en รถnemli geliลmelerden biri de Lifecyle-Aware Component’lerdi. Ben de yeni hakkฤฑnda detaylฤฑ bir yazma fฤฑrsatฤฑ bulabiliyorum. 22 Temmuz’da Google Dome’da GDG Istanbul olarak gerรงekleลtireceฤimiz codelab’in konularฤฑndan biri de bu componentler. Merak edenlerle hep beraber inceleyebiliriz.
Componentlerin detaylarฤฑnฤฑ konuลmaya baลlamadan Android Activity Lifecycle’ฤฑ bir hatฤฑrlamakta fayda var. Aลaฤฤฑdaki imaj aslฤฑnda bize tรผm akฤฑลฤฑ รถzetlemiล oluyor. Activity launch edildiฤinde sฤฑrasฤฑyla onCreate(Activity’nin yaratฤฑldฤฑฤฤฑ state), onStart(Activity’nin kullanฤฑcฤฑya visible olduฤu state), onResume methodlarฤฑ trigger ediliyor ve Activity run edilmiล oluyor. Eฤer รผzerinde baลka bir activity aรงฤฑlฤฑrsa, baลka bir app’e giderse vs onPause methodu รงaฤrฤฑlฤฑyor. Activity sistem tarafฤฑndan sonlanฤฑyorsa ise onPause ardฤฑndan, onStop(Activity tamamen gรถrรผnmez olur) ve onDestroy methodlarฤฑ da tetikleniyor. Eฤer ki memory ihtiyacฤฑ sebebiyle sonlanmฤฑลsa onDestroy’a girmeden sonlanฤฑp tekrar aรงฤฑldฤฑฤฤฑndan en baลtan, yani onCreate’den sรผreรง baลlฤฑyor. Ancak baลka bir Activity aรงmak ya da farklฤฑ bir app’e geรงip geri gelmek iรงin Acitivity’den รงฤฑkฤฑldฤฑysa en baลtan create edilmeyeceฤi iรงin onCreate’e girmeyecektir. Bu durumda onResume’dan devam eder. Bu sebeple eฤer ki onPause’da activity’den รงฤฑktฤฑฤฤฑ iรงin yaptฤฑฤฤฑmฤฑz bir ลey var ise, bunun karลฤฑlฤฑฤฤฑna onResume’da dikkat etmemiz gerekir. onPause’la ilgili bir baลka dikkat etmemiz gereken nokta Android 7’yle beraber multiwindow geldiฤinden beri sadece bir tek acitivity aynฤฑ anda focus alabileceฤi iรงin biri focus aldฤฑฤฤฑnda diฤerinin onPause’a dรผลecek olmasฤฑdฤฑr. Aynฤฑ zamanda Activity’imizin รผzerine bir diyalog aรงฤฑldฤฑฤฤฑnda da gรถrรผnmesine raฤmen focus รผzerinde olmayacaฤฤฑ iรงin onPause methoduna girecektir. Tabiki bu methodlarฤฑn hepsini implement etmek zorunda deฤiliz ama yapฤฑlan iลin ne kadar kompleks olduฤuna gรถre hangilerinin implement edilmesi gerektiฤi deฤiลecektir, bunun iรงin de her birinin ne zaman trigger edildiฤini detaylฤฑ olarak bilmek รงok รถnemlidir.
https://developer.android.com/guide/components/activities/activity-lifecycle.html
Peki o zaman Architecture componentlerin neden kullanmalฤฑyฤฑz, niรงin hayatฤฑmฤฑza girdi dersek. Bu componentler, data tutarlฤฑlฤฑฤฤฑnฤฑ, lifecycle’ฤฑ yรถnetmemize yardฤฑmcฤฑ olmayฤฑ, uygulamamฤฑzฤฑn modรผler olmasฤฑ, memory leak’lerden kaรงฤฑnmamฤฑza ve tekrar eden kodlardan kurtulmamฤฑza yardฤฑmcฤฑ olmayฤฑ amaรงlฤฑyor. Tabi ki daha รถnce de her birimiz รงeลitli yollarla bunu saฤlฤฑyorduk. Bu bazen bir lib kullanmak bazense kendi geliลtirdiฤimiz bir รงรถzรผm olabiliyordu.
Livedata temel olarak datadaki deฤiลiklikleri izlememizi saฤlayan observable bir data holderdฤฑr. Data deฤiลikliklerindeki bizi notify eder, bรถylece ui’ฤฑ deฤiลtirebiliriz. Livedata abstract class’dฤฑr, extend edebilir ya da MutableLiveData’yฤฑ kullanabiliriz. LiveData’yฤฑ Room‘la beraber kullandฤฑฤฤฑmฤฑzda ise daha iyi sonuรงlar elde edebiliriz. Livedata kullanฤฑmฤฑna รถrnek ekranda gรถsterdiฤimiz listenin datanฤฑn deฤiลtiฤinde RecyclerView’i otomatik update etmesi olabilir mesela. LiveData LifeCycle aware bir componentdir. Aslฤฑnda en รถnemli รถzelliฤi de burada karลฤฑmฤฑza รงฤฑkฤฑyor. รรผnkรผ daha รถnce benzeri geliลtirmeler yaptฤฑฤฤฑmฤฑzda yaลabileceฤimiz crashlerin Android’in kendisi tarafฤฑndan handle edilmesini saฤlฤฑyor. Lifecycle-aware demekle yazฤฑnฤฑn baลฤฑndaki Activity’yi รถrnek alarak รผzerine konuลtuฤumuz state’leri dรผลรผnebileceฤiniz gibi fragmentleri, servisleri de dรผลรผnebilirsiniz. ลรถyle รถzetleyebiliriz; Livedata activity’nizin ekranda mฤฑ, deฤil mi yoksa tamamen destroy mu olduฤunu bilir ve updateleri buna gรถre gรถnderir. Bunun iรงin ise iki interface vardฤฑr. Biri lifecycle owners, activity’ler, fragmentler; diฤeri ise livecycle observers, livecycle owner’ฤฑ izleyip, lifecycle observerslarฤฑ notifiy eder. UI componentleri LiveData’yฤฑ, LiveData da LifeCycleOwner’larฤฑ observe eder.
Peki geriye bir tek ลey kalฤฑyor. Artฤฑk bizim componentlerimiz de Activity, Fragment’in state’lerinden haberdar ancak, รถrneฤin her konfigรผrasyon deฤiลikliฤinde, telefonu rotate ettiฤimizde de yeniden LiveData’nฤฑn create olmamasฤฑ datayฤฑ korumasฤฑ gerekir. Bunu da ViewModel‘le yapฤฑyoruz. Bunun iรงin de Activity’imiz iรงin gerekli olan tรผm datayฤฑ tutacaฤฤฑmฤฑz bir class yaratฤฑp bunu AndroidViewModel’den extends etmemiz gerekir.
Her bir senaryo iรงin mรผkemmel รงalฤฑลacak bir mimari kurmak biraz zor olabilir ama architecture components’i developer.android‘de anlatฤฑldฤฑฤฤฑ ลekilde aรงฤฑklamaya รงalฤฑลacaฤฤฑm.
Daha รถnce de yazdฤฑฤฤฑm gibi, ViewModel Activity,Fragment iรงin gerekli olan datanฤฑn tutulmasฤฑndan sorumlu olacak. Ancak sorumluluฤu bununla sฤฑnฤฑrlฤฑ kalฤฑr. Activity, Fragment’in recreation’larฤฑndan, konfigรผrasyon deฤiลikliklerinden etkilenmez.
Bu durumda รถrneฤin bir kullanฤฑcฤฑ sayfamฤฑz olacaksa, bunun activity ya da fragment ve xml’ine ek olarak bir de ViewModel sฤฑnฤฑfฤฑmฤฑz olacak.
Bu arada yine developer.android’de yazฤฑlana gรถre ลu an bu yapฤฑ stabil olmadฤฑฤฤฑ iรงin eฤer kullanmak istiyorsak, LifecycleFragment’den extend ederek kullanmamฤฑz gerekiyor. Ama stabil olduktan sonra Fragment’den extend etmemiz yeterli olacakmฤฑล.
ลu an 3 modรผlรผmรผz oldu. Bunlarฤฑ nasฤฑl baฤlayacaฤฤฑmฤฑzฤฑn cevabฤฑ ise LiveData. LiveData observable bir object. Data deฤiลikliklerinde UI’ฤฑ trigger ediyor. รncesinde bunu kendi geliลtirdiฤimiz รงeลitli yรถntemlerle ya da RxJava gibi kรผtรผphanelerle saฤlฤฑyorduk. LiveData’yla ilgili de en muhteลem ลey lifecycle-aware olmasฤฑ. ฤฐhtiyaรง olmadฤฑฤฤฑnda referanslarฤฑnฤฑ otomatik olarak temizlenmesi. Manuel yรถntemlerle geliลtirme yaptฤฑฤฤฑmฤฑz en hataya aรงฤฑk kฤฑsฤฑm da burasฤฑ olmuล oluyordu.
Artฤฑk LiveData data deฤiลtiฤinde bizi trigger ettiฤi iรงin, aลaฤฤฑdaki gibi bir yapฤฑ kurabiliriz. Bรถylece bir deฤiลiklik olduฤunda LiveData haber verecek ve biz de UI’ฤฑ update edebileceฤiz.
Data deฤiลtikรงe ui’ฤฑn nasฤฑl update edileceฤinden konuลtuk ama datayฤฑ nasฤฑl nerede รงekeceฤimizi konuลmadฤฑk. Bunu ViewModel iรงerisinde yapmak da bir รงรถzรผm olabilir ancak o zaman baลka ViewModel’lerde aynฤฑ data gerektiฤinde aynฤฑ kodu replike etmemiz gerekir ayrฤฑca birden fazla responsibility’nin aynฤฑ yerde implement edilmesine neden olur ki bu da seperation of concerns‘e uygun olmaz. Bu yรผzden datanฤฑn รงekilmesinden sorulu farklฤฑ bir class sรถz konusu olmaya baลlฤฑyor.
Aลaฤฤฑdaki รถrnek retrofit kullanฤฑldฤฑฤฤฑ varsayฤฑlarak yazฤฑlmฤฑล.
Bu iลlerden ise sorumlu olarak Repository modรผlleri atanabilir. Aslฤฑnda buna Repository yerine farklฤฑ bir isim de verilebilir ancak developer.android’in verdiฤi isimlendirmeye baฤlฤฑ kalmak bizi diฤer developerlarla ortak bir dil konuลmamฤฑzฤฑ saฤlar.
UserRepository ve ViewModel’i nasฤฑl baฤlayacaฤฤฑmฤฑz ise aลaฤฤฑdaki gibidir.
ลu ana kadar konuลmadฤฑฤฤฑmฤฑz konulardan biri de cache. Her app’in cache ihtiyacฤฑ bulunmamakla hatta bazฤฑlarฤฑn cacheleme yapmama zorunluluฤu olmasฤฑyla birlikte ihtiyaรง durumunda bu da Repository’nin sorumluluฤunda olmalฤฑdฤฑr. Eฤer cache de data varsa bunu dรถndรผrรผp yoksa yeni datayฤฑ รงekebilir.
Konuลmadฤฑฤฤฑmฤฑz bir diฤer konu da data’nฤฑn sรผrekliliฤi. ย Uygulama var olduฤu sรผrece burada cache iลimizi gรถrebilir. Ancak kullanฤฑcฤฑyฤฑ uygulama saatlerce bฤฑrakฤฑr ve Android sistemi de uygulamayฤฑ kill ederse iลler deฤiลir. Yukarฤฑdaki implementasyon bu case’de datanฤฑn tekrar รงekilmesini saฤlar. app’inizin yapฤฑsฤฑ gereฤi buna ihtiyacฤฑnฤฑz olacaฤฤฑ gibi, ihtiyacฤฑnฤฑz yoksa bu hem kullanฤฑcฤฑ iรงin kรถtรผ bir deneyim de gereksiz mobil data kullanฤฑmฤฑ olacaktฤฑr. Yine architecture componentlerle beraber hayatฤฑmฤฑza giren Room da bu soruna cevap iรงin geliลtirilmiล durumda. Room’un รงรถzรผmรผ SQLite ORM ya da Realm ฤฑn sunduฤunda benzer bir รงรถzรผm aslฤฑnda. Ancak bu yazฤฑda Room’a รงok fazla girmek istemiyorum. รzetle local storage yapฤฑyor olarak dรผลรผnebiliriz.
Umarฤฑm architecture components’in neden รงฤฑktฤฑฤฤฑ ve nasฤฑl kullanฤฑlacaฤฤฑ hakkฤฑnda genel bir bakฤฑล aรงฤฑsฤฑ yaratabilmiลimdir. Daha detaylฤฑ yazฤฑlar da paylaลmaya รงalฤฑลacaฤฤฑm. ๐
Referanslar:
- https://codelabs.developers.google.com/codelabs/android-lifecycles/index.html?index=..%2F..%2Fio2017#0
- https://developer.android.com/guide/components/activities/activity-lifecycle.html
- https://developer.android.com/topic/libraries/architecture/index.html
- https://www.youtube.com/watch?v=vOJCrbr144o
- https://developer.android.com/topic/libraries/architecture/guide.html
3 responses to “Android Lifecycle-Aware components”
Teลekkรผrler (:
[…] รถnce Android architecture component hakkฤฑnda genel bir bilgi toplamaya รงalฤฑลmฤฑลtฤฑm. Aslฤฑnda belki de รถncesinde bugรผnlere […]
Gรผzel bir anlatฤฑm olmuล, teลekkรผrler.