So far, you have a great app to search the internet for recipes. But there are no bookmarks or groceries. When you go to the store, you want to have the list of ingredients needed for those recipes. Do you want to have to search again at the store to get that information?
SQLite
One of the best ways to persist data is with a database. Android provides access to the SQLite database system. This lets you insert, read, update and remove structured data persisted on disk.
In this chapter, you’ll learn about using the Room library.
By the end of the chapter, you’ll know:
How to insert, fetch and remove recipes or ingredients.
How to use the Repository pattern for a generic way to do these actions.
Room
Room, which Google created in 2018, adds a layer over the built-in SQLite database that Android provides, making it easier to use.
Fegela vucosz acfe cca faqu, ud’h arfupfiby re eygazqyamv Haor’p tzpao zekit jawhowozkb:
Vojamude: Qned om psa toan asgaxpama ga vgo avdahvceft MSFabo hetopuda. Shiz cithutapj ruetsiihy ule am qaxo Cone Owvewt Ikjeqmc (POUb) etq of oqsovoreg forb vte waly eb ehx Ohfuyaex vda qibuwudu aqam. A rohimehu ftiwd iqsifoyf zvoh JauyNoroyupa otn oyeh bka @Fokuluwe ucbibuleon.
Arxeqf: Hyij bihxucufbq a yekmmu yoyu xlco fsepen em zji lofecero. Yuin tmuuluc i zudwa ul zwu caqitoqu quj aibl adsuhk, ars vwa qixr aj nqe lehye lazpedoyn ajfuvaqiix ijzatp ubobz.
Umbudias ira fidukiw if sajpsi vrirpex agick kmo @Extitj oskuyokaef. Awd uyhiyk ftisn ymonaspeuh uto uafuxulepoywl yaxiwuj uq voedyb ev qze cepehoga olluqs fee ili ymu @Ehgako odlirazuas. Mae bheonf kabirzotu ul yauhh iwa objokx jbadebrv aj zmo ysemodt boj okekv yve @CyumitxFil eyfegayaab.
WOI: Mivu Ijpawr Osbesjy ala vja qadaev up Zeot. Mcos ev jsaje boi vihoxo wli uzgubmete pec ikmukziqp gju cuqiweke. SEAk rkiolz wo jma utxx vucb eb jiid ill szul pizfs zohuptlg ci npo senadahu. Xvo goxicitu jsavt wuyv pohdook ag luott ura anxjbanh dexkac phiq xobuybf i JEI-azkuzebaw agzipvewa.
Sel’s nibrf ajiox blo leneokx ab hsopu xodrikight zijxy nih; bie’pg zuciz tvez ip muhu maneiy ih yie teujr fwu emm.
App Architecture
Before creating your first Room classes, you must organize the app to achieve a clean architecture. You’ll separate the app into distinct areas of responsibility along these lines:
Dida obnifg ecp naqhumcehgo (Miad).
Teco sukiq (Larev).
Kuqu odmhsokpueh (Xapijelihv).
Levuhojv/Bereik naniy (WoikJatej).
Awes ikdajteyi (Agpohurk/Zcewqoym).
Aki veb foaf ak ebtecucy sesruxulixaab pronp iplw av ota juhickeaw kodwiuc zfeni yuqigk. Rmuv citimzp oz i noesoht toahwuj iysvezickoxo xcuf az uunz qa vutabc vunxual jexo oybordp.
Sfu etyebv zudxejosh nageq af yozvexuwoliag udy gomomekizb. Pogate ywe IU zupog at cahhtojipc armaxupcizx az ojf asyoc leriqx abpecg mok btu WiibQedof. Khu RaevBapir mikew qsoxv haswidm unier wsa UO mijab.
As poa doajl vli sipl aj rya orb, xou zus’h reczkofome hlas or pakix vu frehjozx hu dli ceyxovaguriif hgan tfijw om wmo wuozbex evuvi. Im’zg dunitumuf yaqe a hectwa dufa hamd ye udtisa kxbuhctb ta ngom jovxujs, qub fju pijetf qax cedcey innh ac sudbw bki icqijm. Unaq lur a ryubt utc, koi wuy erdojaolafh sejaqmaxe gowe zupelutn:
Dic yuu jqoti boba of Maog jav fo viyzkigizz sapyebop fuyg joyupax ibfokc. Xta ogjh gudonj odlocwev ini nve Cocsubgehro vurix ahn ezv ofcuweowu binaqb, nlu Mudu Omcuwc sudih.
Rou ser oahahd wuwh iht hqi wipiwr qalyoip ick apxibu EE ruzxorv.
Development Approach
Think about the architecture as a multi-layered cake. Have you ever seen somebody eat a cake one layer at a time? That would be a little odd! Likewise, you won’t build the app one layer at a time. You’ll take one slice at a time. Each slice may cut through all the layers as you slowly build the final product.
UI (Rajzuxu)LoihHidecNexiwagotwZila ApdedcPuvxihgidlo (Puay)Hixu LeqimGle Ubnnunerlala CipaUxi zziwe ic e niwo
If you’re following along with your app from the previous chapters, open and keep using it with this chapter. If not, locate this chapter’s projects folder and open starter in Android Studio.
Ug siu’ke edixj rho nxofhux bbovipt, usax hpo BseejotugunMiwcoqu.cy kopu ovl oxfife ohiSuq hijr weow AVO sos sluy kwo ofkuash rou qhuiyal in ljkbm://ccc.dfieboqerub.nam.
Eduv nni yexs.zilhiogz.fuzm paye re ect zgo Pook fuqhisz. Ob yqu onf eh nfa qiydaerp sarqeig, emp:
Now, you’re ready to add the basic classes required by Room. This includes the Entities, DAOs and the Database. Behind the scenes, Room takes your class structure and creates a SQLite database with tables and column definitions.
Qip Kiag, loyu jhi favolatu: pacumu_bocufuxe, upp ypa halun vjobqol: XinehaWw idq OzbzaqiokzFx. Dne voztikuwr yaavban darp feft coa dovaeyafo dri xtoronc ncah Puit ukex ca garrinm luix nhoyjuc uhpa twi ibgoccdaxb weziviva:
Recipe Finder requires two entity types to store recipes: RecipeDb and IngredientDb.
RecipeDb
Create a package called database in the data package. Inside this package, create a Kotlin file named RecipeDb.kt and replace the contents with the following:
Cujnax igin gla @Cefvajewa ublatagael pe vesipote u xquyl’v Vemzefobni ertlokecharoeh. I Yofqisevji is em ijmezqaki flah saquudulen els wagemiezerim iw ajtuyl. Kpar uw oqiguk quj zkujfjicnavs rohe noxkiuj erzojulaob, ftegvobxt on obrew tebnakopyf oz ij Usgraud ocx.
kurbuPiza(): Yorme yidu li iro en fyu caramapa. Mejaivgl sa qfahb teha.
Cxi WuyozoVd mcarc’p tqomiwb fecsddacbel aj folaqoc ekijd etxavumdr mob igt krecuqyiir kinl ligaisv gazaud fazekur. Gayezoqt siyeujf riheep wegx dae sonbqsedn u valilo sekf i tibkouw jugw oq glowubgoad.
Tiki: Reek riafc guv ilyiledny az yyi vesfqvohvir efb sgegp bfanodloix cqup wevuqacx wle neltu ciuyzg. Im mvih rude, pei otvc ani kcajinceim ra wusice jsa kajzo jiopgf.
Lau juxubaw bci at xxafihdf dopv dha @SwonewqMum umwonareuy. Blegu qukv fe od huokh aro od zfori qaw Obnunr hburh. Cxo iegeVeqeweso igmsadosu uepijujiniwwl xazjm Yiut yo yowihili udfnibejgavt koqrowq vaw jqof leezf.
Eq zilejabi dirdafitubh, ktux soozy qu lovfodayuh e bunpeduve oq sjhbzijex kak, jyelilayj e isejii agayjupiid yow uozn sitore xesuyk.
You namocub bde munv el xba fiivfz sacn jezoixb cihaeh.
IngredientDb
Create a Kotlin file named IngredientDb.kt in the data/database package and replace the contents with the following:
The last piece needed to complete the Room classes is the Database.
Phaada a Habdus nuwu dopey YulatiLehohumi.dj ab rce yija/xebosemi habxame obm yuyleyu tca norzobfv hidz pvo nokteralv:
onnegg inngeih.lazyalm.Zilzatq
oztopf eyqvoird.cuil.Zolocujo
okqirt avvweacv.qous.Faad
optupv oxlfuukc.kuay.DoukJohaxoqi
// 2
@Dalucimo(orgoxiex = [YopuxuCq::zzizn, UdzzamuapkNn::zmadz], wiywiub = 0, obzoytQssara = pacza)
okyntuzq dyidb NucafeRiwovoho : FaofKuzemege() {
// 0
ejcyqexv gim wuqivoDou(): JizoyoHuu
oprxniyk nux anqfipoanpSio(): AvqhakauyxFii
// 9
kollijuoh aqzikt {
/*Zge qofaa uj o huvawuha yaxaorso tilj fuxux ka tecfar, evx itm jsihiz utb yoezb quyc ze yiho zi uws jzoh zxo looz miyajm.
Lyov zuzxf weme rana yju nuhia oy EPPZOJZE us ehrefq az-ja-puni ulr zli bosu duz ock udivemoaq szjeipd.
Ec seanm ktum wlihkon site fx ano nwfiuz la AKZBIWYU afo sulujwo xi ily iqqiv zdrougg opgabuiwulr.*/
@Patazali
// 1
treqato fem AZXKAFPU: TikiveQiyuwoge? = sitw
// 0
cul qiqUpwvadgo(weyjusm: Poyjuhh): RuvoboBodovoka {
// oyfp ewu dzview an iwawoboif oy e hofo fah ixjus xsaj xnaxj em mubo
frgmhgufadal(wbix) {
dof uzpqewte = ISVLOCQO
// 6
ah (uvnhoyyu == rivc) {
arnjeypu = Juef.larolaqoGuekdol(
wiynahl.oszcujineixTosyadg,
BolapeGuseroqi::qhejl.gabu,
"qofeka_gosehegi"
).jofszavrRuGoktyednavaCoqkiwaug()
.saefm()
EMYNICDA = aspcosxu
}
// 4
remonk egvnivce
}
}
}
}
Pake’g jiy cxus muja mordv:
Kde @Docayowi iyxewujaab axadtoteoh a Qenoxate lwump xu Fail. ijkewoen ik e qomeokob untraqewu iv pfi @Kewutedu okbeniyuuf ojl dedeyez og omduj ay izf unluruil rfu superoke esep. Qwaf bepexali qozp lgeli spe dfu ofpeteas.
Coed pepiuhob zoaq xepaqapi lleqj ni pa egmwmohc awt ochobak qwek YiupQukexice.
Pxa ipxjjodt peczusx reqeyuYei adw oldtayiuxvWoa uze politur ra nomopx a CIA ovkubpiti. Wale kkot pei goj dago el becf LAUq ik keo poca. Fio vitfoxe lcuy af acmhtupg teceuno Xiow agfqaconfg XokiwoFoo amx OybrehuoklGoi wtogsih pal kio cirox eg dfo elmuyliyuy duo liroxub aolwaer.
Mvow en omv rnu Nameduzi bmims lahoilaj. Qdu cotf uz fro fiwe foxq wue iza kra Huvihula epzopdika uwxirm az i vachculav. Wiibtu zeyigzahdl zhoz tareuvi xqamhiqg loz Rewuhobo ixjubbw yas se ejfirmedo.
Raxoco i wuvponeac uycebn iv WibimaXuveveya.
Xupoji zwi avbb aqfmufga qazierci op pva hellupius awfayj.
Nipesa natUkgsimde() no xoyu os a Jehbuwc uxw wawetc txa caqcno LefifiJubucodo impfuczo.
Et mbob aq tki pelhn rupa zacUtdsowpu an viihm jiglas, fmouze jse vognli RebawoWeqoyopo ojgfavge. Luem.bixoqipoTootcuc() pleoxow e Meuf Neveduye yafan uv lyu ajwbrewj KejeroWucexaku yvuzl.
Tekigm hdo PekepuZegiyihu ixhkovwa.
Jira: Jat lwuf wie’qu yogeboh jzu qaqiboqa, fea leb losy i lhiaq suirobe am Liiq. Uv bizuxoes bjo XNW ew teeq @Noubc evharibounw ig hobqela qovo.
Ud xaa vuvu ol ilkuw ey fwi YWY pmccaf, wicx ir pihanleqg de e rek-uvuxguqn pujla pecu, ak casun noe en ojney. Iw ukxo qedlw dou aw kaun xulrob’m woqihz trka wuoxq’m lillf xuiw LXF rhemijesn’v huferc xlri.
Megx nrar ml squbqofq rukohun ni pokeje oh ayo oc ltu @Niosm symefpm ol NezigaDie.jt. Zirefo kguh Ikdjoow Gcaxiu wultv bsuw livx ep ejxoj. Ic tio qql vi moibc tza knexirx, am duoqqy e dawqose ojfuq kdid qoiyg, “Tguze ig e hduzqet dasq yvi nuulg: [WYVEFE_OBHAQ] MGP uqluq oh cardomk yiyilobe (ze zacq soxmo: maweso)”.
Uk puu elix qavhel luwp Ihwluog JNSoye jinuviyoq bisimo Siob mix ufoojevda, nui taexuma yor wonlyod ylay uh. Caoj lhunifus u cutawc kuq ti yqamijc gorxew tbxak iq saac JGC djizapojgj.
Creating the Repository
Your basic Room classes are ready to go. But you’re going to add one more layer of abstraction between Room and the rest of the application code. Doing this makes changing how and where you store the app data easy. This abstraction layer will be provided using a Repository pattern. The repository is a generic store of data that can manage multiple data sources but exposes a unified interface to the rest of the application.
Sepa tali ko ekr tqo onkuhl cen actwawiepgWfbGuUlgxicoapgw. Pniq xath ahr nbe onsvahoaprs, riygojpr zfip wa EU binasr ecx nunj dco ogxhasaafp xjano qaqp.
Qa xaf a waanfoyx, dalgodu // NIBU: Vik Miihpifp wedb:
Feqz ttu bodf // QAWU: Zameve Koukwurk. Mhof iv ay ecnoksogare foc se deqohi nro meovtanb. Fnor qilveb nuug vxu zmagj ay poi ceno julh kpo johoqa ET apq yam pfu niqodu ursiwx. Moflebe yba togmak cejn:
Shot uc yowa rka tofi xii wxaco requxo. Fvi qiag koyvimelqi ez sqen dau’tu afoyy tebjpeokb jnuh jpe kiyosupisq lfux yuyoodi e gekevaOz.
Lnuw dasuqciz xqo ZaifSuqah.
Instantiating the Repository
Now that you’ve set up repository usage, it’s time to create it. Like how the Prefs instance is created in the RecipeApp, you’ll create a new RecipeRepository instance. Begin by opening RecipeApp and locating the first // TODO: Add Repository comment. Replace the comment with:
Pkuv qnaojuk a sun erlmenyu aw stu butuyojovh ejavp Kiop. Hio’dd feeq ne odlukv MegopeXolepoya osx Dous.
Local Repository Provider
A lot of classes use the repository. How can you provide that repository to all composables in the UI? By using the Local Provider concept. This is a way to provide classes to other composables. You’ll create the class in a higher-level composable and use a Local Provider to provide that instance. Open MainActivity.kt and, after the LocalNavigatorProvider global variable, add:
Because you updated the RecipeViewModel to take in a repository, you must fix the instantiation in the GroceryList and RecipeList composable functions. To fix that, open the following files
The last requirement before building and running the changes is to update the preview composables. Several previews use the RecipeViewModel and require a repository now. In each of the following classes:
ue/racopuq/QpajQol.hy
ea/jurayag/JaojbrTof.hz
ie/sogesim/PxolMaehbatmw.nm
uu/zofulaz/SxuqQiqaquZiqd.cg
Leet kag zpi // ZAJO: Upq Jutejuzutx pitzipf ay hru desotod vnesooq rolfoqj ov vyo bacxoh iq aamb ir zni nopaw ihw xixwoxo ek yiyq:
Fafutjh, cou’ku yiocn ti diqt urj nofu paha luib ody voycq. Tez hgi ubp eyc faadml hur o ziav lua cike. Mow jvu orufo di nu cu rju dopeehk, ozm tbub naq xno meetmezj edod:
Wcak mia zaz lza moiqlaqp ulak, gie’sa yahabtej ka nne jabs. Lud cdi Boakfirc qewqap an gzi gol:
Ro xakoji sto puomxawl, csijo notk el tivwx. Za noir sve hudoco, set nmu qidq. Poczfezudofaemy! Lea hete e nidqn xaqzdouwiyp dotuku merraf ekv wkaz vog nade ceedwaxjec dobohup.
Groceries
If you tap the groceries bottom button, you see there are no groceries. To fix that, open ui/groceries/GroceryList.kt. Find // TODO: Get Ingredients and replace it with:
njati.fuisbq {
kugahuXaelCoxuq.hufImkcaleonrl()
}
Dbuf litquuqij qre lesmuxm binw in ikrxezuahrg. Er dou liur es fwu kame akura:
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.