CINXE.COM

<!doctype html><html lang="en"><head><title data-rh="true">Now In Android with Koin — part 4 | by Arnaud Giuliani | ProAndroidDev</title><meta data-rh="true" charset="utf-8"/><meta data-rh="true" name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1,maximum-scale=1"/><meta data-rh="true" name="theme-color" content="#000000"/><meta data-rh="true" name="twitter:app:name:iphone" content="Medium"/><meta data-rh="true" name="twitter:app:id:iphone" content="828256236"/><meta data-rh="true" property="al:ios:app_name" content="Medium"/><meta data-rh="true" property="al:ios:app_store_id" content="828256236"/><meta data-rh="true" property="al:android:package" content="com.medium.reader"/><meta data-rh="true" property="fb:app_id" content="542599432471018"/><meta data-rh="true" property="og:site_name" content="Medium"/><meta data-rh="true" property="og:type" content="article"/><meta data-rh="true" property="article:published_time" content="2023-04-17T15:16:50.767Z"/><meta data-rh="true" name="title" content="Now In Android with Koin — part 4 | by Arnaud Giuliani | ProAndroidDev"/><meta data-rh="true" property="og:title" content="Now In Android with Koin — part 4"/><meta data-rh="true" property="al:android:url" content="medium://p/fbdc855824ad"/><meta data-rh="true" property="al:ios:url" content="medium://p/fbdc855824ad"/><meta data-rh="true" property="al:android:app_name" content="Medium"/><meta data-rh="true" name="description" content="Now In Android is an open-source Android application that covers Modern Android Development best practices. The project is maintained by the Google Android team. I propose to continue our tour with…"/><meta data-rh="true" property="og:description" content="Let’s use Koin Annotations instead of Koin DSL to configure DI injection in Google’s NowInAndroid app"/><meta data-rh="true" property="og:url" content="https://proandroiddev.com/now-in-android-with-koin-part-4-fbdc855824ad"/><meta data-rh="true" property="al:web:url" content="https://proandroiddev.com/now-in-android-with-koin-part-4-fbdc855824ad"/><meta data-rh="true" property="og:image" content="https://miro.medium.com/v2/resize:fit:1200/1*hVKWuT24riZnx4VzDpQVJQ.png"/><meta data-rh="true" property="article:author" content="https://giuliani-arnaud.medium.com"/><meta data-rh="true" name="author" content="Arnaud Giuliani"/><meta data-rh="true" name="robots" content="index,noarchive,follow,max-image-preview:large"/><meta data-rh="true" name="referrer" content="unsafe-url"/><meta data-rh="true" property="twitter:title" content="Now In Android with Koin — part 4"/><meta data-rh="true" name="twitter:site" content="@proandroiddev"/><meta data-rh="true" name="twitter:app:url:iphone" content="medium://p/fbdc855824ad"/><meta data-rh="true" property="twitter:description" content="Let’s use Koin Annotations instead of Koin DSL to configure DI injection in Google’s NowInAndroid app"/><meta data-rh="true" name="twitter:image:src" content="https://miro.medium.com/v2/resize:fit:1200/1*hVKWuT24riZnx4VzDpQVJQ.png"/><meta data-rh="true" name="twitter:card" content="summary_large_image"/><meta data-rh="true" name="twitter:label1" content="Reading time"/><meta data-rh="true" name="twitter:data1" content="6 min read"/><link data-rh="true" rel="icon" href="https://miro.medium.com/v2/resize:fill:256:256/1*A8VytPZQhvUf_MG6hm_Dlw.png"/><link data-rh="true" rel="search" type="application/opensearchdescription+xml" title="Medium" href="/osd.xml"/><link data-rh="true" rel="apple-touch-icon" sizes="152x152" href="https://miro.medium.com/v2/resize:fill:304:304/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="120x120" href="https://miro.medium.com/v2/resize:fill:240:240/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="76x76" href="https://miro.medium.com/v2/resize:fill:152:152/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="60x60" href="https://miro.medium.com/v2/resize:fill:120:120/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="mask-icon" href="https://miro.medium.com/v2/resize:fill:1000:1000/7*GAOKVe--MXbEJmV9230oOQ.png" color="#171717"/><link data-rh="true" id="glyph_preload_link" rel="preload" as="style" type="text/css" href="https://glyph.medium.com/css/unbound.css"/><link data-rh="true" id="glyph_link" rel="stylesheet" type="text/css" href="https://glyph.medium.com/css/unbound.css"/><link data-rh="true" rel="author" href="https://giuliani-arnaud.medium.com"/><link data-rh="true" rel="canonical" href="https://proandroiddev.com/now-in-android-with-koin-part-4-fbdc855824ad"/><link data-rh="true" rel="alternate" href="android-app://com.medium.reader/https/medium.com/p/fbdc855824ad"/><script data-rh="true" type="application/ld+json">{"@context":"http:\u002F\u002Fschema.org","@type":"NewsArticle","image":["https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1200\u002F1*hVKWuT24riZnx4VzDpQVJQ.png"],"url":"https:\u002F\u002Fproandroiddev.com\u002Fnow-in-android-with-koin-part-4-fbdc855824ad","dateCreated":"2023-04-04T14:22:06.934Z","datePublished":"2023-04-04T14:22:06.934Z","dateModified":"2023-04-17T15:16:50.767Z","headline":"Now In Android with Koin — part 4 - ProAndroidDev","name":"Now In Android with Koin — part 4 - ProAndroidDev","description":"Now In Android is an open-source Android application that covers Modern Android Development best practices. The project is maintained by the Google Android team. I propose to continue our tour with…","identifier":"fbdc855824ad","author":{"@type":"Person","name":"Arnaud Giuliani","url":"https:\u002F\u002Fgiuliani-arnaud.medium.com"},"creator":["Arnaud Giuliani"],"publisher":{"@type":"Organization","name":"ProAndroidDev","url":"proandroiddev.com","logo":{"@type":"ImageObject","width":272,"height":60,"url":"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:544\u002F7*V1_7XP4snlmqrc_0Njontw.png"}},"mainEntityOfPage":"https:\u002F\u002Fproandroiddev.com\u002Fnow-in-android-with-koin-part-4-fbdc855824ad"}</script><style type="text/css" data-fela-rehydration="605" data-fela-type="STATIC">html{box-sizing:border-box;-webkit-text-size-adjust:100%}*, *:before, *:after{box-sizing:inherit}body{margin:0;padding:0;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;color:rgba(0,0,0,0.8);position:relative;min-height:100vh}h1, h2, h3, h4, h5, h6, dl, dd, ol, ul, menu, figure, blockquote, p, pre, form{margin:0}menu, ol, ul{padding:0;list-style:none;list-style-image:none}main{display:block}a{color:inherit;text-decoration:none}a, button, input{-webkit-tap-highlight-color:transparent}img, svg{vertical-align:middle}button{background:transparent;overflow:visible}button, input, optgroup, select, textarea{margin:0}:root{--reach-tabs:1;--reach-menu-button:1}#speechify-root{font-family:Sohne, sans-serif}div[data-popper-reference-hidden="true"]{visibility:hidden;pointer-events:none}.grecaptcha-badge{visibility:hidden} /*XCode style (c) Angel Garcia <angelgarcia.mail@gmail.com>*/.hljs {background: #fff;color: black; }/* Gray DOCTYPE selectors like WebKit */ .xml .hljs-meta {color: #c0c0c0; }.hljs-comment, .hljs-quote {color: #007400; }.hljs-tag, .hljs-attribute, .hljs-keyword, .hljs-selector-tag, .hljs-literal, .hljs-name {color: #aa0d91; }.hljs-variable, .hljs-template-variable {color: #3F6E74; }.hljs-code, .hljs-string, .hljs-meta .hljs-string {color: #c41a16; }.hljs-regexp, .hljs-link {color: #0E0EFF; }.hljs-title, .hljs-symbol, .hljs-bullet, .hljs-number {color: #1c00cf; }.hljs-section, .hljs-meta {color: #643820; }.hljs-title.class_, .hljs-class .hljs-title, .hljs-type, .hljs-built_in, .hljs-params {color: #5c2699; }.hljs-attr {color: #836C28; }.hljs-subst {color: #000; }.hljs-formula {background-color: #eee;font-style: italic; }.hljs-addition {background-color: #baeeba; }.hljs-deletion {background-color: #ffc8bd; }.hljs-selector-id, .hljs-selector-class {color: #9b703f; }.hljs-doctag, .hljs-strong {font-weight: bold; }.hljs-emphasis {font-style: italic; } </style><style type="text/css" data-fela-rehydration="605" data-fela-type="KEYFRAME">@-webkit-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@-moz-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}</style><style type="text/css" data-fela-rehydration="605" data-fela-type="RULE">.a{font-family:medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif}.b{font-weight:400}.c{background-color:rgba(255, 255, 255, 1)}.l{display:block}.m{position:sticky}.n{top:0}.o{z-index:500}.p{padding:0 24px}.q{align-items:center}.r{border-bottom:solid 1px #F2F2F2}.y{height:41px}.z{line-height:20px}.ab{display:flex}.ac{height:57px}.ae{flex:1 0 auto}.af{color:inherit}.ag{fill:inherit}.ah{font-size:inherit}.ai{border:inherit}.aj{font-family:inherit}.ak{letter-spacing:inherit}.al{font-weight:inherit}.am{padding:0}.an{margin:0}.ao{cursor:pointer}.ap:disabled{cursor:not-allowed}.aq:disabled{color:#6B6B6B}.ar:disabled{fill:#6B6B6B}.au{width:auto}.av path{fill:#242424}.aw{height:25px}.ax{margin-left:16px}.ay{border:none}.az{border-radius:20px}.ba{width:240px}.bb{background:#F9F9F9}.bc path{fill:#6B6B6B}.be{outline:none}.bf{font-family:sohne, "Helvetica Neue", Helvetica, Arial, sans-serif}.bg{font-size:14px}.bh{width:100%}.bi{padding:10px 20px 10px 0}.bj{background-color:transparent}.bk{color:#242424}.bl::placeholder{color:#6B6B6B}.bm{display:inline-block}.bn{margin-left:12px}.bo{margin-right:12px}.bp{border-radius:4px}.bq{margin-left:24px}.br{height:24px}.bx{background-color:#F9F9F9}.by{border-radius:50%}.bz{height:32px}.ca{width:32px}.cb{justify-content:center}.ch{max-width:680px}.ci{min-width:0}.cj{animation:k1 1.2s ease-in-out infinite}.ck{height:100vh}.cl{margin-bottom:16px}.cm{margin-top:48px}.cn{align-items:flex-start}.co{flex-direction:column}.cp{justify-content:space-between}.cq{margin-bottom:24px}.cw{width:80%}.cx{background-color:#F2F2F2}.dd{height:44px}.de{width:44px}.df{margin:auto 0}.dg{margin-bottom:4px}.dh{height:16px}.di{width:120px}.dj{width:80px}.dp{margin-bottom:8px}.dq{width:96%}.dr{width:98%}.ds{width:81%}.dt{margin-left:8px}.du{color:#6B6B6B}.dv{font-size:13px}.dw{height:100%}.ep{color:#FFFFFF}.eq{fill:#FFFFFF}.er{background:rgba(46, 152, 126, 1)}.es{border-color:rgba(46, 152, 126, 1)}.ew:disabled{cursor:inherit !important}.ex:disabled{opacity:0.3}.ey:disabled:hover{background:rgba(46, 152, 126, 1)}.ez:disabled:hover{border-color:rgba(46, 152, 126, 1)}.fa{border-radius:99em}.fb{border-width:1px}.fc{border-style:solid}.fd{box-sizing:border-box}.fe{text-decoration:none}.ff{text-align:center}.fi{margin-right:32px}.fj{position:relative}.fk{fill:#6B6B6B}.fn{background:transparent}.fo svg{margin-left:4px}.fp svg{fill:#6B6B6B}.fr{box-shadow:inset 0 0 0 1px rgba(0, 0, 0, 0.05)}.fs{position:absolute}.fz{margin:0 24px}.gd{background:rgba(255, 255, 255, 1)}.ge{border:1px solid #F2F2F2}.gf{box-shadow:0 1px 4px #F2F2F2}.gg{max-height:100vh}.gh{overflow-y:auto}.gi{left:0}.gj{top:calc(100vh + 100px)}.gk{bottom:calc(100vh + 100px)}.gl{width:10px}.gm{pointer-events:none}.gn{word-break:break-word}.go{word-wrap:break-word}.gp:after{display:block}.gq:after{content:""}.gr:after{clear:both}.gs{line-height:1.23}.gt{letter-spacing:0}.gu{font-style:normal}.gv{font-weight:700}.ia{align-items:baseline}.ib{width:48px}.ic{height:48px}.id{border:2px solid rgba(255, 255, 255, 1)}.ie{z-index:0}.if{box-shadow:none}.ig{border:1px solid rgba(0, 0, 0, 0.05)}.ih{margin-left:-12px}.ii{width:28px}.ij{height:28px}.ik{z-index:1}.il{width:24px}.im{margin-bottom:2px}.in{flex-wrap:nowrap}.io{font-size:16px}.ip{line-height:24px}.ir{margin:0 8px}.is{display:inline}.it{color:rgba(46, 152, 126, 1)}.iu{fill:rgba(46, 152, 126, 1)}.ix{flex:0 0 auto}.ja{flex-wrap:wrap}.jd{white-space:pre-wrap}.je{margin-right:4px}.jf{overflow:hidden}.jg{max-height:20px}.jh{text-overflow:ellipsis}.ji{display:-webkit-box}.jj{-webkit-line-clamp:1}.jk{-webkit-box-orient:vertical}.jl{word-break:break-all}.jn{padding-left:8px}.jo{padding-right:8px}.kp> *{flex-shrink:0}.kq{overflow-x:scroll}.kr::-webkit-scrollbar{display:none}.ks{scrollbar-width:none}.kt{-ms-overflow-style:none}.ku{width:74px}.kv{flex-direction:row}.kw{z-index:2}.kz{-webkit-user-select:none}.la{border:0}.lb{fill:rgba(117, 117, 117, 1)}.le{outline:0}.lf{user-select:none}.lg> svg{pointer-events:none}.lp{cursor:progress}.lq{margin-left:4px}.lr{margin-top:0px}.ls{opacity:1}.lt{padding:4px 0}.lw{width:16px}.ly{display:inline-flex}.me{max-width:100%}.mf{padding:8px 2px}.mg svg{color:#6B6B6B}.mx{margin-left:auto}.my{margin-right:auto}.mz{max-width:1920px}.nf{clear:both}.nh{cursor:zoom-in}.ni{z-index:auto}.nk{height:auto}.nl{margin-top:10px}.nm{max-width:728px}.np{text-decoration:underline}.nq{line-height:1.58}.nr{letter-spacing:-0.004em}.ns{font-family:source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif}.on{margin-bottom:-0.46em}.oo{box-shadow:inset 3px 0 0 0 #242424}.op{padding-left:23px}.oq{margin-left:-20px}.or{font-style:italic}.os{margin-top:32px}.ot{margin-bottom:14px}.ou{padding-top:24px}.ov{padding-bottom:10px}.ow{background-color:#000000}.ox{height:3px}.oy{width:3px}.oz{margin-right:20px}.pa{max-width:700px}.pg{line-height:1.12}.ph{letter-spacing:-0.022em}.pi{font-weight:600}.qd{margin-bottom:-0.28em}.qj{list-style-type:disc}.qk{margin-left:30px}.ql{padding-left:0px}.qr{padding:2px 4px}.qs{font-size:75%}.qt> strong{font-family:inherit}.qu{font-family:source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace}.qv{overflow-x:auto}.qw{padding:32px}.qx{border:1px solid #E5E5E5}.qy{line-height:1.4}.qz{margin-top:-0.2em}.ra{margin-bottom:-0.2em}.rb{white-space:pre}.rc{min-width:fit-content}.rd{max-width:820px}.re{max-width:433px}.rf{max-width:1140px}.rq{box-shadow:inset 0 0 0 1px #F2F2F2}.rr{padding:0px}.rs{padding:16px 20px}.rt{flex:1 1 auto}.rv{max-height:40px}.rw{-webkit-line-clamp:2}.rx{margin-top:8px}.ry{margin-top:12px}.rz{width:160px}.sa{background-image:url(https://miro.medium.com/v2/da:true/resize:fit:320/0*35z9MDbjpVM-dVAH)}.sb{background-origin:border-box}.sc{background-size:cover}.sd{height:167px}.se{background-position:50% 50%}.sf{margin-bottom:26px}.sg{margin-top:6px}.sh{margin-right:8px}.si{padding:8px 16px}.sj{border-radius:100px}.sk{transition:background 300ms ease}.sm{white-space:nowrap}.sn{border-top:none}.so{height:52px}.sp{max-height:52px}.sq{box-sizing:content-box}.sr{position:static}.st{max-width:155px}.te{height:0px}.tf{margin-bottom:40px}.tg{margin-bottom:48px}.tu{border-radius:2px}.tw{height:64px}.tx{width:64px}.ty{align-self:flex-end}.tz{color:rgba(255, 255, 255, 1)}.ua{fill:rgba(255, 255, 255, 1)}.ub{background:rgba(25, 25, 25, 1)}.uc{border-color:rgba(25, 25, 25, 1)}.uf:disabled{opacity:0.1}.ug:disabled:hover{background:rgba(25, 25, 25, 1)}.uh:disabled:hover{border-color:rgba(25, 25, 25, 1)}.un{padding-right:4px}.uo{font-weight:500}.vb{margin-top:16px}.vk{gap:18px}.vl{fill:rgba(61, 61, 61, 1)}.vn{fill:#242424}.vo{background:0}.vp{border-color:#242424}.vq:disabled:hover{color:#242424}.vr:disabled:hover{fill:#242424}.vs:disabled:hover{border-color:#242424}.wd{border-bottom:solid 1px #E5E5E5}.we{margin-top:72px}.wf{padding:24px 0}.wg{margin-bottom:0px}.wh{margin-right:16px}.as:hover:not(:disabled){color:rgba(25, 25, 25, 1)}.at:hover:not(:disabled){fill:rgba(25, 25, 25, 1)}.et:hover{background:rgba(50, 130, 108, 1)}.eu:hover{border-color:rgba(50, 130, 108, 1)}.ev:hover{cursor:pointer}.fl:hover{color:#242424}.fm:hover{fill:#242424}.fq:hover svg{fill:#242424}.ft:hover{background-color:rgba(0, 0, 0, 0.1)}.iq:hover{text-decoration:underline}.iv:hover:not(:disabled){color:rgba(50, 130, 108, 1)}.iw:hover:not(:disabled){fill:rgba(50, 130, 108, 1)}.ld:hover{fill:rgba(8, 8, 8, 1)}.lu:hover{fill:#000000}.lv:hover p{color:#000000}.lx:hover{color:#000000}.mh:hover svg{color:#000000}.sl:hover{background-color:#F2F2F2}.tv:hover{background-color:none}.ud:hover{background:#000000}.ue:hover{border-color:#242424}.vm:hover{fill:rgba(25, 25, 25, 1)}.bd:focus-within path{fill:#242424}.lc:focus{fill:rgba(8, 8, 8, 1)}.mi:focus svg{color:#000000}.nj:focus{transform:scale(1.01)}.lh:active{border-style:none}</style><style type="text/css" data-fela-rehydration="605" data-fela-type="RULE" media="all and (min-width: 1080px)">.d{display:none}.bw{width:64px}.cg{margin:0 64px}.cv{height:48px}.dc{margin-bottom:52px}.do{margin-bottom:48px}.ef{font-size:14px}.eg{line-height:20px}.em{font-size:13px}.eo{padding:5px 12px}.fh{display:flex}.fy{margin-bottom:68px}.gc{max-width:680px}.hq{font-size:42px}.hr{margin-top:1.19em}.hs{margin-bottom:32px}.ht{line-height:52px}.hu{letter-spacing:-0.011em}.hz{align-items:center}.kb{border-top:solid 1px #F2F2F2}.kc{border-bottom:solid 1px #F2F2F2}.kd{margin:32px 0 0}.ke{padding:3px 8px}.kn> *{margin-right:24px}.ko> :last-child{margin-right:0}.lo{margin-top:0px}.md{margin:0}.ne{margin-top:40px}.oj{font-size:20px}.ok{margin-top:2.14em}.ol{line-height:32px}.om{letter-spacing:-0.003em}.pf{margin-top:56px}.pz{font-size:24px}.qa{margin-top:1.95em}.qb{line-height:30px}.qc{letter-spacing:-0.016em}.qi{margin-top:0.94em}.qq{margin-top:1.14em}.rk{margin-top:1.25em}.rp{margin-top:32px}.sy{display:inline-block}.td{margin-bottom:104px}.th{flex-direction:row}.tk{margin-bottom:0}.tl{margin-right:20px}.ui{max-width:500px}.uz{line-height:24px}.va{letter-spacing:0}.vg{margin-bottom:88px}.vj{margin-bottom:72px}.vx{width:min-width}.wc{padding-top:72px}</style><style type="text/css" data-fela-rehydration="605" data-fela-type="RULE" media="all and (max-width: 1079.98px)">.e{display:none}.ln{margin-top:0px}.nn{margin-left:auto}.no{text-align:center}.sx{display:inline-block}</style><style type="text/css" data-fela-rehydration="605" data-fela-type="RULE" media="all and (max-width: 903.98px)">.f{display:none}.lm{margin-top:0px}.sw{display:inline-block}</style><style type="text/css" data-fela-rehydration="605" data-fela-type="RULE" media="all and (max-width: 727.98px)">.g{display:none}.lk{margin-top:0px}.ll{margin-right:0px}.ru{padding:10px 12px 10px}.sv{display:inline-block}</style><style type="text/css" data-fela-rehydration="605" data-fela-type="RULE" media="all and (max-width: 551.98px)">.h{display:none}.s{display:flex}.t{justify-content:space-between}.bs{width:24px}.cc{margin:0 24px}.cr{height:40px}.cy{margin-bottom:44px}.dk{margin-bottom:32px}.dx{font-size:13px}.dy{line-height:20px}.eh{padding:0px 8px 1px}.fu{margin-bottom:4px}.gw{font-size:32px}.gx{margin-top:1.01em}.gy{margin-bottom:24px}.gz{line-height:38px}.ha{letter-spacing:-0.014em}.hv{align-items:flex-start}.iy{flex-direction:column}.jb{margin-bottom:2px}.jp{margin:24px -24px 0}.jq{padding:0}.kf> *{margin-right:8px}.kg> :last-child{margin-right:24px}.kx{margin-left:0px}.li{margin-top:0px}.lj{margin-right:0px}.lz{margin:0}.mj{border:1px solid #F2F2F2}.mk{border-radius:99em}.ml{padding:0px 16px 0px 12px}.mm{height:38px}.mn{align-items:center}.mp svg{margin-right:8px}.na{margin-top:32px}.nt{font-size:18px}.nu{margin-top:1.56em}.nv{line-height:28px}.nw{letter-spacing:-0.003em}.pb{margin-top:40px}.pj{font-size:20px}.pk{margin-top:1.2em}.pl{line-height:24px}.pm{letter-spacing:0}.qe{margin-top:0.67em}.qm{margin-top:1.34em}.rg{margin-top:0.93em}.rl{margin-top:24px}.su{display:inline-block}.sz{margin-bottom:96px}.ts{margin-bottom:20px}.tt{margin-right:0}.um{max-width:100%}.up{font-size:24px}.uq{line-height:30px}.ur{letter-spacing:-0.016em}.vc{margin-bottom:64px}.vt{width:100%}.vy{padding-top:48px}.mo:hover{border-color:#E5E5E5}</style><style type="text/css" data-fela-rehydration="605" data-fela-type="RULE" media="all and (min-width: 904px) and (max-width: 1079.98px)">.i{display:none}.bv{width:64px}.cf{margin:0 64px}.cu{height:48px}.db{margin-bottom:52px}.dn{margin-bottom:48px}.ed{font-size:14px}.ee{line-height:20px}.ek{font-size:13px}.el{padding:5px 12px}.fg{display:flex}.fx{margin-bottom:68px}.gb{max-width:680px}.hl{font-size:42px}.hm{margin-top:1.19em}.hn{margin-bottom:32px}.ho{line-height:52px}.hp{letter-spacing:-0.011em}.hy{align-items:center}.jx{border-top:solid 1px #F2F2F2}.jy{border-bottom:solid 1px #F2F2F2}.jz{margin:32px 0 0}.ka{padding:3px 8px}.kl> *{margin-right:24px}.km> :last-child{margin-right:0}.mc{margin:0}.nd{margin-top:40px}.of{font-size:20px}.og{margin-top:2.14em}.oh{line-height:32px}.oi{letter-spacing:-0.003em}.pe{margin-top:56px}.pv{font-size:24px}.pw{margin-top:1.95em}.px{line-height:30px}.py{letter-spacing:-0.016em}.qh{margin-top:0.94em}.qp{margin-top:1.14em}.rj{margin-top:1.25em}.ro{margin-top:32px}.tc{margin-bottom:104px}.ti{flex-direction:row}.tm{margin-bottom:0}.tn{margin-right:20px}.uj{max-width:500px}.ux{line-height:24px}.uy{letter-spacing:0}.vf{margin-bottom:88px}.vi{margin-bottom:72px}.vw{width:min-width}.wb{padding-top:72px}</style><style type="text/css" data-fela-rehydration="605" data-fela-type="RULE" media="all and (min-width: 728px) and (max-width: 903.98px)">.j{display:none}.w{display:flex}.x{justify-content:space-between}.bu{width:64px}.ce{margin:0 48px}.ct{height:48px}.da{margin-bottom:52px}.dm{margin-bottom:48px}.eb{font-size:13px}.ec{line-height:20px}.ej{padding:0px 8px 1px}.fw{margin-bottom:68px}.ga{max-width:680px}.hg{font-size:42px}.hh{margin-top:1.19em}.hi{margin-bottom:32px}.hj{line-height:52px}.hk{letter-spacing:-0.011em}.hx{align-items:center}.jt{border-top:solid 1px #F2F2F2}.ju{border-bottom:solid 1px #F2F2F2}.jv{margin:32px 0 0}.jw{padding:3px 8px}.kj> *{margin-right:24px}.kk> :last-child{margin-right:0}.mb{margin:0}.nc{margin-top:40px}.ob{font-size:20px}.oc{margin-top:2.14em}.od{line-height:32px}.oe{letter-spacing:-0.003em}.pd{margin-top:56px}.pr{font-size:24px}.ps{margin-top:1.95em}.pt{line-height:30px}.pu{letter-spacing:-0.016em}.qg{margin-top:0.94em}.qo{margin-top:1.14em}.ri{margin-top:1.25em}.rn{margin-top:32px}.tb{margin-bottom:104px}.tj{flex-direction:row}.to{margin-bottom:0}.tp{margin-right:20px}.uk{max-width:500px}.uv{line-height:24px}.uw{letter-spacing:0}.ve{margin-bottom:88px}.vh{margin-bottom:72px}.vv{width:min-width}.wa{padding-top:72px}</style><style type="text/css" data-fela-rehydration="605" data-fela-type="RULE" media="all and (min-width: 552px) and (max-width: 727.98px)">.k{display:none}.u{display:flex}.v{justify-content:space-between}.bt{width:24px}.cd{margin:0 24px}.cs{height:40px}.cz{margin-bottom:44px}.dl{margin-bottom:32px}.dz{font-size:13px}.ea{line-height:20px}.ei{padding:0px 8px 1px}.fv{margin-bottom:4px}.hb{font-size:32px}.hc{margin-top:1.01em}.hd{margin-bottom:24px}.he{line-height:38px}.hf{letter-spacing:-0.014em}.hw{align-items:flex-start}.iz{flex-direction:column}.jc{margin-bottom:2px}.jr{margin:24px 0 0}.js{padding:0}.kh> *{margin-right:8px}.ki> :last-child{margin-right:8px}.ky{margin-left:0px}.ma{margin:0}.mq{border:1px solid #F2F2F2}.mr{border-radius:99em}.ms{padding:0px 16px 0px 12px}.mt{height:38px}.mu{align-items:center}.mw svg{margin-right:8px}.nb{margin-top:32px}.nx{font-size:18px}.ny{margin-top:1.56em}.nz{line-height:28px}.oa{letter-spacing:-0.003em}.pc{margin-top:40px}.pn{font-size:20px}.po{margin-top:1.2em}.pp{line-height:24px}.pq{letter-spacing:0}.qf{margin-top:0.67em}.qn{margin-top:1.34em}.rh{margin-top:0.93em}.rm{margin-top:24px}.ta{margin-bottom:96px}.tq{margin-bottom:20px}.tr{margin-right:0}.ul{max-width:100%}.us{font-size:24px}.ut{line-height:30px}.uu{letter-spacing:-0.016em}.vd{margin-bottom:64px}.vu{width:100%}.vz{padding-top:48px}.mv:hover{border-color:#E5E5E5}</style><style type="text/css" data-fela-rehydration="605" data-fela-type="RULE" media="print">.ss{display:none}</style><style type="text/css" data-fela-rehydration="605" data-fela-type="RULE" media="(orientation: landscape) and (max-width: 903.98px)">.jm{max-height:none}</style><style type="text/css" data-fela-rehydration="605" data-fela-type="RULE" media="(prefers-reduced-motion: no-preference)">.ng{transition:transform 300ms cubic-bezier(0.2, 0, 0.2, 1)}</style></head><body><div id="root"><div class="a b c"><div class="d e f g h i j k"></div><script>document.domain = document.domain;</script><div class="l c"><div class="l m n o c"><div class="p q r s t u v w x i d y z"><a class="du ag dv bf ak b am an ao ap aq ar as at s u w i d q dw z" href="https://rsci.app.link/?%24canonical_url=https%3A%2F%2Fmedium.com%2Fp%2Ffbdc855824ad&amp;%7Efeature=LoOpenInAppButton&amp;%7Echannel=ShowPostUnderCollection&amp;source=---top_nav_layout_nav----------------------------------" rel="noopener follow">Open in app<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" fill="none" viewBox="0 0 10 10" class="dt"><path fill="currentColor" d="M.985 8.485a.375.375 0 1 0 .53.53zM8.75 1.25h.375A.375.375 0 0 0 8.75.875zM8.375 6.5a.375.375 0 1 0 .75 0zM3.5.875a.375.375 0 1 0 0 .75zm-1.985 8.14 7.5-7.5-.53-.53-7.5 7.5zm6.86-7.765V6.5h.75V1.25zM3.5 1.625h5.25v-.75H3.5z"></path></svg></a><div class="ab q"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="bf b dx dy eh dz ea ei eb ec ej ek ee el em eg eo ep eq er es et eu ev ew ex ey ez fa fb fc fd bm fe ff" data-testid="headerSignUpButton" href="https://medium.com/m/signin?operation=register&amp;redirect=https%3A%2F%2Fproandroiddev.com%2Fnow-in-android-with-koin-part-4-fbdc855824ad&amp;source=post_page---top_nav_layout_nav-----------------------global_nav-----------" rel="noopener follow">Sign up</a></span></p><div class="ax l"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSignInButton" href="https://medium.com/m/signin?operation=login&amp;redirect=https%3A%2F%2Fproandroiddev.com%2Fnow-in-android-with-koin-part-4-fbdc855824ad&amp;source=post_page---top_nav_layout_nav-----------------------global_nav-----------" rel="noopener follow">Sign in</a></span></p></div></div></div><div class="p q r ab ac"><div class="ab q ae"><a class="af ag ah ai aj ak al am an ao ap aq ar as at ab" aria-label="Homepage" data-testid="headerMediumLogo" href="https://medium.com/?source=---top_nav_layout_nav----------------------------------" rel="noopener follow"><svg xmlns="http://www.w3.org/2000/svg" width="719" height="160" fill="none" viewBox="0 0 719 160" class="au av aw"><path fill="#242424" d="m174.104 9.734.215-.047V8.02H130.39L89.6 103.89 48.81 8.021H1.472v1.666l.212.047c8.018 1.81 12.09 4.509 12.09 14.242V137.93c0 9.734-4.087 12.433-12.106 14.243l-.212.047v1.671h32.118v-1.665l-.213-.048c-8.018-1.809-12.089-4.509-12.089-14.242V30.586l52.399 123.305h2.972l53.925-126.743V140.75c-.687 7.688-4.721 10.062-11.982 11.701l-.215.05v1.652h55.948v-1.652l-.215-.05c-7.269-1.639-11.4-4.013-12.087-11.701l-.037-116.774h.037c0-9.733 4.071-12.432 12.087-14.242m25.555 75.488c.915-20.474 8.268-35.252 20.606-35.507 3.806.063 6.998 1.312 9.479 3.714 5.272 5.118 7.751 15.812 7.368 31.793zm-.553 5.77h65.573v-.275c-.186-15.656-4.721-27.834-13.466-36.196-7.559-7.227-18.751-11.203-30.507-11.203h-.263c-6.101 0-13.584 1.48-18.909 4.16-6.061 2.807-11.407 7.003-15.855 12.511-7.161 8.874-11.499 20.866-12.554 34.343q-.05.606-.092 1.212a50 50 0 0 0-.065 1.151 85.807 85.807 0 0 0-.094 5.689c.71 30.524 17.198 54.917 46.483 54.917 25.705 0 40.675-18.791 44.407-44.013l-1.886-.664c-6.557 13.556-18.334 21.771-31.738 20.769-18.297-1.369-32.314-19.922-31.042-42.395m139.722 41.359c-2.151 5.101-6.639 7.908-12.653 7.908s-11.513-4.129-15.418-11.63c-4.197-8.053-6.405-19.436-6.405-32.92 0-28.067 8.729-46.22 22.24-46.22 5.657 0 10.111 2.807 12.236 7.704zm43.499 20.008c-8.019-1.897-12.089-4.722-12.089-14.951V1.309l-48.716 14.353v1.757l.299-.024c6.72-.543 11.278.386 13.925 2.83 2.072 1.915 3.082 4.853 3.082 8.987v18.66c-4.803-3.067-10.516-4.56-17.448-4.56-14.059 0-26.909 5.92-36.176 16.672-9.66 11.205-14.767 26.518-14.767 44.278-.003 31.72 15.612 53.039 38.851 53.039 13.595 0 24.533-7.449 29.54-20.013v16.865h43.711v-1.746zM424.1 19.819c0-9.904-7.468-17.374-17.375-17.374-9.859 0-17.573 7.632-17.573 17.374s7.721 17.374 17.573 17.374c9.907 0 17.375-7.47 17.375-17.374m11.499 132.546c-8.019-1.897-12.089-4.722-12.089-14.951h-.035V43.635l-43.714 12.551v1.705l.263.024c9.458.842 12.047 4.1 12.047 15.152v81.086h43.751v-1.746zm112.013 0c-8.018-1.897-12.089-4.722-12.089-14.951V43.635l-41.621 12.137v1.71l.246.026c7.733.813 9.967 4.257 9.967 15.36v59.279c-2.578 5.102-7.415 8.131-13.274 8.336-9.503 0-14.736-6.419-14.736-18.073V43.638l-43.714 12.55v1.703l.262.024c9.459.84 12.05 4.097 12.05 15.152v50.17a56.3 56.3 0 0 0 .91 10.444l.787 3.423c3.701 13.262 13.398 20.197 28.59 20.197 12.868 0 24.147-7.966 29.115-20.43v17.311h43.714v-1.747zm169.818 1.788v-1.749l-.213-.05c-8.7-2.006-12.089-5.789-12.089-13.49v-63.79c0-19.89-11.171-31.761-29.883-31.761-13.64 0-25.141 7.882-29.569 20.16-3.517-13.01-13.639-20.16-28.606-20.16-13.146 0-23.449 6.938-27.869 18.657V43.643L545.487 55.68v1.715l.263.024c9.345.829 12.047 4.181 12.047 14.95v81.784h40.787v-1.746l-.215-.053c-6.941-1.631-9.181-4.606-9.181-12.239V66.998c1.836-4.289 5.537-9.37 12.853-9.37 9.086 0 13.692 6.296 13.692 18.697v77.828h40.797v-1.746l-.215-.053c-6.94-1.631-9.18-4.606-9.18-12.239V75.066a42 42 0 0 0-.578-7.26c1.947-4.661 5.86-10.177 13.475-10.177 9.214 0 13.691 6.114 13.691 18.696v77.828z"></path></svg></a><div class="ax h"><div class="ab ay az ba bb q bc bd"><div class="bm" aria-hidden="false" aria-describedby="searchResults" aria-labelledby="searchResults"></div><div class="bn bo ab"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M4.092 11.06a6.95 6.95 0 1 1 13.9 0 6.95 6.95 0 0 1-13.9 0m6.95-8.05a8.05 8.05 0 1 0 5.13 14.26l3.75 3.75a.56.56 0 1 0 .79-.79l-3.73-3.73A8.05 8.05 0 0 0 11.042 3z" clip-rule="evenodd"></path></svg></div><input role="combobox" aria-controls="searchResults" aria-expanded="false" aria-label="search" data-testid="headerSearchInput" tabindex="0" class="ay be bf bg z bh bi bj bk bl" placeholder="Search" value=""/></div></div></div><div class="h k w fg fh"><div class="fi ab"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerWriteButton" href="https://medium.com/m/signin?operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fnew-story&amp;source=---top_nav_layout_nav-----------------------new_post_topnav-----------" rel="noopener follow"><div class="bf b bg z du fj fk ab q fl fm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24" aria-label="Write"><path fill="currentColor" d="M14 4a.5.5 0 0 0 0-1zm7 6a.5.5 0 0 0-1 0zm-7-7H4v1h10zM3 4v16h1V4zm1 17h16v-1H4zm17-1V10h-1v10zm-1 1a1 1 0 0 0 1-1h-1zM3 20a1 1 0 0 0 1 1v-1zM4 3a1 1 0 0 0-1 1h1z"></path><path stroke="currentColor" d="m17.5 4.5-8.458 8.458a.25.25 0 0 0-.06.098l-.824 2.47a.25.25 0 0 0 .316.316l2.47-.823a.25.25 0 0 0 .098-.06L19.5 6.5m-2-2 2.323-2.323a.25.25 0 0 1 .354 0l1.646 1.646a.25.25 0 0 1 0 .354L19.5 6.5m-2-2 2 2"></path></svg><div class="dt l">Write</div></div></a></span></div></div><div class="k j i d"><div class="fi ab"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSearchButton" href="https://medium.com/search?source=---top_nav_layout_nav----------------------------------" rel="noopener follow"><div class="bf b bg z du fj fk ab q fl fm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24" aria-label="Search"><path fill="currentColor" fill-rule="evenodd" d="M4.092 11.06a6.95 6.95 0 1 1 13.9 0 6.95 6.95 0 0 1-13.9 0m6.95-8.05a8.05 8.05 0 1 0 5.13 14.26l3.75 3.75a.56.56 0 1 0 .79-.79l-3.73-3.73A8.05 8.05 0 0 0 11.042 3z" clip-rule="evenodd"></path></svg></div></a></div></div><div class="fi h k j"><div class="ab q"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="bf b dx dy eh dz ea ei eb ec ej ek ee el em eg eo ep eq er es et eu ev ew ex ey ez fa fb fc fd bm fe ff" data-testid="headerSignUpButton" href="https://medium.com/m/signin?operation=register&amp;redirect=https%3A%2F%2Fproandroiddev.com%2Fnow-in-android-with-koin-part-4-fbdc855824ad&amp;source=post_page---top_nav_layout_nav-----------------------global_nav-----------" rel="noopener follow">Sign up</a></span></p><div class="ax l"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSignInButton" href="https://medium.com/m/signin?operation=login&amp;redirect=https%3A%2F%2Fproandroiddev.com%2Fnow-in-android-with-koin-part-4-fbdc855824ad&amp;source=post_page---top_nav_layout_nav-----------------------global_nav-----------" rel="noopener follow">Sign in</a></span></p></div></div></div><div class="l" aria-hidden="false"><button class="ay fn am ab q ao fo fp fq" aria-label="user options menu" data-testid="headerUserIcon"><div class="l fj"><img alt="" class="l fd by bz ca cx" src="https://miro.medium.com/v2/resize:fill:64:64/1*dmbNkD5D-u45r44go_cf0g.png" width="32" height="32" loading="lazy" role="presentation"/><div class="fr by l bz ca fs n ay ft"></div></div></button></div></div></div><div class="l"><div class="fu fv fw fx fy l"><div class="ab cb"><div class="ci bh fz ga gb gc"></div></div><article><div class="l"><div class="l"><span class="l"></span><section><div><div class="fs gi gj gk gl gm"></div><div class="gn go gp gq gr"><div class="ab cb"><div class="ci bh fz ga gb gc"><div><h1 id="a486" class="pw-post-title gs gt gu bf gv gw gx gy gz ha hb hc hd he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu bk" data-testid="storyTitle">Now In Android with Koin — part 4</h1><div><div class="speechify-ignore ab cp"><div class="speechify-ignore bh l"><div class="hv hw hx hy hz ab"><div><div class="ab ia"><div><div class="bm" aria-hidden="false"><a href="https://giuliani-arnaud.medium.com/?source=post_page---byline--fbdc855824ad--------------------------------" rel="noopener follow"><div class="l ib ic by id ie"><div class="l fj"><img alt="Arnaud Giuliani" class="l fd by dd de cx" src="https://miro.medium.com/v2/resize:fill:88:88/1*aRvmkmivw-VRIX-6wYUVCA.jpeg" width="44" height="44" loading="lazy" data-testid="authorPhoto"/><div class="if by l dd de fs n ig ft"></div></div></div></a></div></div><div class="ih ab fj"><div><div class="bm" aria-hidden="false"><a href="https://proandroiddev.com/?source=post_page---byline--fbdc855824ad--------------------------------" rel="noopener ugc nofollow"><div class="l ii ij by id ik"><div class="l fj"><img alt="ProAndroidDev" class="l fd by br il cx" src="https://miro.medium.com/v2/resize:fill:48:48/1*XVtdl45m8YaYrPI4buJ5yQ.png" width="24" height="24" loading="lazy" data-testid="publicationPhoto"/><div class="if by l br il fs n ig ft"></div></div></div></a></div></div></div></div></div><div class="bn bh l"><div class="ab"><div style="flex:1"><span class="bf b bg z bk"><div class="im ab q"><div class="ab q in"><div class="ab q"><div><div class="bm" aria-hidden="false"><p class="bf b io ip bk"><a class="af ag ah ai aj ak al am an ao ap aq ar iq" data-testid="authorName" href="https://giuliani-arnaud.medium.com/?source=post_page---byline--fbdc855824ad--------------------------------" rel="noopener follow">Arnaud Giuliani</a></p></div></div></div><span class="ir is" aria-hidden="true"><span class="bf b bg z du">·</span></span><p class="bf b io ip du"><span><a class="it iu ah ai aj ak al am an ao ap aq ar ex iv iw" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fsubscribe%2Fuser%2F9ad99ca649d4&amp;operation=register&amp;redirect=https%3A%2F%2Fproandroiddev.com%2Fnow-in-android-with-koin-part-4-fbdc855824ad&amp;user=Arnaud+Giuliani&amp;userId=9ad99ca649d4&amp;source=post_page-9ad99ca649d4--byline--fbdc855824ad---------------------post_header-----------" rel="noopener follow">Follow</a></span></p></div></div></span></div></div><div class="l ix"><span class="bf b bg z du"><div class="ab cn iy iz ja"><div class="jb jc ab"><div class="bf b bg z du ab jd"><span class="je l ix">Published in</span><div><div class="l" aria-hidden="false"><a class="af ag ah ai aj ak al am an ao ap aq ar iq ab q" data-testid="publicationName" href="https://proandroiddev.com/?source=post_page---byline--fbdc855824ad--------------------------------" rel="noopener ugc nofollow"><p class="bf b bg z jf jg jh ji jj jk jl jm bk">ProAndroidDev</p></a></div></div></div><div class="h k"><span class="ir is" aria-hidden="true"><span class="bf b bg z du">·</span></span></div></div><span class="bf b bg z du"><div class="ab ae"><span data-testid="storyReadTime">6 min read</span><div class="jn jo l" aria-hidden="true"><span class="l" aria-hidden="true"><span class="bf b bg z du">·</span></span></div><span data-testid="storyPublishDate">Apr 4, 2023</span></div></span></div></span></div></div></div><div class="ab cp jp jq jr js jt ju jv jw jx jy jz ka kb kc kd ke"><div class="h k w fg fh q"><div class="ku l"><div class="ab q kv kw"><div class="pw-multi-vote-icon fj je kx ky kz"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerClapButton" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fproandroiddev%2Ffbdc855824ad&amp;operation=register&amp;redirect=https%3A%2F%2Fproandroiddev.com%2Fnow-in-android-with-koin-part-4-fbdc855824ad&amp;user=Arnaud+Giuliani&amp;userId=9ad99ca649d4&amp;source=---header_actions--fbdc855824ad---------------------clap_footer-----------" rel="noopener follow"><div><div class="bm" aria-hidden="false"><div class="la ao lb lc ld le am lf lg lh kz"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l li lj lk ll lm ln lo"><p class="bf b dv z du"><span class="lp">--</span></p></div></div></div><div><div class="bm" aria-hidden="false"><button class="ao la ls lt ab q fk lu lv" aria-label="responses"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="lr"><path d="M18.006 16.803c1.533-1.456 2.234-3.325 2.234-5.321C20.24 7.357 16.709 4 12.191 4S4 7.357 4 11.482c0 4.126 3.674 7.482 8.191 7.482.817 0 1.622-.111 2.393-.327.231.2.48.391.744.559 1.06.693 2.203 1.044 3.399 1.044.224-.008.4-.112.486-.287a.49.49 0 0 0-.042-.518c-.495-.67-.845-1.364-1.04-2.057a4 4 0 0 1-.125-.598zm-3.122 1.055-.067-.223-.315.096a8 8 0 0 1-2.311.338c-4.023 0-7.292-2.955-7.292-6.587 0-3.633 3.269-6.588 7.292-6.588 4.014 0 7.112 2.958 7.112 6.593 0 1.794-.608 3.469-2.027 4.72l-.195.168v.255c0 .056 0 .151.016.295.025.231.081.478.154.733.154.558.398 1.117.722 1.659a5.3 5.3 0 0 1-2.165-.845c-.276-.176-.714-.383-.941-.59z"></path></svg><p class="bf b dv z du"><span class="pw-responses-count lq lr">1</span></p></button></div></div></div><div class="ab q kf kg kh ki kj kk kl km kn ko kp kq kr ks kt"><div class="lw k j i d"></div><div class="h k"><div><div class="bm" aria-hidden="false"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerBookmarkButton" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fbookmark%2Fp%2Ffbdc855824ad&amp;operation=register&amp;redirect=https%3A%2F%2Fproandroiddev.com%2Fnow-in-android-with-koin-part-4-fbdc855824ad&amp;source=---header_actions--fbdc855824ad---------------------bookmark_footer-----------" rel="noopener follow"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="none" viewBox="0 0 25 25" class="du lx" aria-label="Add to list bookmark button"><path fill="currentColor" d="M18 2.5a.5.5 0 0 1 1 0V5h2.5a.5.5 0 0 1 0 1H19v2.5a.5.5 0 1 1-1 0V6h-2.5a.5.5 0 0 1 0-1H18zM7 7a1 1 0 0 1 1-1h3.5a.5.5 0 0 0 0-1H8a2 2 0 0 0-2 2v14a.5.5 0 0 0 .805.396L12.5 17l5.695 4.396A.5.5 0 0 0 19 21v-8.5a.5.5 0 0 0-1 0v7.485l-5.195-4.012a.5.5 0 0 0-.61 0L7 19.985z"></path></svg></a></span></div></div></div><div class="fd ly cn"><div class="l ae"><div class="ab cb"><div class="lz ma mb mc md me ci bh"><div class="ab"><div class="bm bh" aria-hidden="false"><div><div class="bm" aria-hidden="false"><button aria-label="Listen" data-testid="audioPlayButton" class="af fk ah ai aj ak al mf an ao ap ex mg mh lv mi mj mk ml mm s mn mo mp mq mr ms mt u mu mv mw"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M3 12a9 9 0 1 1 18 0 9 9 0 0 1-18 0m9-10C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2m3.376 10.416-4.599 3.066a.5.5 0 0 1-.777-.416V8.934a.5.5 0 0 1 .777-.416l4.599 3.066a.5.5 0 0 1 0 .832" clip-rule="evenodd"></path></svg><div class="j i d"><p class="bf b bg z du">Listen</p></div></button></div></div></div></div></div></div></div></div><div class="bm" aria-hidden="false" aria-describedby="postFooterSocialMenu" aria-labelledby="postFooterSocialMenu"><div><div class="bm" aria-hidden="false"><button aria-controls="postFooterSocialMenu" aria-expanded="false" aria-label="Share Post" data-testid="headerSocialShareButton" class="af fk ah ai aj ak al mf an ao ap ex mg mh lv mi mj mk ml mm s mn mo mp mq mr ms mt u mu mv mw"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M15.218 4.931a.4.4 0 0 1-.118.132l.012.006a.45.45 0 0 1-.292.074.5.5 0 0 1-.3-.13l-2.02-2.02v7.07c0 .28-.23.5-.5.5s-.5-.22-.5-.5v-7.04l-2 2a.45.45 0 0 1-.57.04h-.02a.4.4 0 0 1-.16-.3.4.4 0 0 1 .1-.32l2.8-2.8a.5.5 0 0 1 .7 0l2.8 2.79a.42.42 0 0 1 .068.498m-.106.138.008.004v-.01zM16 7.063h1.5a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-11c-1.1 0-2-.9-2-2v-10a2 2 0 0 1 2-2H8a.5.5 0 0 1 .35.15.5.5 0 0 1 .15.35.5.5 0 0 1-.15.35.5.5 0 0 1-.35.15H6.4c-.5 0-.9.4-.9.9v10.2a.9.9 0 0 0 .9.9h11.2c.5 0 .9-.4.9-.9v-10.2c0-.5-.4-.9-.9-.9H16a.5.5 0 0 1 0-1" clip-rule="evenodd"></path></svg><div class="j i d"><p class="bf b bg z du">Share</p></div></button></div></div></div></div></div></div></div></div></div><figure class="na nb nc nd ne nf mx my paragraph-image"><div role="button" tabindex="0" class="ng nh fj ni bh nj"><div class="mx my mz"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*hVKWuT24riZnx4VzDpQVJQ.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*hVKWuT24riZnx4VzDpQVJQ.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*hVKWuT24riZnx4VzDpQVJQ.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*hVKWuT24riZnx4VzDpQVJQ.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*hVKWuT24riZnx4VzDpQVJQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*hVKWuT24riZnx4VzDpQVJQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*hVKWuT24riZnx4VzDpQVJQ.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*hVKWuT24riZnx4VzDpQVJQ.png 640w, https://miro.medium.com/v2/resize:fit:720/1*hVKWuT24riZnx4VzDpQVJQ.png 720w, https://miro.medium.com/v2/resize:fit:750/1*hVKWuT24riZnx4VzDpQVJQ.png 750w, https://miro.medium.com/v2/resize:fit:786/1*hVKWuT24riZnx4VzDpQVJQ.png 786w, https://miro.medium.com/v2/resize:fit:828/1*hVKWuT24riZnx4VzDpQVJQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*hVKWuT24riZnx4VzDpQVJQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*hVKWuT24riZnx4VzDpQVJQ.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh me nk c" width="700" height="341" loading="eager" role="presentation"/></picture></div></div><figcaption class="nl ff nm mx my nn no bf b bg z du">Koined from original banner — <a class="af np" href="https://github.com/android/nowinandroid" rel="noopener ugc nofollow" target="_blank">https://github.com/android/nowinandroid</a></figcaption></figure><p id="7a78" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk"><a class="af np" href="https://github.com/android/nowinandroid" rel="noopener ugc nofollow" target="_blank">Now In Android</a> is an open-source Android application that covers Modern Android Development best practices. The project is maintained by the Google Android team.</p><p id="03be" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">I propose to continue our tour with the <strong class="ns gv">version</strong> <strong class="ns gv">built with the Koin dependency injection framework</strong>. This is a good time to refresh practices, from standard components structure to more advanced cases.</p><p id="cbb5" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">For this article, <strong class="ns gv">I propose now to use Koin Annotations instead of Koin DSL to configure all the app’s components injection. </strong>This is interesting to see how much it can improve the experience in terms of writing.</p><p id="0c3d" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">Prepare yourself, we have many things to see together 👍 🚀</p><blockquote class="oo op oq"><p id="8973" class="nq nr or ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">This version uses Koin Annotations 1.2</p></blockquote></div></div></div><div class="ab cb os ot ou ov" role="separator"><span class="ow by bm ox oy oz"></span><span class="ow by bm ox oy oz"></span><span class="ow by bm ox oy"></span></div><div class="gn go gp gq gr"><div class="ab cb"><div class="ci bh fz ga gb gc"><p id="46e2" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">This article series covers several parts:</p><p id="940d" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk"><a class="af np" rel="noopener ugc nofollow" target="_blank" href="/now-in-android-with-koin-part-1-2b871d8549f1">Part 1 — Koin setup, application verification, and a first module tour</a></p><p id="2a90" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk"><a class="af np" rel="noopener ugc nofollow" target="_blank" href="/now-in-android-with-koin-part-2-49158741cb92#1936-6cf6d648e2ac-reply">Part 2 — Common Modules components and feature modules</a></p><p id="bb38" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk"><a class="af np" rel="noopener ugc nofollow" target="_blank" href="/now-in-android-with-koin-part-3-2801ffeed4d6">Part 3 — Get started with Koin Annotations</a></p><p id="0f58" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk"><a class="af np" rel="noopener ugc nofollow" target="_blank" href="/now-in-android-with-koin-part-4-fbdc855824ad"><strong class="ns gv">Part 4 — Core &amp; Features Components with Koin Annotations</strong></a></p><p id="eea4" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">… more to come :)</p><figure class="pb pc pd pe pf nf mx my paragraph-image"><div class="mx my pa"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/0*SgUInfHiU6tfX3-c.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*SgUInfHiU6tfX3-c.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*SgUInfHiU6tfX3-c.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*SgUInfHiU6tfX3-c.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*SgUInfHiU6tfX3-c.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*SgUInfHiU6tfX3-c.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*SgUInfHiU6tfX3-c.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/0*SgUInfHiU6tfX3-c.png 640w, https://miro.medium.com/v2/resize:fit:720/0*SgUInfHiU6tfX3-c.png 720w, https://miro.medium.com/v2/resize:fit:750/0*SgUInfHiU6tfX3-c.png 750w, https://miro.medium.com/v2/resize:fit:786/0*SgUInfHiU6tfX3-c.png 786w, https://miro.medium.com/v2/resize:fit:828/0*SgUInfHiU6tfX3-c.png 828w, https://miro.medium.com/v2/resize:fit:1100/0*SgUInfHiU6tfX3-c.png 1100w, https://miro.medium.com/v2/resize:fit:1400/0*SgUInfHiU6tfX3-c.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh me nk c" width="700" height="393" loading="eager" role="presentation"/></picture></div></figure><p id="5aa3" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">Features picture from <a class="af np" href="https://github.com/android/nowinandroid" rel="noopener ugc nofollow" target="_blank">https://github.com/android/nowinandroid</a></p></div></div></div><div class="ab cb os ot ou ov" role="separator"><span class="ow by bm ox oy oz"></span><span class="ow by bm ox oy oz"></span><span class="ow by bm ox oy"></span></div><div class="gn go gp gq gr"><div class="ab cb"><div class="ci bh fz ga gb gc"><p id="766e" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">Previously in part 3, we saw how to setup and use Koin annotations with Koin dependency injection framework. It’s really easy as the Koin annotation processor can detect many cases, and generate your dependency injection configuration really quickly. It’s now time to dive into more components of the NowInAndroid project.</p><p id="019b" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">You will have the reference for all the content to browse the code. Also, everything is available online on the Github repo: <a class="af np" href="https://github.com/InsertKoinIO/nowinandroid/tree/refacto_koin/annotations" rel="noopener ugc nofollow" target="_blank">https://github.com/InsertKoinIO/nowinandroid/</a></p><h1 id="1b53" class="pg ph gu bf pi pj pk pl pm pn po pp pq pr ps pt pu pv pw px py pz qa qb qc qd bk">Common Data Layers</h1><p id="7fed" class="pw-post-body-paragraph nq nr gu ns b nt qe nv nw nx qf nz oa ob qg od oe of qh oh oi oj qi ol om on gn bk">Following the <a class="af np" rel="noopener ugc nofollow" target="_blank" href="/now-in-android-with-koin-part-2-49158741cb92#1936-6cf6d648e2ac-reply">part 2 article</a>, we will now go through the common core components that will be used by the features later. But this time, the configuration will be done with annotations.</p><p id="c7a5" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">As a reminder, the Nia app is developed using Jetpack Compose and uses repository &amp; use-case components:</p><ul class=""><li id="1ace" class="nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on qj qk ql bk">Repository to access data (network, database …)</li><li id="55d5" class="nq nr gu ns b nt qm nv nw nx qn nz oa ob qo od oe of qp oh oi oj qq ol om on qj qk ql bk">Usecase to handle business logic</li></ul><p id="9c6e" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">The module that is gathering all those common components is the<code class="cx qr qs qt qu b"><a class="af np" href="https://github.com/InsertKoinIO/nowinandroid/blob/refacto_koin/annotations/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/di/DataKoinModule.kt#L48" rel="noopener ugc nofollow" target="_blank">DataKoinModule.kt</a></code> module:</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="155b" class="qy ph gu qu b bg qz ra l rb rc">@Module(includes = [DaosKoinModule::class, DataStoreKoinModule::class, NetworkKoinModule::class, DispatchersKoinModule::class, DataUtilModule::class])<br/>@ComponentScan(&quot;com.google.samples.apps.nowinandroid.core.data.repository&quot;)<br/>class DataKoinModule</span></pre><p id="d29d" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">This module is making several things:</p><ul class=""><li id="2810" class="nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on qj qk ql bk">scans all repository classes defined in <code class="cx qr qs qt qu b">@ComponentScan</code></li><li id="90f6" class="nq nr gu ns b nt qm nv nw nx qn nz oa ob qo od oe of qp oh oi oj qq ol om on qj qk ql bk">includes modules that are declaring sub-data layers components</li></ul><p id="5c9d" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">Each repository class is simply tagged with <code class="cx qr qs qt qu b">@Single</code> annotation like this:</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="219a" class="qy ph gu qu b bg qz ra l rb rc">@Single<br/>class OfflineFirstAuthorsRepository(<br/> private val authorDao: AuthorDao,<br/> private val network: NiaNetworkDataSource,<br/>)</span></pre><p id="45d5" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">You can find all the repository classes in <a class="af np" href="https://github.com/InsertKoinIO/nowinandroid/tree/refacto_koin/annotations/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository" rel="noopener ugc nofollow" target="_blank">the source code data package</a>.</p><h1 id="b470" class="pg ph gu bf pi pj pk pl pm pn po pp pq pr ps pt pu pv pw px py pz qa qb qc qd bk">Database Storage</h1><p id="e15b" class="pw-post-body-paragraph nq nr gu ns b nt qe nv nw nx qf nz oa ob qg od oe of qh oh oi oj qi ol om on gn bk">For the database storage layer, we need to declare our Room database instance via a function using the Room API builder like this:</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="8846" class="qy ph gu qu b bg qz ra l rb rc">@Module<br/>class DatabaseKoinModule {<br/><br/> @Single<br/> fun database(context: Context) =<br/> Room.databaseBuilder(context, NiaDatabase::class.java, &quot;nia-database&quot;)<br/> .build()<br/>}</span></pre><p id="28db" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">The <code class="cx qr qs qt qu b">context</code> parameter here is the Android Context instance from Koin.</p><p id="a368" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">In a second module, we can reuse our <code class="cx qr qs qt qu b">NiaDatabase</code> instance below in DAOs:</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="7424" class="qy ph gu qu b bg qz ra l rb rc">@Module(includes = [DatabaseKoinModule::class])<br/>class DaosKoinModule {<br/><br/> @Single<br/> fun authorDao(niaDatabase: NiaDatabase) = niaDatabase.authorDao()<br/><br/> @Single<br/> fun topicDao(niaDatabase: NiaDatabase) = niaDatabase.topicDao()<br/><br/> @Single<br/> fun newsResourcesDao(niaDatabase: NiaDatabase) = niaDatabase.newsResourceDao()<br/>}</span></pre><p id="ba81" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">That’s it! Our Database Layer is ready to be injected.</p><h1 id="616d" class="pg ph gu bf pi pj pk pl pm pn po pp pq pr ps pt pu pv pw px py pz qa qb qc qd bk">Datasource Components — Datastore &amp; Networking</h1><p id="b769" class="pw-post-body-paragraph nq nr gu ns b nt qe nv nw nx qf nz oa ob qg od oe of qh oh oi oj qi ol om on gn bk">This layer defines Datasources which are components that abstract the calls to different sources of data. E.g: remote web service, local data storage, and so on. Therefore, the UI doesn’t need to know where the data comes from. It just calls the interface defined here.</p><p id="158d" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">We are defining severasl kind of usages with <code class="cx qr qs qt qu b">NiaNetworkDatasource</code>:</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="5d0c" class="qy ph gu qu b bg qz ra l rb rc">interface NiaNetworkDataSource {<br/> suspend fun getTopics(ids: List&lt;String&gt;? = null): List&lt;NetworkTopic&gt;<br/><br/> suspend fun getAuthors(ids: List&lt;String&gt;? = null): List&lt;NetworkAuthor&gt;<br/><br/> suspend fun getNewsResources(ids: List&lt;String&gt;? = null): List&lt;NetworkNewsResource&gt;<br/><br/> suspend fun getTopicChangeList(after: Int? = null): List&lt;NetworkChangeList&gt;<br/><br/> suspend fun getAuthorChangeList(after: Int? = null): List&lt;NetworkChangeList&gt;<br/><br/> suspend fun getNewsResourceChangeList(after: Int? = null): List&lt;NetworkChangeList&gt;<br/>}</span></pre><p id="085b" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">First, we need to declare a default Coroutine dispatcher directly in a module:</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="23d3" class="qy ph gu qu b bg qz ra l rb rc">@Module<br/>class DispatchersKoinModule{<br/> <br/> @Single<br/> fun dispatcher() = Dispatchers.IO<br/>}</span></pre><blockquote class="oo op oq"><p id="7c43" class="nq nr or ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">In<!-- --> a test environment, you simply have to redefine a <code class="cx qr qs qt qu b">CoroutineDispatcher</code> type to specify your needed one. Just add the new definition and it will override the existing one.</p></blockquote><p id="71a4" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">The <a class="af np" href="https://github.com/InsertKoinIO/nowinandroid/tree/refacto_koin/annotations/core/network/src" rel="noopener ugc nofollow" target="_blank">network module</a> is declaring <code class="cx qr qs qt qu b">NiaNetworkDatasource</code>, and is organized into 2 flavors:</p><ul class=""><li id="a6b8" class="nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on qj qk ql bk">demo — with local data</li><li id="9b7f" class="nq nr gu ns b nt qm nv nw nx qn nz oa ob qo od oe of qp oh oi oj qq ol om on qj qk ql bk">prod — for online data</li></ul><p id="03b4" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">The <code class="cx qr qs qt qu b">NetworkKoinModule</code> includes the right flavour implementation:</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="28d4" class="qy ph gu qu b bg qz ra l rb rc">@Module(includes = [FlavoredNetworkKoinModule::class])<br/>class NetworkKoinModule {<br/><br/> @Single<br/> fun json() = Json { ignoreUnknownKeys = true }<br/>}</span></pre><figure class="pb pc pd pe pf nf mx my paragraph-image"><div role="button" tabindex="0" class="ng nh fj ni bh nj"><div class="mx my rd"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*ZV6ZXgkeUT3JSQqFfOYLxw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*ZV6ZXgkeUT3JSQqFfOYLxw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*ZV6ZXgkeUT3JSQqFfOYLxw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*ZV6ZXgkeUT3JSQqFfOYLxw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*ZV6ZXgkeUT3JSQqFfOYLxw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*ZV6ZXgkeUT3JSQqFfOYLxw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*ZV6ZXgkeUT3JSQqFfOYLxw.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*ZV6ZXgkeUT3JSQqFfOYLxw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*ZV6ZXgkeUT3JSQqFfOYLxw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*ZV6ZXgkeUT3JSQqFfOYLxw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*ZV6ZXgkeUT3JSQqFfOYLxw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*ZV6ZXgkeUT3JSQqFfOYLxw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*ZV6ZXgkeUT3JSQqFfOYLxw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*ZV6ZXgkeUT3JSQqFfOYLxw.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh me nk c" width="700" height="412" loading="lazy" role="presentation"/></picture></div></div><figcaption class="nl ff nm mx my nn no bf b bg z du">Demo flavor in Network module</figcaption></figure><p id="5b74" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">The demo flavour uses Datastore API and Protobuff API is used to store local data to display as an offline-first architecture.</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="99da" class="qy ph gu qu b bg qz ra l rb rc">@Module(includes = [DispatchersKoinModule::class])<br/>@ComponentScan(&quot;com.google.samples.apps.nowinandroid.core.network.fake&quot;)<br/>class FlavoredNetworkKoinModule{<br/><br/> @Single<br/> fun assetManager(context: Context) = FakeAssetManager(context.assets::open)<br/>}</span></pre><p id="2771" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">Below is the demo datasource implementation declared as a singleton:</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="2466" class="qy ph gu qu b bg qz ra l rb rc">@Single<br/>class FakeNiaNetworkDataSource(<br/> private val ioDispatcher: CoroutineDispatcher,<br/> private val networkJson: Json,<br/> private val assets: FakeAssetManager = JvmUnitTestFakeAssetManager,<br/>) : NiaNetworkDataSource</span></pre><p id="10bf" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">The online version is declared with the following module:</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="5e8d" class="qy ph gu qu b bg qz ra l rb rc">@Module(includes = [DispatchersKoinModule::class])<br/>@ComponentScan(&quot;com.google.samples.apps.nowinandroid.core.network.retrofit&quot;)<br/>class FlavoredNetworkKoinModule</span></pre><p id="1f33" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">This module will scan the Retrofit implementation:</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="bea2" class="qy ph gu qu b bg qz ra l rb rc">@Single<br/>class RetrofitNiaNetwork(<br/> networkJson: Json<br/>) : NiaNetworkDataSource</span></pre><p id="e54d" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">One last part is about Datastore persistence API, used to declare local data storage. Check the <a class="af np" href="https://github.com/InsertKoinIO/nowinandroid/blob/refacto_koin/annotations/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/di/DataStoreKoinModule.kt" rel="noopener ugc nofollow" target="_blank">Datastore Persistence Module</a> that is declaring the required components for <code class="cx qr qs qt qu b">NiaPreferencesDatasource</code>.</p><h1 id="d3b3" class="pg ph gu bf pi pj pk pl pm pn po pp pq pr ps pt pu pv pw px py pz qa qb qc qd bk">Domain &amp; Features Modules</h1><p id="a286" class="pw-post-body-paragraph nq nr gu ns b nt qe nv nw nx qf nz oa ob qg od oe of qh oh oi oj qi ol om on gn bk">Before running our features, we have some use-case components using the DataKoinModule. Those use-cases components are reusable business logic components. They are defined from the <code class="cx qr qs qt qu b">DomainKoinModule</code>:</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="df3f" class="qy ph gu qu b bg qz ra l rb rc">@Module(includes = [DataKoinModule::class])<br/>@ComponentScan<br/>class DomainKoinModule</span></pre><p id="99e5" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">You can note that we don’t specify what package to scan. This means that the module will scan in the current package and sub-packages for annotated components:</p><figure class="pb pc pd pe pf nf mx my paragraph-image"><div class="mx my re"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*HQzVRHo6PAOtCLNZcEGKuQ.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*HQzVRHo6PAOtCLNZcEGKuQ.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*HQzVRHo6PAOtCLNZcEGKuQ.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*HQzVRHo6PAOtCLNZcEGKuQ.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*HQzVRHo6PAOtCLNZcEGKuQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*HQzVRHo6PAOtCLNZcEGKuQ.png 1100w, https://miro.medium.com/v2/resize:fit:866/format:webp/1*HQzVRHo6PAOtCLNZcEGKuQ.png 866w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 433px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*HQzVRHo6PAOtCLNZcEGKuQ.png 640w, https://miro.medium.com/v2/resize:fit:720/1*HQzVRHo6PAOtCLNZcEGKuQ.png 720w, https://miro.medium.com/v2/resize:fit:750/1*HQzVRHo6PAOtCLNZcEGKuQ.png 750w, https://miro.medium.com/v2/resize:fit:786/1*HQzVRHo6PAOtCLNZcEGKuQ.png 786w, https://miro.medium.com/v2/resize:fit:828/1*HQzVRHo6PAOtCLNZcEGKuQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*HQzVRHo6PAOtCLNZcEGKuQ.png 1100w, https://miro.medium.com/v2/resize:fit:866/1*HQzVRHo6PAOtCLNZcEGKuQ.png 866w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 433px"/><img alt="" class="bh me nk c" width="433" height="169" loading="lazy" role="presentation"/></picture></div></figure><p id="e374" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">Each usecase component is declared with <code class="cx qr qs qt qu b">@Factory</code> annotation. This asks Koin to create a new instance each time we need it.</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="8f1c" class="qy ph gu qu b bg qz ra l rb rc">@Factory<br/>class GetFollowableTopicsStreamUseCase(<br/> private val topicsRepository: TopicsRepository,<br/> private val userDataRepository: UserDataRepository<br/>)</span></pre><blockquote class="oo op oq"><p id="0da7" class="nq nr or ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">Why not a singleton instance? Because those usecase components will be used with a <code class="cx qr qs qt qu b">ViewModel</code>, following the Android lifecycle. Making them as a singleton, we would take a risk to have references to a <code class="cx qr qs qt qu b">ViewModel</code> that are destroyed by the application.</p></blockquote><p id="f4ca" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">Finally, we are ready to use all of this in our Feature module. Each will then include <code class="cx qr qs qt qu b">DomainKoinModule</code> or <code class="cx qr qs qt qu b">DataKoinModule</code> to benefit from the common components:</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="d552" class="qy ph gu qu b bg qz ra l rb rc">@Module(includes = [DomainKoinModule::class,StringDecoderKoinModule::class])<br/>@ComponentScan(&quot;com.google.samples.apps.nowinandroid.feature.author&quot;)<br/>class AuthorKoinModule</span></pre><p id="6ba3" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">By scanning the right package in our module, we will be able to declare our ViewModel instances like this:</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="2a13" class="qy ph gu qu b bg qz ra l rb rc">@KoinViewModel<br/>class AuthorViewModel(<br/> savedStateHandle: SavedStateHandle,<br/> stringDecoder: StringDecoder,<br/> private val userDataRepository: UserDataRepository,<br/> authorsRepository: AuthorsRepository,<br/> getSaveableNewsResourcesStream: GetSaveableNewsResourcesStreamUseCase<br/>) : ViewModel()</span></pre><h1 id="846c" class="pg ph gu bf pi pj pk pl pm pn po pp pq pr ps pt pu pv pw px py pz qa qb qc qd bk">Sync Worker — Offline data sync with WorkManager</h1><p id="5217" class="pw-post-body-paragraph nq nr gu ns b nt qe nv nw nx qf nz oa ob qg od oe of qh oh oi oj qi ol om on gn bk">Finally, we need to declare our SyncWorker components, to asynchronously prepare offline content. This consists of a module:</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="58fc" class="qy ph gu qu b bg qz ra l rb rc">@Module<br/>@ComponentScan<br/>class SyncWorkerKoinModule</span></pre><p id="aa04" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">The following definitions will be scanned by the module.</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="e140" class="qy ph gu qu b bg qz ra l rb rc">@Single<br/>class WorkManagerSyncStatusMonitor(<br/> context: Context<br/>) : SyncStatusMonitor</span></pre><p id="dafd" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk">And the <code class="cx qr qs qt qu b">SyncWorker</code> component declared with <code class="cx qr qs qt qu b">@KoinWorker</code> annotation. This will generate the equivalent of <code class="cx qr qs qt qu b">worker { }</code> DSL:</p><pre class="pb pc pd pe pf qv qu qw bp qx bb bk"><span id="695a" class="qy ph gu qu b bg qz ra l rb rc">@KoinWorker<br/>class SyncWorker (<br/> private val appContext: Context,<br/> workerParams: WorkerParameters,<br/> private val niaPreferences: NiaPreferencesDataSource,<br/> private val topicRepository: TopicsRepository,<br/> private val newsRepository: NewsRepository,<br/> private val authorsRepository: AuthorsRepository,<br/> private val ioDispatcher: CoroutineDispatcher,<br/>) : CoroutineWorker(appContext, workerParams), Synchronizer</span></pre><p id="13be" class="pw-post-body-paragraph nq nr gu ns b nt nu nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on gn bk"><code class="cx qr qs qt qu b">SyncWorker</code> will be declared with Workmanager Koin factory. This one has to be activated at the start like this:</p><figure class="pb pc pd pe pf nf mx my paragraph-image"><div role="button" tabindex="0" class="ng nh fj ni bh nj"><div class="mx my rf"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*7TDkzXW4mtotwat50QSQ8A.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*7TDkzXW4mtotwat50QSQ8A.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*7TDkzXW4mtotwat50QSQ8A.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*7TDkzXW4mtotwat50QSQ8A.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*7TDkzXW4mtotwat50QSQ8A.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*7TDkzXW4mtotwat50QSQ8A.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*7TDkzXW4mtotwat50QSQ8A.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*7TDkzXW4mtotwat50QSQ8A.png 640w, https://miro.medium.com/v2/resize:fit:720/1*7TDkzXW4mtotwat50QSQ8A.png 720w, https://miro.medium.com/v2/resize:fit:750/1*7TDkzXW4mtotwat50QSQ8A.png 750w, https://miro.medium.com/v2/resize:fit:786/1*7TDkzXW4mtotwat50QSQ8A.png 786w, https://miro.medium.com/v2/resize:fit:828/1*7TDkzXW4mtotwat50QSQ8A.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*7TDkzXW4mtotwat50QSQ8A.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*7TDkzXW4mtotwat50QSQ8A.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh me nk c" width="700" height="190" loading="lazy" role="presentation"/></picture></div></div><figcaption class="nl ff nm mx my nn no bf b bg z du">Koin start in NiaApplication class</figcaption></figure></div></div></div><div class="ab cb os ot ou ov" role="separator"><span class="ow by bm ox oy oz"></span><span class="ow by bm ox oy oz"></span><span class="ow by bm ox oy"></span></div><div class="gn go gp gq gr"><div class="ab cb"><div class="ci bh fz ga gb gc"><h1 id="415f" class="pg ph gu bf pi pj rg pl pm pn rh pp pq pr ri pt pu pv rj px py pz rk qb qc qd bk">Koin Annotations — Cheat Sheet</h1><p id="bf1a" class="pw-post-body-paragraph nq nr gu ns b nt qe nv nw nx qf nz oa ob qg od oe of qh oh oi oj qi ol om on gn bk">Hope you enjoyed the walkthrough NowInAndroid application with Koin dependency injection and annotations. You will find below the last cheat sheet we’ve made.</p><div class="rl rm rn ro rp rq"><a href="https://blog.kotzilla.io/koin-3-2-annotations-cheat-sheets/?source=post_page-----fbdc855824ad--------------------------------" rel="noopener ugc nofollow" target="_blank"><div class="rr ab ix"><div class="rs ab co cb rt ru"><h2 class="bf gv io z jf rv jh ji rw jk jm gt bk">Koin 3.2 &amp; Koin Annotations 1.0 — Cheat Sheets</h2><div class="rx l"><h3 class="bf b io z jf rv jh ji rw jk jm du">Hello Folks 👋 While we are at several conferences to show Architecture Design with Koin, Kotzilla is also offering…</h3></div><div class="ry l"><p class="bf b dv z jf rv jh ji rw jk jm du">blog.kotzilla.io</p></div></div><div class="rz l"><div class="sa l sb sc sd rz se me rq"></div></div></div></a></div></div></div></div></div></section></div></div></article></div><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="sf sg ab ja"><div class="rx ab"><a class="sh ay am ao" href="https://medium.com/tag/android?source=post_page-----fbdc855824ad--------------------------------" rel="noopener follow"><div class="si fj cx sj ge sk sl bf b bg z bk sm">Android</div></a></div><div class="rx ab"><a class="sh ay am ao" href="https://medium.com/tag/kotlin?source=post_page-----fbdc855824ad--------------------------------" rel="noopener follow"><div class="si fj cx sj ge sk sl bf b bg z bk sm">Kotlin</div></a></div><div class="rx ab"><a class="sh ay am ao" href="https://medium.com/tag/dependency-injection?source=post_page-----fbdc855824ad--------------------------------" rel="noopener follow"><div class="si fj cx sj ge sk sl bf b bg z bk sm">Dependency Injection</div></a></div><div class="rx ab"><a class="sh ay am ao" href="https://medium.com/tag/koin?source=post_page-----fbdc855824ad--------------------------------" rel="noopener follow"><div class="si fj cx sj ge sk sl bf b bg z bk sm">Koin</div></a></div><div class="rx ab"><a class="sh ay am ao" href="https://medium.com/tag/annotations?source=post_page-----fbdc855824ad--------------------------------" rel="noopener follow"><div class="si fj cx sj ge sk sl bf b bg z bk sm">Annotations</div></a></div></div></div></div><div class="l"></div><footer class="sn ot so sp sq ab q sr ik c"><div class="l ae"><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="ab cp ss"><div class="ab q kv"><div class="st l"><span class="l su sv sw e d"><div class="ab q kv kw"><div class="pw-multi-vote-icon fj je kx ky kz"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerClapButton" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fproandroiddev%2Ffbdc855824ad&amp;operation=register&amp;redirect=https%3A%2F%2Fproandroiddev.com%2Fnow-in-android-with-koin-part-4-fbdc855824ad&amp;user=Arnaud+Giuliani&amp;userId=9ad99ca649d4&amp;source=---footer_actions--fbdc855824ad---------------------clap_footer-----------" rel="noopener follow"><div><div class="bm" aria-hidden="false"><div class="la ao lb lc ld le am lf lg lh kz"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l li lj lk ll lm ln lo"><p class="bf b dv z du"><span class="lp">--</span></p></div></div></span><span class="l h g f sx sy"><div class="ab q kv kw"><div class="pw-multi-vote-icon fj je kx ky kz"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerClapButton" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fproandroiddev%2Ffbdc855824ad&amp;operation=register&amp;redirect=https%3A%2F%2Fproandroiddev.com%2Fnow-in-android-with-koin-part-4-fbdc855824ad&amp;user=Arnaud+Giuliani&amp;userId=9ad99ca649d4&amp;source=---footer_actions--fbdc855824ad---------------------clap_footer-----------" rel="noopener follow"><div><div class="bm" aria-hidden="false"><div class="la ao lb lc ld le am lf lg lh kz"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l li lj lk ll lm ln lo"><p class="bf b dv z du"><span class="lp">--</span></p></div></div></span></div><div class="bq ab"><div><div class="bm" aria-hidden="false"><button class="ao la ls lt ab q fk lu lv" aria-label="responses"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="lr"><path d="M18.006 16.803c1.533-1.456 2.234-3.325 2.234-5.321C20.24 7.357 16.709 4 12.191 4S4 7.357 4 11.482c0 4.126 3.674 7.482 8.191 7.482.817 0 1.622-.111 2.393-.327.231.2.48.391.744.559 1.06.693 2.203 1.044 3.399 1.044.224-.008.4-.112.486-.287a.49.49 0 0 0-.042-.518c-.495-.67-.845-1.364-1.04-2.057a4 4 0 0 1-.125-.598zm-3.122 1.055-.067-.223-.315.096a8 8 0 0 1-2.311.338c-4.023 0-7.292-2.955-7.292-6.587 0-3.633 3.269-6.588 7.292-6.588 4.014 0 7.112 2.958 7.112 6.593 0 1.794-.608 3.469-2.027 4.72l-.195.168v.255c0 .056 0 .151.016.295.025.231.081.478.154.733.154.558.398 1.117.722 1.659a5.3 5.3 0 0 1-2.165-.845c-.276-.176-.714-.383-.941-.59z"></path></svg><p class="bf b bg z du"><span class="pw-responses-count lq lr">1</span></p></button></div></div></div></div><div class="ab q"><div class="oz l ix"><div><div class="bm" aria-hidden="false"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerBookmarkButton" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fbookmark%2Fp%2Ffbdc855824ad&amp;operation=register&amp;redirect=https%3A%2F%2Fproandroiddev.com%2Fnow-in-android-with-koin-part-4-fbdc855824ad&amp;source=---footer_actions--fbdc855824ad---------------------bookmark_footer-----------" rel="noopener follow"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="none" viewBox="0 0 25 25" class="du lx" aria-label="Add to list bookmark button"><path fill="currentColor" d="M18 2.5a.5.5 0 0 1 1 0V5h2.5a.5.5 0 0 1 0 1H19v2.5a.5.5 0 1 1-1 0V6h-2.5a.5.5 0 0 1 0-1H18zM7 7a1 1 0 0 1 1-1h3.5a.5.5 0 0 0 0-1H8a2 2 0 0 0-2 2v14a.5.5 0 0 0 .805.396L12.5 17l5.695 4.396A.5.5 0 0 0 19 21v-8.5a.5.5 0 0 0-1 0v7.485l-5.195-4.012a.5.5 0 0 0-.61 0L7 19.985z"></path></svg></a></span></div></div></div><div class="oz l ix"><div class="bm" aria-hidden="false" aria-describedby="postFooterSocialMenu" aria-labelledby="postFooterSocialMenu"><div><div class="bm" aria-hidden="false"><button aria-controls="postFooterSocialMenu" aria-expanded="false" aria-label="Share Post" data-testid="footerSocialShareButton" class="af fk ah ai aj ak al mf an ao ap ex mg mh lv mi"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M15.218 4.931a.4.4 0 0 1-.118.132l.012.006a.45.45 0 0 1-.292.074.5.5 0 0 1-.3-.13l-2.02-2.02v7.07c0 .28-.23.5-.5.5s-.5-.22-.5-.5v-7.04l-2 2a.45.45 0 0 1-.57.04h-.02a.4.4 0 0 1-.16-.3.4.4 0 0 1 .1-.32l2.8-2.8a.5.5 0 0 1 .7 0l2.8 2.79a.42.42 0 0 1 .068.498m-.106.138.008.004v-.01zM16 7.063h1.5a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-11c-1.1 0-2-.9-2-2v-10a2 2 0 0 1 2-2H8a.5.5 0 0 1 .35.15.5.5 0 0 1 .15.35.5.5 0 0 1-.15.35.5.5 0 0 1-.35.15H6.4c-.5 0-.9.4-.9.9v10.2a.9.9 0 0 0 .9.9h11.2c.5 0 .9-.4.9-.9v-10.2c0-.5-.4-.9-.9-.9H16a.5.5 0 0 1 0-1" clip-rule="evenodd"></path></svg></button></div></div></div></div></div></div></div></div></div></footer><div class="sz ta tb tc td l"><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="te bh r tf"></div><div class="tg l"><div class="ab th ti tj iz iy"><div class="tk tl tm tn to tp tq tr ts tt ab cp"><div class="h k"><a href="https://proandroiddev.com/?source=post_page---post_publication_info--fbdc855824ad--------------------------------" rel="noopener follow"><div class="fj ab"><img alt="ProAndroidDev" class="tu ib ic cx" src="https://miro.medium.com/v2/resize:fill:96:96/1*XVtdl45m8YaYrPI4buJ5yQ.png" width="48" height="48" loading="lazy"/><div class="tu l ic ib fs n fr tv"></div></div></a></div><div class="j i d"><a href="https://proandroiddev.com/?source=post_page---post_publication_info--fbdc855824ad--------------------------------" rel="noopener follow"><div class="fj ab"><img alt="ProAndroidDev" class="tu tx tw cx" src="https://miro.medium.com/v2/resize:fill:128:128/1*XVtdl45m8YaYrPI4buJ5yQ.png" width="64" height="64" loading="lazy"/><div class="tu l tw tx fs n fr tv"></div></div></a></div><div class="j i d ty ix"><div class="ab"><span><a class="bf b bg z tz si ua ub uc ud ue ev ew uf ug uh fa fb fc fd bm fe ff" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fsubscribe%2Fcollection%2Fproandroiddev&amp;operation=register&amp;redirect=https%3A%2F%2Fproandroiddev.com%2Fnow-in-android-with-koin-part-4-fbdc855824ad&amp;collection=ProAndroidDev&amp;collectionId=c72404660798&amp;source=post_page---post_publication_info--fbdc855824ad---------------------follow_profile-----------" rel="noopener follow">Follow</a></span></div></div></div><div class="ab co rt"><div class="ui uj uk ul um l"><a class="af ag ah aj ak al am an ao ap aq ar as at ab q" href="https://proandroiddev.com/?source=post_page---post_publication_info--fbdc855824ad--------------------------------" rel="noopener follow"><h2 class="pw-author-name bf uo up uq ur us ut uu ob uv uw of ux uy oj uz va bk"><span class="gn un">Published in <!-- -->ProAndroidDev</span></h2></a><div class="rx ab ia"><div class="l ix"><span class="pw-follower-count bf b bg z du"><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/followers?source=post_page---post_publication_info--fbdc855824ad--------------------------------">62K Followers</a></span></div><div class="bf b bg z du ab jd"><span class="ir l" aria-hidden="true"><span class="bf b bg z du">·</span></span><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/benchmarking-koin-vs-dagger-hilt-in-modern-android-development-2024-ff7bb40470df?source=post_page---post_publication_info--fbdc855824ad--------------------------------">Last published <!-- -->3 days ago</a></div></div><div class="vb l"><p class="bf b bg z bk"><span class="gn">The latest posts from Android Professionals and Google Developer Experts.</span></p></div></div></div><div class="h k"><div class="ab"><span><a class="bf b bg z tz si ua ub uc ud ue ev ew uf ug uh fa fb fc fd bm fe ff" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fsubscribe%2Fcollection%2Fproandroiddev&amp;operation=register&amp;redirect=https%3A%2F%2Fproandroiddev.com%2Fnow-in-android-with-koin-part-4-fbdc855824ad&amp;collection=ProAndroidDev&amp;collectionId=c72404660798&amp;source=post_page---post_publication_info--fbdc855824ad---------------------follow_profile-----------" rel="noopener follow">Follow</a></span></div></div></div></div><div class="ab th ti tj iz iy"><div class="tk tl tm tn to tp tq tr ts tt ab cp"><div class="h k"><a tabindex="0" href="https://giuliani-arnaud.medium.com/?source=post_page---post_author_info--fbdc855824ad--------------------------------" rel="noopener follow"><div class="l fj"><img alt="Arnaud Giuliani" class="l fd by ic ib cx" src="https://miro.medium.com/v2/resize:fill:96:96/1*aRvmkmivw-VRIX-6wYUVCA.jpeg" width="48" height="48" loading="lazy"/><div class="fr by l ic ib fs n ay tv"></div></div></a></div><div class="j i d"><a tabindex="0" href="https://giuliani-arnaud.medium.com/?source=post_page---post_author_info--fbdc855824ad--------------------------------" rel="noopener follow"><div class="l fj"><img alt="Arnaud Giuliani" class="l fd by tw tx cx" src="https://miro.medium.com/v2/resize:fill:128:128/1*aRvmkmivw-VRIX-6wYUVCA.jpeg" width="64" height="64" loading="lazy"/><div class="fr by l tw tx fs n ay tv"></div></div></a></div><div class="j i d ty ix"><div class="ab"><span><a class="bf b bg z tz si ua ub uc ud ue ev ew uf ug uh fa fb fc fd bm fe ff" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fsubscribe%2Fuser%2F9ad99ca649d4&amp;operation=register&amp;redirect=https%3A%2F%2Fproandroiddev.com%2Fnow-in-android-with-koin-part-4-fbdc855824ad&amp;user=Arnaud+Giuliani&amp;userId=9ad99ca649d4&amp;source=post_page-9ad99ca649d4--post_author_info--fbdc855824ad---------------------follow_profile-----------" rel="noopener follow">Follow</a></span></div></div></div><div class="ab co rt"><div class="ui uj uk ul um l"><a class="af ag ah aj ak al am an ao ap aq ar as at ab q" href="https://giuliani-arnaud.medium.com/?source=post_page---post_author_info--fbdc855824ad--------------------------------" rel="noopener follow"><h2 class="pw-author-name bf uo up uq ur us ut uu ob uv uw of ux uy oj uz va bk"><span class="gn un">Written by <!-- -->Arnaud Giuliani</span></h2></a><div class="rx ab ia"><div class="l ix"><span class="pw-follower-count bf b bg z du"><a class="af ag ah ai aj ak al am an ao ap aq ar iq" href="https://giuliani-arnaud.medium.com/followers?source=post_page---post_author_info--fbdc855824ad--------------------------------" rel="noopener follow">2.3K Followers</a></span></div><div class="bf b bg z du ab jd"><span class="ir l" aria-hidden="true"><span class="bf b bg z du">·</span></span><a class="af ag ah ai aj ak al am an ao ap aq ar iq" href="https://medium.com/@giuliani-arnaud/following?source=post_page---post_author_info--fbdc855824ad--------------------------------" rel="noopener follow">61 Following</a></div></div><div class="vb l"><p class="bf b bg z bk">Lead of #Koin framework (<a class="af ag ah ai aj ak al am an ao ap aq ar np go" href="http://insert-koin.io" rel="noopener ugc nofollow">insert-koin.io</a>) - Co-founder of Kotzilla (<a class="af ag ah ai aj ak al am an ao ap aq ar np go" href="http://kotzilla.io" rel="noopener ugc nofollow">kotzilla.io</a>) - Google Dev Expert #Kotlin - #AndroidDev</p></div></div></div><div class="h k"><div class="ab"><span><a class="bf b bg z tz si ua ub uc ud ue ev ew uf ug uh fa fb fc fd bm fe ff" href="https://medium.com/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fsubscribe%2Fuser%2F9ad99ca649d4&amp;operation=register&amp;redirect=https%3A%2F%2Fproandroiddev.com%2Fnow-in-android-with-koin-part-4-fbdc855824ad&amp;user=Arnaud+Giuliani&amp;userId=9ad99ca649d4&amp;source=post_page-9ad99ca649d4--post_author_info--fbdc855824ad---------------------follow_profile-----------" rel="noopener follow">Follow</a></span></div></div></div></div></div></div><div class="vc vd ve vf vg l"><div class="te bh r vc vd vh vi vj"></div><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="ab q cp"><h2 class="bf uo pj pl pm pn pp pq pr pt pu pv px py pz qb qc bk">Responses (<!-- -->1<!-- -->)</h2><div class="ab vk"><div><div class="bm" aria-hidden="false"><a class="vl vm" href="https://policy.medium.com/medium-rules-30e5502c4eb4?source=post_page---post_responses--fbdc855824ad--------------------------------" rel="noopener follow" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 25 25"><path fill-rule="evenodd" d="M11.987 5.036a.754.754 0 0 1 .914-.01c.972.721 1.767 1.218 2.6 1.543.828.322 1.719.485 2.887.505a.755.755 0 0 1 .741.757c-.018 3.623-.43 6.256-1.449 8.21-1.034 1.984-2.662 3.209-4.966 4.083a.75.75 0 0 1-.537-.003c-2.243-.874-3.858-2.095-4.897-4.074-1.024-1.951-1.457-4.583-1.476-8.216a.755.755 0 0 1 .741-.757c1.195-.02 2.1-.182 2.923-.503.827-.322 1.6-.815 2.519-1.535m.468.903c-.897.69-1.717 1.21-2.623 1.564-.898.35-1.856.527-3.026.565.037 3.45.469 5.817 1.36 7.515.884 1.684 2.25 2.762 4.284 3.571 2.092-.81 3.465-1.89 4.344-3.575.886-1.698 1.299-4.065 1.334-7.512-1.149-.039-2.091-.217-2.99-.567-.906-.353-1.745-.873-2.683-1.561m-.009 9.155a2.672 2.672 0 1 0 0-5.344 2.672 2.672 0 0 0 0 5.344m0 1a3.672 3.672 0 1 0 0-7.344 3.672 3.672 0 0 0 0 7.344m-1.813-3.777.525-.526.916.917 1.623-1.625.526.526-2.149 2.152z" clip-rule="evenodd"></path></svg></a></div></div></div></div><div class="os l"><button class="bf b bg z bk si vn vo vp lx lu ue ev ew ex vq vr vs fa vt vu vv vw vx fb fc fd bm fe ff">See all responses</button></div></div></div></div><div class="vy vz wa wb wc l bx"><div class="h k j"><div class="te bh wd we"></div><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="wf ab kv ja"><div class="wg wh l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://help.medium.com/hc/en-us?source=post_page-----fbdc855824ad--------------------------------" rel="noopener follow"><p class="bf b dv z du">Help</p></a></div><div class="wg wh l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://medium.statuspage.io/?source=post_page-----fbdc855824ad--------------------------------" rel="noopener follow"><p class="bf b dv z du">Status</p></a></div><div class="wg wh l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://medium.com/about?autoplay=1&amp;source=post_page-----fbdc855824ad--------------------------------" rel="noopener follow"><p class="bf b dv z du">About</p></a></div><div class="wg wh l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://medium.com/jobs-at-medium/work-at-medium-959d1a85284e?source=post_page-----fbdc855824ad--------------------------------" rel="noopener follow"><p class="bf b dv z du">Careers</p></a></div><div class="wg wh l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="pressinquiries@medium.com?source=post_page-----fbdc855824ad--------------------------------" rel="noopener follow"><p class="bf b dv z du">Press</p></a></div><div class="wg wh l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://blog.medium.com/?source=post_page-----fbdc855824ad--------------------------------" rel="noopener follow"><p class="bf b dv z du">Blog</p></a></div><div class="wg wh l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://policy.medium.com/medium-privacy-policy-f03bf92035c9?source=post_page-----fbdc855824ad--------------------------------" rel="noopener follow"><p class="bf b dv z du">Privacy</p></a></div><div class="wg wh l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://policy.medium.com/medium-terms-of-service-9db0094a1e0f?source=post_page-----fbdc855824ad--------------------------------" rel="noopener follow"><p class="bf b dv z du">Terms</p></a></div><div class="wg wh l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://speechify.com/medium?source=post_page-----fbdc855824ad--------------------------------" rel="noopener follow"><p class="bf b dv z du">Text to speech</p></a></div><div class="wg l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://medium.com/business?source=post_page-----fbdc855824ad--------------------------------" rel="noopener follow"><p class="bf b dv z du">Teams</p></a></div></div></div></div></div></div></div></div></div></div><script>window.__BUILD_ID__="main-20241129-135346-5cf0f044cd"</script><script>window.__GRAPHQL_URI__ = "https://proandroiddev.com/_/graphql"</script><script>window.__PRELOADED_STATE__ = {"algolia":{"queries":{}},"cache":{"experimentGroupSet":true,"reason":"This request is not using the cache middleware worker","group":"disabled","tags":["group-edgeCachePosts","post-fbdc855824ad","user-9ad99ca649d4","collection-c72404660798"],"serverVariantState":"","middlewareEnabled":false,"cacheStatus":"DYNAMIC","shouldUseCache":false,"vary":[],"lohpSummerUpsellEnabled":false,"publicationHierarchyEnabledWeb":false,"postBottomResponsesEnabled":false},"client":{"hydrated":false,"isUs":false,"isNativeMedium":false,"isSafariMobile":false,"isSafari":false,"isFirefox":false,"routingEntity":{"type":"COLLECTION","id":"c72404660798","explicit":true},"viewerIsBot":false},"debug":{"requestId":"143ed16f-9ce6-4b32-9ec7-588d115d351a","hybridDevServices":[],"originalSpanCarrier":{"traceparent":"00-c255f6169c1574cb520d5454428f888e-85cb76c805a5287a-01"}},"multiVote":{"clapsPerPost":{}},"navigation":{"branch":{"show":null,"hasRendered":null,"blockedByCTA":false},"hideGoogleOneTap":false,"hasRenderedAlternateUserBanner":null,"currentLocation":"https:\u002F\u002Fproandroiddev.com\u002Fnow-in-android-with-koin-part-4-fbdc855824ad","host":"proandroiddev.com","hostname":"proandroiddev.com","referrer":"","hasSetReferrer":false,"susiModal":{"step":null,"operation":"register"},"postRead":false,"partnerProgram":{"selectedCountryCode":null}},"config":{"nodeEnv":"production","version":"main-20241129-135346-5cf0f044cd","target":"production","productName":"Medium","publicUrl":"https:\u002F\u002Fcdn-client.medium.com\u002Flite","authDomain":"medium.com","authGoogleClientId":"216296035834-k1k6qe060s2tp2a2jam4ljdcms00sttg.apps.googleusercontent.com","favicon":"production","glyphUrl":"https:\u002F\u002Fglyph.medium.com","branchKey":"key_live_ofxXr2qTrrU9NqURK8ZwEhknBxiI6KBm","algolia":{"appId":"MQ57UUUQZ2","apiKeySearch":"394474ced050e3911ae2249ecc774921","indexPrefix":"medium_","host":"-dsn.algolia.net"},"recaptchaKey":"6Lfc37IUAAAAAKGGtC6rLS13R1Hrw_BqADfS1LRk","recaptcha3Key":"6Lf8R9wUAAAAABMI_85Wb8melS7Zj6ziuf99Yot5","recaptchaEnterpriseKeyId":"6Le-uGgpAAAAAPprRaokM8AKthQ9KNGdoxaGUvVp","datadog":{"applicationId":"6702d87d-a7e0-42fe-bbcb-95b469547ea0","clientToken":"pub853ea8d17ad6821d9f8f11861d23dfed","rumToken":"pubf9cc52896502b9413b68ba36fc0c7162","context":{"deployment":{"target":"production","tag":"main-20241129-135346-5cf0f044cd","commit":"5cf0f044cde04a296c7f1e11fd4877d75fdab011"}},"datacenter":"us"},"googleAnalyticsCode":"G-7JY7T788PK","googlePay":{"apiVersion":"2","apiVersionMinor":"0","merchantId":"BCR2DN6TV7EMTGBM","merchantName":"Medium","instanceMerchantId":"13685562959212738550"},"applePay":{"version":3},"signInWallCustomDomainCollectionIds":["3a8144eabfe3","336d898217ee","61061eb0c96b","138adf9c44c","819cc2aaeee0"],"mediumMastodonDomainName":"me.dm","mediumOwnedAndOperatedCollectionIds":["8a9336e5bb4","b7e45b22fec3","193b68bd4fba","8d6b8a439e32","54c98c43354d","3f6ecf56618","d944778ce714","92d2092dc598","ae2a65f35510","1285ba81cada","544c7006046e","fc8964313712","40187e704f1c","88d9857e584e","7b6769f2748b","bcc38c8f6edf","cef6983b292","cb8577c9149e","444d13b52878","713d7dbc99b0","ef8e90590e66","191186aaafa0","55760f21cdc5","9dc80918cc93","bdc4052bbdba","8ccfed20cbb2"],"tierOneDomains":["medium.com","thebolditalic.com","arcdigital.media","towardsdatascience.com","uxdesign.cc","codeburst.io","psiloveyou.xyz","writingcooperative.com","entrepreneurshandbook.co","prototypr.io","betterhumans.coach.me","theascent.pub"],"topicsToFollow":["d61cf867d93f","8a146bc21b28","1eca0103fff3","4d562ee63426","aef1078a3ef5","e15e46793f8d","6158eb913466","55f1c20aba7a","3d18b94f6858","4861fee224fd","63c6f1f93ee","1d98b3a9a871","decb52b64abf","ae5d4995e225","830cded25262"],"topicToTagMappings":{"accessibility":"accessibility","addiction":"addiction","android-development":"android-development","art":"art","artificial-intelligence":"artificial-intelligence","astrology":"astrology","basic-income":"basic-income","beauty":"beauty","biotech":"biotech","blockchain":"blockchain","books":"books","business":"business","cannabis":"cannabis","cities":"cities","climate-change":"climate-change","comics":"comics","coronavirus":"coronavirus","creativity":"creativity","cryptocurrency":"cryptocurrency","culture":"culture","cybersecurity":"cybersecurity","data-science":"data-science","design":"design","digital-life":"digital-life","disability":"disability","economy":"economy","education":"education","equality":"equality","family":"family","feminism":"feminism","fiction":"fiction","film":"film","fitness":"fitness","food":"food","freelancing":"freelancing","future":"future","gadgets":"gadgets","gaming":"gaming","gun-control":"gun-control","health":"health","history":"history","humor":"humor","immigration":"immigration","ios-development":"ios-development","javascript":"javascript","justice":"justice","language":"language","leadership":"leadership","lgbtqia":"lgbtqia","lifestyle":"lifestyle","machine-learning":"machine-learning","makers":"makers","marketing":"marketing","math":"math","media":"media","mental-health":"mental-health","mindfulness":"mindfulness","money":"money","music":"music","neuroscience":"neuroscience","nonfiction":"nonfiction","outdoors":"outdoors","parenting":"parenting","pets":"pets","philosophy":"philosophy","photography":"photography","podcasts":"podcast","poetry":"poetry","politics":"politics","privacy":"privacy","product-management":"product-management","productivity":"productivity","programming":"programming","psychedelics":"psychedelics","psychology":"psychology","race":"race","relationships":"relationships","religion":"religion","remote-work":"remote-work","san-francisco":"san-francisco","science":"science","self":"self","self-driving-cars":"self-driving-cars","sexuality":"sexuality","social-media":"social-media","society":"society","software-engineering":"software-engineering","space":"space","spirituality":"spirituality","sports":"sports","startups":"startup","style":"style","technology":"technology","transportation":"transportation","travel":"travel","true-crime":"true-crime","tv":"tv","ux":"ux","venture-capital":"venture-capital","visual-design":"visual-design","work":"work","world":"world","writing":"writing"},"defaultImages":{"avatar":{"imageId":"1*dmbNkD5D-u45r44go_cf0g.png","height":150,"width":150},"orgLogo":{"imageId":"7*V1_7XP4snlmqrc_0Njontw.png","height":110,"width":500},"postLogo":{"imageId":"bd978bb536350a710e8efb012513429cabdc4c28700604261aeda246d0f980b7","height":810,"width":1440},"postPreviewImage":{"imageId":"1*hn4v1tCaJy7cWMyb0bpNpQ.png","height":386,"width":579}},"collectionStructuredData":{"8d6b8a439e32":{"name":"Elemental","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F980\u002F1*9ygdqoKprhwuTVKUM0DLPA@2x.png","width":980,"height":159}}},"3f6ecf56618":{"name":"Forge","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F596\u002F1*uULpIlImcO5TDuBZ6lm7Lg@2x.png","width":596,"height":183}}},"ae2a65f35510":{"name":"GEN","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F264\u002F1*RdVZMdvfV3YiZTw6mX7yWA.png","width":264,"height":140}}},"88d9857e584e":{"name":"LEVEL","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*JqYMhNX6KNNb2UlqGqO2WQ.png","width":540,"height":108}}},"7b6769f2748b":{"name":"Marker","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F383\u002F1*haCUs0wF6TgOOvfoY-jEoQ@2x.png","width":383,"height":92}}},"444d13b52878":{"name":"OneZero","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*cw32fIqCbRWzwJaoQw6BUg.png","width":540,"height":123}}},"8ccfed20cbb2":{"name":"Zora","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*tZUQqRcCCZDXjjiZ4bDvgQ.png","width":540,"height":106}}}},"embeddedPostIds":{"coronavirus":"cd3010f9d81f"},"sharedCdcMessaging":{"COVID_APPLICABLE_TAG_SLUGS":[],"COVID_APPLICABLE_TOPIC_NAMES":[],"COVID_APPLICABLE_TOPIC_NAMES_FOR_TOPIC_PAGE":[],"COVID_MESSAGES":{"tierA":{"text":"For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":66,"end":73,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"tierB":{"text":"Anyone can publish on Medium per our Policies, but we don’t fact-check every story. For more info about the coronavirus, see cdc.gov.","markups":[{"start":37,"end":45,"href":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Fcategories\u002F201931128-Policies-Safety"},{"start":125,"end":132,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"paywall":{"text":"This article has been made free for everyone, thanks to Medium Members. For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":56,"end":70,"href":"https:\u002F\u002Fmedium.com\u002Fmembership"},{"start":138,"end":145,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"unbound":{"text":"This article is free for everyone, thanks to Medium Members. For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":45,"end":59,"href":"https:\u002F\u002Fmedium.com\u002Fmembership"},{"start":127,"end":134,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]}},"COVID_BANNER_POST_ID_OVERRIDE_WHITELIST":["3b31a67bff4a"]},"sharedVoteMessaging":{"TAGS":["politics","election-2020","government","us-politics","election","2020-presidential-race","trump","donald-trump","democrats","republicans","congress","republican-party","democratic-party","biden","joe-biden","maga"],"TOPICS":["politics","election"],"MESSAGE":{"text":"Find out more about the U.S. election results here.","markups":[{"start":46,"end":50,"href":"https:\u002F\u002Fcookpolitical.com\u002F2020-national-popular-vote-tracker"}]},"EXCLUDE_POSTS":["397ef29e3ca5"]},"embedPostRules":[],"recircOptions":{"v1":{"limit":3},"v2":{"limit":8}},"braintreeClientKey":"production_zjkj96jm_m56f8fqpf7ngnrd4","braintree":{"enabled":true,"merchantId":"m56f8fqpf7ngnrd4","merchantAccountId":{"usd":"AMediumCorporation_instant","eur":"amediumcorporation_EUR","cad":"amediumcorporation_CAD"},"publicKey":"ds2nn34bg2z7j5gd","braintreeEnvironment":"production","dashboardUrl":"https:\u002F\u002Fwww.braintreegateway.com\u002Fmerchants","gracePeriodDurationInDays":14,"mediumMembershipPlanId":{"monthly":"ce105f8c57a3","monthlyV2":"e8a5e126-792b-4ee6-8fba-d574c1b02fc5","monthlyWithTrial":"d5ee3dbe3db8","monthlyPremium":"fa741a9b47a2","yearly":"a40ad4a43185","yearlyV2":"3815d7d6-b8ca-4224-9b8c-182f9047866e","yearlyStaff":"d74fb811198a","yearlyWithTrial":"b3bc7350e5c7","yearlyPremium":"e21bd2c12166","monthlyOneYearFree":"e6c0637a-2bad-4171-ab4f-3c268633d83c","monthly25PercentOffFirstYear":"235ecc62-0cdb-49ae-9378-726cd21c504b","monthly20PercentOffFirstYear":"ba518864-9c13-4a99-91ca-411bf0cac756","monthly15PercentOffFirstYear":"594c029b-9f89-43d5-88f8-8173af4e070e","monthly10PercentOffFirstYear":"c6c7bc9a-40f2-4b51-8126-e28511d5bdb0","monthlyForStudents":"629ebe51-da7d-41fd-8293-34cd2f2030a8","yearlyOneYearFree":"78ba7be9-0d9f-4ece-aa3e-b54b826f2bf1","yearly25PercentOffFirstYear":"2dbb010d-bb8f-4eeb-ad5c-a08509f42d34","yearly20PercentOffFirstYear":"47565488-435b-47f8-bf93-40d5fbe0ebc8","yearly15PercentOffFirstYear":"8259809b-0881-47d9-acf7-6c001c7f720f","yearly10PercentOffFirstYear":"9dd694fb-96e1-472c-8d9e-3c868d5c1506","yearlyForStudents":"e29345ef-ab1c-4234-95c5-70e50fe6bc23","monthlyCad":"p52orjkaceei","yearlyCad":"h4q9g2up9ktt"},"braintreeDiscountId":{"oneMonthFree":"MONTHS_FREE_01","threeMonthsFree":"MONTHS_FREE_03","sixMonthsFree":"MONTHS_FREE_06","fiftyPercentOffOneYear":"FIFTY_PERCENT_OFF_ONE_YEAR"},"3DSecureVersion":"2","defaultCurrency":"usd","providerPlanIdCurrency":{"4ycw":"usd","rz3b":"usd","3kqm":"usd","jzw6":"usd","c2q2":"usd","nnsw":"usd","q8qw":"usd","d9y6":"usd","fx7w":"cad","nwf2":"cad"}},"paypalClientId":"AXj1G4fotC2GE8KzWX9mSxCH1wmPE3nJglf4Z2ig_amnhvlMVX87otaq58niAg9iuLktVNF_1WCMnN7v","paypal":{"host":"https:\u002F\u002Fapi.paypal.com:443","clientMode":"production","serverMode":"live","webhookId":"4G466076A0294510S","monthlyPlan":{"planId":"P-9WR0658853113943TMU5FDQA","name":"Medium Membership (Monthly) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"yearlyPlan":{"planId":"P-7N8963881P8875835MU5JOPQ","name":"Medium Membership (Annual) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"oneYearGift":{"name":"Medium Membership (1 Year, Digital Gift Code)","description":"Unlimited access to the best and brightest stories on Medium. Gift codes can be redeemed at medium.com\u002Fredeem.","price":"50.00","currency":"USD","sku":"membership-gift-1-yr"},"oldMonthlyPlan":{"planId":"P-96U02458LM656772MJZUVH2Y","name":"Medium Membership (Monthly)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"oldYearlyPlan":{"planId":"P-59P80963JF186412JJZU3SMI","name":"Medium Membership (Annual)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"monthlyPlanWithTrial":{"planId":"P-66C21969LR178604GJPVKUKY","name":"Medium Membership (Monthly) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"yearlyPlanWithTrial":{"planId":"P-6XW32684EX226940VKCT2MFA","name":"Medium Membership (Annual) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"oldMonthlyPlanNoSetupFee":{"planId":"P-4N046520HR188054PCJC7LJI","name":"Medium Membership (Monthly)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"oldYearlyPlanNoSetupFee":{"planId":"P-7A4913502Y5181304CJEJMXQ","name":"Medium Membership (Annual)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"sdkUrl":"https:\u002F\u002Fwww.paypal.com\u002Fsdk\u002Fjs"},"stripePublishableKey":"pk_live_7FReX44VnNIInZwrIIx6ghjl","log":{"json":true,"level":"info"},"imageUploadMaxSizeMb":25,"staffPicks":{"title":"Staff Picks","catalogId":"c7bc6e1ee00f"}},"session":{"xsrf":""}}</script><script>window.__APOLLO_STATE__ = {"ROOT_QUERY":{"__typename":"Query","viewer":null,"variantFlags":[{"__typename":"VariantFlag","name":"enable_tipping_v0_android","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"android_enable_image_sharer","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_seamless_social_sharing","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_deprecate_legacy_providers_v3","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_google_webhook","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_lo_homepage","valueType":{"__typename":"VariantFlagString","value":"control"}},{"__typename":"VariantFlag","name":"ios_display_paywall_after_onboarding","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_enable_friend_links_creation","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_android_miro_v2","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_auto_follow_on_subscribe","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_publication_hierarchy_web","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_update_topic_portals_wtf","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_author_cards","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_rito_upstream_deadlines","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_enable_lock_responses","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_android_offline_reading","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_lite_response_markup","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_ranker_v10","valueType":{"__typename":"VariantFlagString","value":"control"}},{"__typename":"VariantFlag","name":"rex_generator_max_candidates","valueType":{"__typename":"VariantFlagNumber","value":1000}},{"__typename":"VariantFlag","name":"enable_conversion_model_v2","valueType":{"__typename":"VariantFlagString","value":"group_2"}},{"__typename":"VariantFlag","name":"enable_moc_load_processor_all_recs_surfaces","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_braintree_paypal","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_maim_the_meter","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"signin_services","valueType":{"__typename":"VariantFlagString","value":"twitter,facebook,google,email,google-fastidv,google-one-tap,apple"}},{"__typename":"VariantFlag","name":"ios_enable_friend_links_postpage_banners","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"available_monthly_premium_plan","valueType":{"__typename":"VariantFlagString","value":"12a660186432"}},{"__typename":"VariantFlag","name":"enable_speechify_ios","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_updated_pub_recs_ui","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_starspace","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_ios_easy_resubscribe","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"can_send_tips_v0","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_update_explore_wtf","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"redefined_top_posts","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_author_cards_byline","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_ml_rank_rex_anno","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_remove_twitter_onboarding_step","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_lite_homepage","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_marketing_emails","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_rex_new_push_notification_endpoint","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"available_annual_plan","valueType":{"__typename":"VariantFlagString","value":"2c754bcc2995"}},{"__typename":"VariantFlag","name":"enable_android_dynamic_aspirational_paywall","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"limit_user_follows","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"android_rating_prompt_stories_read_threshold","valueType":{"__typename":"VariantFlagNumber","value":2}},{"__typename":"VariantFlag","name":"can_receive_tips_v0","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_medium2_kbfd","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_pill_based_home_feed","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_post_bottom_responses","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"allow_access","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_recaptcha_enterprise","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_recommended_publishers_query","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_see_pronouns","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"mobile_custom_app_icon","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_configure_pronouns","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_conversion_ranker_v2","valueType":{"__typename":"VariantFlagString","value":"control"}},{"__typename":"VariantFlag","name":"allow_signup","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"allow_test_auth","valueType":{"__typename":"VariantFlagString","value":"disallow"}},{"__typename":"VariantFlag","name":"android_enable_editor_new_publishing_flow","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_susi_redesign_android","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"android_enable_friend_links_postpage_banners","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_cache_less_following_feed","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_lite_server_upstream_deadlines","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_tag_recs","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_simplified_digest_v2_b","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_speechify_widget","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"onboarding_tags_from_top_views","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_bayesian_average_pub_search","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"textshots_userid","valueType":{"__typename":"VariantFlagString","value":""}},{"__typename":"VariantFlag","name":"ios_enable_verified_book_author","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_iceland_nux","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"available_annual_premium_plan","valueType":{"__typename":"VariantFlagString","value":"4a442ace1476"}},{"__typename":"VariantFlag","name":"enable_app_flirty_thirty","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_bg_post_post","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_ios_dynamic_paywall_programming","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_in_app_free_trial","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"android_enable_lists_v2","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_abandoned_cart_promotion_email","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_premium_tier","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_post_bottom_responses_input","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_explicit_signals","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"android_enable_syntax_highlight","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_mastodon_for_members","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_tick_landing_page","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"coronavirus_topic_recirc","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_switch_plan_premium_tier","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_braintree_client","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_sharer_create_post_share_key","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_apple_webhook","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_google_one_tap","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_premium_tier_badge","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_explicit_signals_updated_post_previews","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_ios_offline_reading","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_aurora_pub_follower_page","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_billing_frequency_on_step2","valueType":{"__typename":"VariantFlagString","value":"control"}},{"__typename":"VariantFlag","name":"enable_braintree_webhook","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_entities_to_follow_v2","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"signup_services","valueType":{"__typename":"VariantFlagString","value":"twitter,facebook,google,email,google-fastidv,google-one-tap,apple"}},{"__typename":"VariantFlag","name":"enable_mastodon_for_members_username_selection","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_pre_pp_v4","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_verifications_service","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_pp_country_expansion","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"goliath_externalsearch_enable_comment_deindexation","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_braintree_apple_pay","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_lite_archive_page","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_boost_nia_v01","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_rex_reading_history","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"reader_fair_distribution_non_qp","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_legacy_feed_in_iceland","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_sharer_validate_post_share_key","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"android_two_hour_refresh","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_braintree_integration","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_eventstats_event_processing","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"android_enable_friend_links_creation","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_import","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"num_post_bottom_responses_to_show","valueType":{"__typename":"VariantFlagString","value":"1"}},{"__typename":"VariantFlag","name":"browsable_stream_config_bucket","valueType":{"__typename":"VariantFlagString","value":"curated-topics"}},{"__typename":"VariantFlag","name":"enable_iceland_forced_android","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_pp_v4","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_newsletter_lo_flow_custom_domains","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"price_smoke_test_monthly","valueType":{"__typename":"VariantFlagString","value":""}},{"__typename":"VariantFlag","name":"enable_apple_sign_in","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_mastodon_avatar_upload","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_enable_home_post_menu","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_diversification_rex","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_braintree_google_pay","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_creator_welcome_email","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_branch_io","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_intrinsic_automatic_actions","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_new_stripe_customers","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_recirc_model","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_ios_dynamic_paywall_aspiriational","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_new_manage_membership_flow","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_android_dynamic_programming_paywall","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_moc_load_processor_first_story","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_rex_aggregator_v2","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_sprig","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"disable_partner_program_enrollment","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_group_gifting","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_ios_autorefresh","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_tipping_v0_ios","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_android_verified_author","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_members_only_audio","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_tribute_landing_page","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"ios_social_share_sheet","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_susi_redesign_ios","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"skip_fs_cache_user_vals","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"android_enable_topic_portals","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_automod","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_moc_load_processor_c","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"price_smoke_test_yearly","valueType":{"__typename":"VariantFlagString","value":""}},{"__typename":"VariantFlag","name":"enable_lite_continue_this_thread","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"limit_post_referrers","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"available_monthly_plan","valueType":{"__typename":"VariantFlagString","value":"60e220181034"}},{"__typename":"VariantFlag","name":"enable_footer_app_buttons","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"enable_braintree_trial_membership","valueType":{"__typename":"VariantFlagBoolean","value":true}},{"__typename":"VariantFlag","name":"glyph_font_set","valueType":{"__typename":"VariantFlagString","value":"m2-unbound-source-serif-pro"}},{"__typename":"VariantFlag","name":"reengagement_notification_duration","valueType":{"__typename":"VariantFlagNumber","value":3}}],"collectionByDomainOrSlug({\"domainOrSlug\":\"proandroiddev.com\"})":{"__ref":"Collection:c72404660798"},"postResult({\"id\":\"fbdc855824ad\"})":{"__ref":"Post:fbdc855824ad"}},"ImageMetadata:1*A8VytPZQhvUf_MG6hm_Dlw.png":{"__typename":"ImageMetadata","id":"1*A8VytPZQhvUf_MG6hm_Dlw.png"},"Collection:c72404660798":{"__typename":"Collection","id":"c72404660798","favicon":{"__ref":"ImageMetadata:1*A8VytPZQhvUf_MG6hm_Dlw.png"},"customStyleSheet":null,"colorPalette":{"__typename":"ColorPalette","highlightSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FFFFFFFF","colorPoints":[{"__typename":"ColorPoint","color":"#FFE4F8EF","point":0},{"__typename":"ColorPoint","color":"#FFDEF8ED","point":0.1},{"__typename":"ColorPoint","color":"#FFD9F7EB","point":0.2},{"__typename":"ColorPoint","color":"#FFD3F6E9","point":0.3},{"__typename":"ColorPoint","color":"#FFCEF6E7","point":0.4},{"__typename":"ColorPoint","color":"#FFC8F5E4","point":0.5},{"__typename":"ColorPoint","color":"#FFC2F4E2","point":0.6},{"__typename":"ColorPoint","color":"#FFBCF4E0","point":0.7},{"__typename":"ColorPoint","color":"#FFB5F3DE","point":0.8},{"__typename":"ColorPoint","color":"#FFAFF2DB","point":0.9},{"__typename":"ColorPoint","color":"#FFA8F2D9","point":1}]},"defaultBackgroundSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FFFFFFFF","colorPoints":[{"__typename":"ColorPoint","color":"#FF2E987E","point":0},{"__typename":"ColorPoint","color":"#FF318D75","point":0.1},{"__typename":"ColorPoint","color":"#FF32826C","point":0.2},{"__typename":"ColorPoint","color":"#FF327663","point":0.3},{"__typename":"ColorPoint","color":"#FF306B5A","point":0.4},{"__typename":"ColorPoint","color":"#FF2E5F50","point":0.5},{"__typename":"ColorPoint","color":"#FF2A5347","point":0.6},{"__typename":"ColorPoint","color":"#FF26463C","point":0.7},{"__typename":"ColorPoint","color":"#FF203931","point":0.8},{"__typename":"ColorPoint","color":"#FF192C25","point":0.9},{"__typename":"ColorPoint","color":"#FF101D19","point":1}]},"tintBackgroundSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FF7DE1C3","colorPoints":[{"__typename":"ColorPoint","color":"#FF7DE1C3","point":0},{"__typename":"ColorPoint","color":"#FF6ED2B5","point":0.1},{"__typename":"ColorPoint","color":"#FF5EC3A6","point":0.2},{"__typename":"ColorPoint","color":"#FF4EB397","point":0.3},{"__typename":"ColorPoint","color":"#FF3CA388","point":0.4},{"__typename":"ColorPoint","color":"#FF269278","point":0.5},{"__typename":"ColorPoint","color":"#FF008168","point":0.6},{"__typename":"ColorPoint","color":"#FF006F57","point":0.7},{"__typename":"ColorPoint","color":"#FF005C45","point":0.8},{"__typename":"ColorPoint","color":"#FF004732","point":0.9},{"__typename":"ColorPoint","color":"#FF002F1C","point":1}]}},"domain":"proandroiddev.com","slug":"proandroiddev","googleAnalyticsId":null,"editors":[{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:fbb92b85b19e"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:eac743c05401"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:c6e8e225f7d5"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:96912518b8bb"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:d022c4e0f12b"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:6fffa5371f97"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:bf87f3641b6c"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:f6e9347ca668"}}],"name":"ProAndroidDev","avatar":{"__ref":"ImageMetadata:1*XVtdl45m8YaYrPI4buJ5yQ.png"},"description":"The latest posts from Android Professionals and Google Developer Experts.","subscriberCount":62479,"latestPostsConnection({\"paging\":{\"limit\":1}})":{"__typename":"PostConnection","posts":[{"__ref":"Post:ff7bb40470df"}]},"viewerEdge":{"__ref":"CollectionViewerEdge:collectionId:c72404660798-viewerId:lo_788b5fc96ef9"},"twitterUsername":"proandroiddev","facebookPageId":null,"logo":{"__ref":"ImageMetadata:"}},"User:fbb92b85b19e":{"__typename":"User","id":"fbb92b85b19e"},"User:eac743c05401":{"__typename":"User","id":"eac743c05401"},"User:c6e8e225f7d5":{"__typename":"User","id":"c6e8e225f7d5"},"User:96912518b8bb":{"__typename":"User","id":"96912518b8bb"},"User:d022c4e0f12b":{"__typename":"User","id":"d022c4e0f12b"},"User:6fffa5371f97":{"__typename":"User","id":"6fffa5371f97"},"User:bf87f3641b6c":{"__typename":"User","id":"bf87f3641b6c"},"User:f6e9347ca668":{"__typename":"User","id":"f6e9347ca668"},"ImageMetadata:1*XVtdl45m8YaYrPI4buJ5yQ.png":{"__typename":"ImageMetadata","id":"1*XVtdl45m8YaYrPI4buJ5yQ.png"},"User:9ad99ca649d4":{"__typename":"User","id":"9ad99ca649d4","customDomainState":{"__typename":"CustomDomainState","live":{"__typename":"CustomDomain","domain":"giuliani-arnaud.medium.com"}},"hasSubdomain":true,"username":"giuliani-arnaud","name":"Arnaud Giuliani","newsletterV3":{"__ref":"NewsletterV3:172ca0c0b886"},"linkedAccounts":{"__ref":"LinkedAccounts:9ad99ca649d4"},"isSuspended":false,"imageId":"1*aRvmkmivw-VRIX-6wYUVCA.jpeg","mediumMemberAt":1716797025000,"verifications":{"__typename":"VerifiedInfo","isBookAuthor":false},"socialStats":{"__typename":"SocialStats","followerCount":2364,"followingCount":40,"collectionFollowingCount":21},"bio":"Lead of #Koin framework (insert-koin.io) - Co-founder of Kotzilla (kotzilla.io) - Google Dev Expert #Kotlin - #AndroidDev","isPartnerProgramEnrolled":false,"viewerEdge":{"__ref":"UserViewerEdge:userId:9ad99ca649d4-viewerId:lo_788b5fc96ef9"},"viewerIsUser":false,"postSubscribeMembershipUpsellShownAt":0,"membership":{"__ref":"Membership:4b8a4137fb97"},"allowNotes":true,"twitterScreenName":""},"Post:ff7bb40470df":{"__typename":"Post","id":"ff7bb40470df","firstPublishedAt":1732672821762,"creator":{"__ref":"User:9ad99ca649d4"},"collection":{"__ref":"Collection:c72404660798"},"isSeries":false,"mediumUrl":"https:\u002F\u002Fproandroiddev.com\u002Fbenchmarking-koin-vs-dagger-hilt-in-modern-android-development-2024-ff7bb40470df","sequence":null,"uniqueSlug":"benchmarking-koin-vs-dagger-hilt-in-modern-android-development-2024-ff7bb40470df"},"LinkedAccounts:9ad99ca649d4":{"__typename":"LinkedAccounts","mastodon":null,"id":"9ad99ca649d4"},"UserViewerEdge:userId:9ad99ca649d4-viewerId:lo_788b5fc96ef9":{"__typename":"UserViewerEdge","id":"userId:9ad99ca649d4-viewerId:lo_788b5fc96ef9","isFollowing":false,"isUser":false,"isMuting":false},"NewsletterV3:172ca0c0b886":{"__typename":"NewsletterV3","id":"172ca0c0b886","type":"NEWSLETTER_TYPE_AUTHOR","slug":"9ad99ca649d4","name":"9ad99ca649d4","collection":null,"user":{"__ref":"User:9ad99ca649d4"}},"Membership:4b8a4137fb97":{"__typename":"Membership","tier":"MEMBER","id":"4b8a4137fb97"},"Paragraph:5a101a705abe_0":{"__typename":"Paragraph","id":"5a101a705abe_0","name":"a486","type":"H3","href":null,"layout":null,"metadata":null,"text":"Now In Android with Koin — part 4","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*hVKWuT24riZnx4VzDpQVJQ.png":{"__typename":"ImageMetadata","id":"1*hVKWuT24riZnx4VzDpQVJQ.png","originalHeight":935,"originalWidth":1920,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:5a101a705abe_1":{"__typename":"Paragraph","id":"5a101a705abe_1","name":"94f9","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*hVKWuT24riZnx4VzDpQVJQ.png"},"text":"Koined from original banner — https:\u002F\u002Fgithub.com\u002Fandroid\u002Fnowinandroid","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":30,"end":69,"href":"https:\u002F\u002Fgithub.com\u002Fandroid\u002Fnowinandroid","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_2":{"__typename":"Paragraph","id":"5a101a705abe_2","name":"7a78","type":"P","href":null,"layout":null,"metadata":null,"text":"Now In Android is an open-source Android application that covers Modern Android Development best practices. The project is maintained by the Google Android team.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":0,"end":14,"href":"https:\u002F\u002Fgithub.com\u002Fandroid\u002Fnowinandroid","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_3":{"__typename":"Paragraph","id":"5a101a705abe_3","name":"03be","type":"P","href":null,"layout":null,"metadata":null,"text":"I propose to continue our tour with the version built with the Koin dependency injection framework. This is a good time to refresh practices, from standard components structure to more advanced cases.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":40,"end":47,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":48,"end":98,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_4":{"__typename":"Paragraph","id":"5a101a705abe_4","name":"cbb5","type":"P","href":null,"layout":null,"metadata":null,"text":"For this article, I propose now to use Koin Annotations instead of Koin DSL to configure all the app’s components injection. This is interesting to see how much it can improve the experience in terms of writing.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":18,"end":125,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_5":{"__typename":"Paragraph","id":"5a101a705abe_5","name":"0c3d","type":"P","href":null,"layout":null,"metadata":null,"text":"Prepare yourself, we have many things to see together 👍 🚀","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_6":{"__typename":"Paragraph","id":"5a101a705abe_6","name":"8973","type":"BQ","href":null,"layout":null,"metadata":null,"text":"This version uses Koin Annotations 1.2","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_7":{"__typename":"Paragraph","id":"5a101a705abe_7","name":"46e2","type":"P","href":null,"layout":null,"metadata":null,"text":"This article series covers several parts:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_8":{"__typename":"Paragraph","id":"5a101a705abe_8","name":"940d","type":"P","href":null,"layout":null,"metadata":null,"text":"Part 1 — Koin setup, application verification, and a first module tour","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":0,"end":70,"href":"https:\u002F\u002Fproandroiddev.com\u002Fnow-in-android-with-koin-part-1-2b871d8549f1","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_9":{"__typename":"Paragraph","id":"5a101a705abe_9","name":"2a90","type":"P","href":null,"layout":null,"metadata":null,"text":"Part 2 — Common Modules components and feature modules","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":0,"end":54,"href":"https:\u002F\u002Fproandroiddev.com\u002Fnow-in-android-with-koin-part-2-49158741cb92#1936-6cf6d648e2ac-reply","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_10":{"__typename":"Paragraph","id":"5a101a705abe_10","name":"bb38","type":"P","href":null,"layout":null,"metadata":null,"text":"Part 3 — Get started with Koin Annotations","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":0,"end":42,"href":"https:\u002F\u002Fproandroiddev.com\u002Fnow-in-android-with-koin-part-3-2801ffeed4d6","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_11":{"__typename":"Paragraph","id":"5a101a705abe_11","name":"0f58","type":"P","href":null,"layout":null,"metadata":null,"text":"Part 4 — Core & Features Components with Koin Annotations","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":0,"end":57,"href":"https:\u002F\u002Fproandroiddev.com\u002Fnow-in-android-with-koin-part-4-fbdc855824ad","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":0,"end":57,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_12":{"__typename":"Paragraph","id":"5a101a705abe_12","name":"eea4","type":"P","href":null,"layout":null,"metadata":null,"text":"… more to come :)","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:0*SgUInfHiU6tfX3-c.png":{"__typename":"ImageMetadata","id":"0*SgUInfHiU6tfX3-c.png","originalHeight":393,"originalWidth":700,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:5a101a705abe_13":{"__typename":"Paragraph","id":"5a101a705abe_13","name":"c09a","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:0*SgUInfHiU6tfX3-c.png"},"text":"","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_14":{"__typename":"Paragraph","id":"5a101a705abe_14","name":"5aa3","type":"P","href":null,"layout":null,"metadata":null,"text":"Features picture from https:\u002F\u002Fgithub.com\u002Fandroid\u002Fnowinandroid","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":22,"end":61,"href":"https:\u002F\u002Fgithub.com\u002Fandroid\u002Fnowinandroid","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_15":{"__typename":"Paragraph","id":"5a101a705abe_15","name":"766e","type":"P","href":null,"layout":null,"metadata":null,"text":"Previously in part 3, we saw how to setup and use Koin annotations with Koin dependency injection framework. It’s really easy as the Koin annotation processor can detect many cases, and generate your dependency injection configuration really quickly. It’s now time to dive into more components of the NowInAndroid project.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_16":{"__typename":"Paragraph","id":"5a101a705abe_16","name":"019b","type":"P","href":null,"layout":null,"metadata":null,"text":"You will have the reference for all the content to browse the code. Also, everything is available online on the Github repo: https:\u002F\u002Fgithub.com\u002FInsertKoinIO\u002Fnowinandroid\u002F","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":125,"end":170,"href":"https:\u002F\u002Fgithub.com\u002FInsertKoinIO\u002Fnowinandroid\u002Ftree\u002Frefacto_koin\u002Fannotations","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_17":{"__typename":"Paragraph","id":"5a101a705abe_17","name":"1b53","type":"H3","href":null,"layout":null,"metadata":null,"text":"Common Data Layers","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_18":{"__typename":"Paragraph","id":"5a101a705abe_18","name":"7fed","type":"P","href":null,"layout":null,"metadata":null,"text":"Following the part 2 article, we will now go through the common core components that will be used by the features later. But this time, the configuration will be done with annotations.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":14,"end":28,"href":"https:\u002F\u002Fproandroiddev.com\u002Fnow-in-android-with-koin-part-2-49158741cb92#1936-6cf6d648e2ac-reply","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_19":{"__typename":"Paragraph","id":"5a101a705abe_19","name":"c7a5","type":"P","href":null,"layout":null,"metadata":null,"text":"As a reminder, the Nia app is developed using Jetpack Compose and uses repository & use-case components:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_20":{"__typename":"Paragraph","id":"5a101a705abe_20","name":"1ace","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Repository to access data (network, database …)","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_21":{"__typename":"Paragraph","id":"5a101a705abe_21","name":"55d5","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Usecase to handle business logic","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_22":{"__typename":"Paragraph","id":"5a101a705abe_22","name":"9c6e","type":"P","href":null,"layout":null,"metadata":null,"text":"The module that is gathering all those common components is theDataKoinModule.kt module:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":63,"end":80,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":63,"end":80,"href":"https:\u002F\u002Fgithub.com\u002FInsertKoinIO\u002Fnowinandroid\u002Fblob\u002Frefacto_koin\u002Fannotations\u002Fcore\u002Fdata\u002Fsrc\u002Fmain\u002Fjava\u002Fcom\u002Fgoogle\u002Fsamples\u002Fapps\u002Fnowinandroid\u002Fcore\u002Fdata\u002Fdi\u002FDataKoinModule.kt#L48","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_23":{"__typename":"Paragraph","id":"5a101a705abe_23","name":"155b","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@Module(includes = [DaosKoinModule::class, DataStoreKoinModule::class, NetworkKoinModule::class, DispatchersKoinModule::class, DataUtilModule::class])\n@ComponentScan(\"com.google.samples.apps.nowinandroid.core.data.repository\")\nclass DataKoinModule","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"EXPLICIT","lang":"kotlin"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_24":{"__typename":"Paragraph","id":"5a101a705abe_24","name":"d29d","type":"P","href":null,"layout":null,"metadata":null,"text":"This module is making several things:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_25":{"__typename":"Paragraph","id":"5a101a705abe_25","name":"2810","type":"ULI","href":null,"layout":null,"metadata":null,"text":"scans all repository classes defined in @ComponentScan","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":40,"end":54,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_26":{"__typename":"Paragraph","id":"5a101a705abe_26","name":"90f6","type":"ULI","href":null,"layout":null,"metadata":null,"text":"includes modules that are declaring sub-data layers components","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_27":{"__typename":"Paragraph","id":"5a101a705abe_27","name":"5c9d","type":"P","href":null,"layout":null,"metadata":null,"text":"Each repository class is simply tagged with @Single annotation like this:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":44,"end":51,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_28":{"__typename":"Paragraph","id":"5a101a705abe_28","name":"219a","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@Single\nclass OfflineFirstAuthorsRepository(\n private val authorDao: AuthorDao,\n private val network: NiaNetworkDataSource,\n)","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"kotlin"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_29":{"__typename":"Paragraph","id":"5a101a705abe_29","name":"45d5","type":"P","href":null,"layout":null,"metadata":null,"text":"You can find all the repository classes in the source code data package.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":43,"end":71,"href":"https:\u002F\u002Fgithub.com\u002FInsertKoinIO\u002Fnowinandroid\u002Ftree\u002Frefacto_koin\u002Fannotations\u002Fcore\u002Fdata\u002Fsrc\u002Fmain\u002Fjava\u002Fcom\u002Fgoogle\u002Fsamples\u002Fapps\u002Fnowinandroid\u002Fcore\u002Fdata\u002Frepository","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_30":{"__typename":"Paragraph","id":"5a101a705abe_30","name":"b470","type":"H3","href":null,"layout":null,"metadata":null,"text":"Database Storage","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_31":{"__typename":"Paragraph","id":"5a101a705abe_31","name":"e15b","type":"P","href":null,"layout":null,"metadata":null,"text":"For the database storage layer, we need to declare our Room database instance via a function using the Room API builder like this:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_32":{"__typename":"Paragraph","id":"5a101a705abe_32","name":"8846","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@Module\nclass DatabaseKoinModule {\n\n @Single\n fun database(context: Context) =\n Room.databaseBuilder(context, NiaDatabase::class.java, \"nia-database\")\n .build()\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"kotlin"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_33":{"__typename":"Paragraph","id":"5a101a705abe_33","name":"28db","type":"P","href":null,"layout":null,"metadata":null,"text":"The context parameter here is the Android Context instance from Koin.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":4,"end":11,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_34":{"__typename":"Paragraph","id":"5a101a705abe_34","name":"a368","type":"P","href":null,"layout":null,"metadata":null,"text":"In a second module, we can reuse our NiaDatabase instance below in DAOs:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":37,"end":48,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_35":{"__typename":"Paragraph","id":"5a101a705abe_35","name":"7424","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@Module(includes = [DatabaseKoinModule::class])\nclass DaosKoinModule {\n\n @Single\n fun authorDao(niaDatabase: NiaDatabase) = niaDatabase.authorDao()\n\n @Single\n fun topicDao(niaDatabase: NiaDatabase) = niaDatabase.topicDao()\n\n @Single\n fun newsResourcesDao(niaDatabase: NiaDatabase) = niaDatabase.newsResourceDao()\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"EXPLICIT","lang":"kotlin"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_36":{"__typename":"Paragraph","id":"5a101a705abe_36","name":"ba81","type":"P","href":null,"layout":null,"metadata":null,"text":"That’s it! Our Database Layer is ready to be injected.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_37":{"__typename":"Paragraph","id":"5a101a705abe_37","name":"616d","type":"H3","href":null,"layout":null,"metadata":null,"text":"Datasource Components — Datastore & Networking","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_38":{"__typename":"Paragraph","id":"5a101a705abe_38","name":"b769","type":"P","href":null,"layout":null,"metadata":null,"text":"This layer defines Datasources which are components that abstract the calls to different sources of data. E.g: remote web service, local data storage, and so on. Therefore, the UI doesn’t need to know where the data comes from. It just calls the interface defined here.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_39":{"__typename":"Paragraph","id":"5a101a705abe_39","name":"158d","type":"P","href":null,"layout":null,"metadata":null,"text":"We are defining severasl kind of usages with NiaNetworkDatasource:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":45,"end":65,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_40":{"__typename":"Paragraph","id":"5a101a705abe_40","name":"5d0c","type":"PRE","href":null,"layout":null,"metadata":null,"text":"interface NiaNetworkDataSource {\n suspend fun getTopics(ids: List\u003CString\u003E? = null): List\u003CNetworkTopic\u003E\n\n suspend fun getAuthors(ids: List\u003CString\u003E? = null): List\u003CNetworkAuthor\u003E\n\n suspend fun getNewsResources(ids: List\u003CString\u003E? = null): List\u003CNetworkNewsResource\u003E\n\n suspend fun getTopicChangeList(after: Int? = null): List\u003CNetworkChangeList\u003E\n\n suspend fun getAuthorChangeList(after: Int? = null): List\u003CNetworkChangeList\u003E\n\n suspend fun getNewsResourceChangeList(after: Int? = null): List\u003CNetworkChangeList\u003E\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"kotlin"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_41":{"__typename":"Paragraph","id":"5a101a705abe_41","name":"085b","type":"P","href":null,"layout":null,"metadata":null,"text":"First, we need to declare a default Coroutine dispatcher directly in a module:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_42":{"__typename":"Paragraph","id":"5a101a705abe_42","name":"23d3","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@Module\nclass DispatchersKoinModule{\n \n @Single\n fun dispatcher() = Dispatchers.IO\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"kotlin"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_43":{"__typename":"Paragraph","id":"5a101a705abe_43","name":"7c43","type":"BQ","href":null,"layout":null,"metadata":null,"text":"In a test environment, you simply have to redefine a CoroutineDispatcher type to specify your needed one. Just add the new definition and it will override the existing one.","hasDropCap":true,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":53,"end":72,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_44":{"__typename":"Paragraph","id":"5a101a705abe_44","name":"71a4","type":"P","href":null,"layout":null,"metadata":null,"text":"The network module is declaring NiaNetworkDatasource, and is organized into 2 flavors:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":32,"end":52,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":4,"end":18,"href":"https:\u002F\u002Fgithub.com\u002FInsertKoinIO\u002Fnowinandroid\u002Ftree\u002Frefacto_koin\u002Fannotations\u002Fcore\u002Fnetwork\u002Fsrc","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_45":{"__typename":"Paragraph","id":"5a101a705abe_45","name":"a6b8","type":"ULI","href":null,"layout":null,"metadata":null,"text":"demo — with local data","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_46":{"__typename":"Paragraph","id":"5a101a705abe_46","name":"9b7f","type":"ULI","href":null,"layout":null,"metadata":null,"text":"prod — for online data","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_47":{"__typename":"Paragraph","id":"5a101a705abe_47","name":"03b4","type":"P","href":null,"layout":null,"metadata":null,"text":"The NetworkKoinModule includes the right flavour implementation:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":4,"end":21,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_48":{"__typename":"Paragraph","id":"5a101a705abe_48","name":"28d4","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@Module(includes = [FlavoredNetworkKoinModule::class])\nclass NetworkKoinModule {\n\n @Single\n fun json() = Json { ignoreUnknownKeys = true }\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"kotlin"},"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*ZV6ZXgkeUT3JSQqFfOYLxw.png":{"__typename":"ImageMetadata","id":"1*ZV6ZXgkeUT3JSQqFfOYLxw.png","originalHeight":482,"originalWidth":820,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:5a101a705abe_49":{"__typename":"Paragraph","id":"5a101a705abe_49","name":"3396","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*ZV6ZXgkeUT3JSQqFfOYLxw.png"},"text":"Demo flavor in Network module","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_50":{"__typename":"Paragraph","id":"5a101a705abe_50","name":"5b74","type":"P","href":null,"layout":null,"metadata":null,"text":"The demo flavour uses Datastore API and Protobuff API is used to store local data to display as an offline-first architecture.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_51":{"__typename":"Paragraph","id":"5a101a705abe_51","name":"99da","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@Module(includes = [DispatchersKoinModule::class])\n@ComponentScan(\"com.google.samples.apps.nowinandroid.core.network.fake\")\nclass FlavoredNetworkKoinModule{\n\n @Single\n fun assetManager(context: Context) = FakeAssetManager(context.assets::open)\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"less"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_52":{"__typename":"Paragraph","id":"5a101a705abe_52","name":"2771","type":"P","href":null,"layout":null,"metadata":null,"text":"Below is the demo datasource implementation declared as a singleton:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_53":{"__typename":"Paragraph","id":"5a101a705abe_53","name":"2466","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@Single\nclass FakeNiaNetworkDataSource(\n private val ioDispatcher: CoroutineDispatcher,\n private val networkJson: Json,\n private val assets: FakeAssetManager = JvmUnitTestFakeAssetManager,\n) : NiaNetworkDataSource","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"kotlin"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_54":{"__typename":"Paragraph","id":"5a101a705abe_54","name":"10bf","type":"P","href":null,"layout":null,"metadata":null,"text":"The online version is declared with the following module:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_55":{"__typename":"Paragraph","id":"5a101a705abe_55","name":"5e8d","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@Module(includes = [DispatchersKoinModule::class])\n@ComponentScan(\"com.google.samples.apps.nowinandroid.core.network.retrofit\")\nclass FlavoredNetworkKoinModule","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"less"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_56":{"__typename":"Paragraph","id":"5a101a705abe_56","name":"1f33","type":"P","href":null,"layout":null,"metadata":null,"text":"This module will scan the Retrofit implementation:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_57":{"__typename":"Paragraph","id":"5a101a705abe_57","name":"bea2","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@Single\nclass RetrofitNiaNetwork(\n networkJson: Json\n) : NiaNetworkDataSource","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"kotlin"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_58":{"__typename":"Paragraph","id":"5a101a705abe_58","name":"e54d","type":"P","href":null,"layout":null,"metadata":null,"text":"One last part is about Datastore persistence API, used to declare local data storage. Check the Datastore Persistence Module that is declaring the required components for NiaPreferencesDatasource.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":171,"end":195,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":96,"end":124,"href":"https:\u002F\u002Fgithub.com\u002FInsertKoinIO\u002Fnowinandroid\u002Fblob\u002Frefacto_koin\u002Fannotations\u002Fcore\u002Fdata\u002Fsrc\u002Fmain\u002Fjava\u002Fcom\u002Fgoogle\u002Fsamples\u002Fapps\u002Fnowinandroid\u002Fcore\u002Fdata\u002Fdi\u002FDataStoreKoinModule.kt","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_59":{"__typename":"Paragraph","id":"5a101a705abe_59","name":"d3b3","type":"H3","href":null,"layout":null,"metadata":null,"text":"Domain & Features Modules","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_60":{"__typename":"Paragraph","id":"5a101a705abe_60","name":"a286","type":"P","href":null,"layout":null,"metadata":null,"text":"Before running our features, we have some use-case components using the DataKoinModule. Those use-cases components are reusable business logic components. They are defined from the DomainKoinModule:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":181,"end":197,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_61":{"__typename":"Paragraph","id":"5a101a705abe_61","name":"df3f","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@Module(includes = [DataKoinModule::class])\n@ComponentScan\nclass DomainKoinModule","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"less"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_62":{"__typename":"Paragraph","id":"5a101a705abe_62","name":"99e5","type":"P","href":null,"layout":null,"metadata":null,"text":"You can note that we don’t specify what package to scan. This means that the module will scan in the current package and sub-packages for annotated components:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*HQzVRHo6PAOtCLNZcEGKuQ.png":{"__typename":"ImageMetadata","id":"1*HQzVRHo6PAOtCLNZcEGKuQ.png","originalHeight":169,"originalWidth":433,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:5a101a705abe_63":{"__typename":"Paragraph","id":"5a101a705abe_63","name":"f491","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*HQzVRHo6PAOtCLNZcEGKuQ.png"},"text":"","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_64":{"__typename":"Paragraph","id":"5a101a705abe_64","name":"e374","type":"P","href":null,"layout":null,"metadata":null,"text":"Each usecase component is declared with @Factory annotation. This asks Koin to create a new instance each time we need it.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":40,"end":48,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_65":{"__typename":"Paragraph","id":"5a101a705abe_65","name":"8f1c","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@Factory\nclass GetFollowableTopicsStreamUseCase(\n private val topicsRepository: TopicsRepository,\n private val userDataRepository: UserDataRepository\n)","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"kotlin"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_66":{"__typename":"Paragraph","id":"5a101a705abe_66","name":"0da7","type":"BQ","href":null,"layout":null,"metadata":null,"text":"Why not a singleton instance? Because those usecase components will be used with a ViewModel, following the Android lifecycle. Making them as a singleton, we would take a risk to have references to a ViewModel that are destroyed by the application.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":83,"end":92,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":200,"end":209,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_67":{"__typename":"Paragraph","id":"5a101a705abe_67","name":"f4ca","type":"P","href":null,"layout":null,"metadata":null,"text":"Finally, we are ready to use all of this in our Feature module. Each will then include DomainKoinModule or DataKoinModule to benefit from the common components:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":87,"end":103,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":107,"end":121,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_68":{"__typename":"Paragraph","id":"5a101a705abe_68","name":"d552","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@Module(includes = [DomainKoinModule::class,StringDecoderKoinModule::class])\n@ComponentScan(\"com.google.samples.apps.nowinandroid.feature.author\")\nclass AuthorKoinModule","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"less"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_69":{"__typename":"Paragraph","id":"5a101a705abe_69","name":"6ba3","type":"P","href":null,"layout":null,"metadata":null,"text":"By scanning the right package in our module, we will be able to declare our ViewModel instances like this:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_70":{"__typename":"Paragraph","id":"5a101a705abe_70","name":"2a13","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@KoinViewModel\nclass AuthorViewModel(\n savedStateHandle: SavedStateHandle,\n stringDecoder: StringDecoder,\n private val userDataRepository: UserDataRepository,\n authorsRepository: AuthorsRepository,\n getSaveableNewsResourcesStream: GetSaveableNewsResourcesStreamUseCase\n) : ViewModel()","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"less"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_71":{"__typename":"Paragraph","id":"5a101a705abe_71","name":"846c","type":"H3","href":null,"layout":null,"metadata":null,"text":"Sync Worker — Offline data sync with WorkManager","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_72":{"__typename":"Paragraph","id":"5a101a705abe_72","name":"5217","type":"P","href":null,"layout":null,"metadata":null,"text":"Finally, we need to declare our SyncWorker components, to asynchronously prepare offline content. This consists of a module:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_73":{"__typename":"Paragraph","id":"5a101a705abe_73","name":"58fc","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@Module\n@ComponentScan\nclass SyncWorkerKoinModule","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"EXPLICIT","lang":"kotlin"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_74":{"__typename":"Paragraph","id":"5a101a705abe_74","name":"aa04","type":"P","href":null,"layout":null,"metadata":null,"text":"The following definitions will be scanned by the module.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_75":{"__typename":"Paragraph","id":"5a101a705abe_75","name":"e140","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@Single\nclass WorkManagerSyncStatusMonitor(\n context: Context\n) : SyncStatusMonitor","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"kotlin"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_76":{"__typename":"Paragraph","id":"5a101a705abe_76","name":"dafd","type":"P","href":null,"layout":null,"metadata":null,"text":"And the SyncWorker component declared with @KoinWorker annotation. This will generate the equivalent of worker { } DSL:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":8,"end":18,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":43,"end":54,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":104,"end":114,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_77":{"__typename":"Paragraph","id":"5a101a705abe_77","name":"695a","type":"PRE","href":null,"layout":null,"metadata":null,"text":"@KoinWorker\nclass SyncWorker (\n private val appContext: Context,\n workerParams: WorkerParameters,\n private val niaPreferences: NiaPreferencesDataSource,\n private val topicRepository: TopicsRepository,\n private val newsRepository: NewsRepository,\n private val authorsRepository: AuthorsRepository,\n private val ioDispatcher: CoroutineDispatcher,\n) : CoroutineWorker(appContext, workerParams), Synchronizer","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"kotlin"},"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_78":{"__typename":"Paragraph","id":"5a101a705abe_78","name":"13be","type":"P","href":null,"layout":null,"metadata":null,"text":"SyncWorker will be declared with Workmanager Koin factory. This one has to be activated at the start like this:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":0,"end":10,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*7TDkzXW4mtotwat50QSQ8A.png":{"__typename":"ImageMetadata","id":"1*7TDkzXW4mtotwat50QSQ8A.png","originalHeight":308,"originalWidth":1140,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:5a101a705abe_79":{"__typename":"Paragraph","id":"5a101a705abe_79","name":"d2f2","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*7TDkzXW4mtotwat50QSQ8A.png"},"text":"Koin start in NiaApplication class","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_80":{"__typename":"Paragraph","id":"5a101a705abe_80","name":"415f","type":"H3","href":null,"layout":null,"metadata":null,"text":"Koin Annotations — Cheat Sheet","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_81":{"__typename":"Paragraph","id":"5a101a705abe_81","name":"bf1a","type":"P","href":null,"layout":null,"metadata":null,"text":"Hope you enjoyed the walkthrough NowInAndroid application with Koin dependency injection and annotations. You will find below the last cheat sheet we’ve made.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:5a101a705abe_82":{"__typename":"Paragraph","id":"5a101a705abe_82","name":"af95","type":"MIXTAPE_EMBED","href":null,"layout":null,"metadata":null,"text":"Koin 3.2 & Koin Annotations 1.0 — Cheat Sheets\nHello Folks 👋 While we are at several conferences to show Architecture Design with Koin, Kotzilla is also offering…blog.kotzilla.io","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":0,"end":179,"href":"https:\u002F\u002Fblog.kotzilla.io\u002Fkoin-3-2-annotations-cheat-sheets\u002F","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":0,"end":46,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"EM","start":47,"end":163,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":{"__typename":"MixtapeMetadata","href":"https:\u002F\u002Fblog.kotzilla.io\u002Fkoin-3-2-annotations-cheat-sheets\u002F","mediaResource":{"__typename":"MediaResource","mediumCatalog":null},"thumbnailImageId":"0*35z9MDbjpVM-dVAH"}},"CollectionViewerEdge:collectionId:c72404660798-viewerId:lo_788b5fc96ef9":{"__typename":"CollectionViewerEdge","id":"collectionId:c72404660798-viewerId:lo_788b5fc96ef9","isEditor":false,"isMuting":false},"ImageMetadata:":{"__typename":"ImageMetadata","id":"","originalWidth":0,"originalHeight":0},"PostViewerEdge:postId:fbdc855824ad-viewerId:lo_788b5fc96ef9":{"__typename":"PostViewerEdge","shouldIndexPostForExternalSearch":true,"id":"postId:fbdc855824ad-viewerId:lo_788b5fc96ef9"},"Tag:android":{"__typename":"Tag","id":"android","displayTitle":"Android","normalizedTagSlug":"android"},"Tag:kotlin":{"__typename":"Tag","id":"kotlin","displayTitle":"Kotlin","normalizedTagSlug":"kotlin"},"Tag:dependency-injection":{"__typename":"Tag","id":"dependency-injection","displayTitle":"Dependency Injection","normalizedTagSlug":"dependency-injection"},"Tag:koin":{"__typename":"Tag","id":"koin","displayTitle":"Koin","normalizedTagSlug":"koin"},"Tag:annotations":{"__typename":"Tag","id":"annotations","displayTitle":"Annotations","normalizedTagSlug":"annotations"},"Post:fbdc855824ad":{"__typename":"Post","id":"fbdc855824ad","collection":{"__ref":"Collection:c72404660798"},"content({\"postMeteringOptions\":{}})":{"__typename":"PostContent","isLockedPreviewOnly":false,"bodyModel":{"__typename":"RichText","sections":[{"__typename":"Section","name":"97c9","startIndex":0,"textLayout":null,"imageLayout":null,"backgroundImage":null,"videoLayout":null,"backgroundVideo":null},{"__typename":"Section","name":"cee7","startIndex":7,"textLayout":null,"imageLayout":null,"backgroundImage":null,"videoLayout":null,"backgroundVideo":null},{"__typename":"Section","name":"46e5","startIndex":15,"textLayout":null,"imageLayout":null,"backgroundImage":null,"videoLayout":null,"backgroundVideo":null},{"__typename":"Section","name":"685c","startIndex":80,"textLayout":null,"imageLayout":null,"backgroundImage":null,"videoLayout":null,"backgroundVideo":null}],"paragraphs":[{"__ref":"Paragraph:5a101a705abe_0"},{"__ref":"Paragraph:5a101a705abe_1"},{"__ref":"Paragraph:5a101a705abe_2"},{"__ref":"Paragraph:5a101a705abe_3"},{"__ref":"Paragraph:5a101a705abe_4"},{"__ref":"Paragraph:5a101a705abe_5"},{"__ref":"Paragraph:5a101a705abe_6"},{"__ref":"Paragraph:5a101a705abe_7"},{"__ref":"Paragraph:5a101a705abe_8"},{"__ref":"Paragraph:5a101a705abe_9"},{"__ref":"Paragraph:5a101a705abe_10"},{"__ref":"Paragraph:5a101a705abe_11"},{"__ref":"Paragraph:5a101a705abe_12"},{"__ref":"Paragraph:5a101a705abe_13"},{"__ref":"Paragraph:5a101a705abe_14"},{"__ref":"Paragraph:5a101a705abe_15"},{"__ref":"Paragraph:5a101a705abe_16"},{"__ref":"Paragraph:5a101a705abe_17"},{"__ref":"Paragraph:5a101a705abe_18"},{"__ref":"Paragraph:5a101a705abe_19"},{"__ref":"Paragraph:5a101a705abe_20"},{"__ref":"Paragraph:5a101a705abe_21"},{"__ref":"Paragraph:5a101a705abe_22"},{"__ref":"Paragraph:5a101a705abe_23"},{"__ref":"Paragraph:5a101a705abe_24"},{"__ref":"Paragraph:5a101a705abe_25"},{"__ref":"Paragraph:5a101a705abe_26"},{"__ref":"Paragraph:5a101a705abe_27"},{"__ref":"Paragraph:5a101a705abe_28"},{"__ref":"Paragraph:5a101a705abe_29"},{"__ref":"Paragraph:5a101a705abe_30"},{"__ref":"Paragraph:5a101a705abe_31"},{"__ref":"Paragraph:5a101a705abe_32"},{"__ref":"Paragraph:5a101a705abe_33"},{"__ref":"Paragraph:5a101a705abe_34"},{"__ref":"Paragraph:5a101a705abe_35"},{"__ref":"Paragraph:5a101a705abe_36"},{"__ref":"Paragraph:5a101a705abe_37"},{"__ref":"Paragraph:5a101a705abe_38"},{"__ref":"Paragraph:5a101a705abe_39"},{"__ref":"Paragraph:5a101a705abe_40"},{"__ref":"Paragraph:5a101a705abe_41"},{"__ref":"Paragraph:5a101a705abe_42"},{"__ref":"Paragraph:5a101a705abe_43"},{"__ref":"Paragraph:5a101a705abe_44"},{"__ref":"Paragraph:5a101a705abe_45"},{"__ref":"Paragraph:5a101a705abe_46"},{"__ref":"Paragraph:5a101a705abe_47"},{"__ref":"Paragraph:5a101a705abe_48"},{"__ref":"Paragraph:5a101a705abe_49"},{"__ref":"Paragraph:5a101a705abe_50"},{"__ref":"Paragraph:5a101a705abe_51"},{"__ref":"Paragraph:5a101a705abe_52"},{"__ref":"Paragraph:5a101a705abe_53"},{"__ref":"Paragraph:5a101a705abe_54"},{"__ref":"Paragraph:5a101a705abe_55"},{"__ref":"Paragraph:5a101a705abe_56"},{"__ref":"Paragraph:5a101a705abe_57"},{"__ref":"Paragraph:5a101a705abe_58"},{"__ref":"Paragraph:5a101a705abe_59"},{"__ref":"Paragraph:5a101a705abe_60"},{"__ref":"Paragraph:5a101a705abe_61"},{"__ref":"Paragraph:5a101a705abe_62"},{"__ref":"Paragraph:5a101a705abe_63"},{"__ref":"Paragraph:5a101a705abe_64"},{"__ref":"Paragraph:5a101a705abe_65"},{"__ref":"Paragraph:5a101a705abe_66"},{"__ref":"Paragraph:5a101a705abe_67"},{"__ref":"Paragraph:5a101a705abe_68"},{"__ref":"Paragraph:5a101a705abe_69"},{"__ref":"Paragraph:5a101a705abe_70"},{"__ref":"Paragraph:5a101a705abe_71"},{"__ref":"Paragraph:5a101a705abe_72"},{"__ref":"Paragraph:5a101a705abe_73"},{"__ref":"Paragraph:5a101a705abe_74"},{"__ref":"Paragraph:5a101a705abe_75"},{"__ref":"Paragraph:5a101a705abe_76"},{"__ref":"Paragraph:5a101a705abe_77"},{"__ref":"Paragraph:5a101a705abe_78"},{"__ref":"Paragraph:5a101a705abe_79"},{"__ref":"Paragraph:5a101a705abe_80"},{"__ref":"Paragraph:5a101a705abe_81"},{"__ref":"Paragraph:5a101a705abe_82"}]},"validatedShareKey":"","shareKeyCreator":null},"creator":{"__ref":"User:9ad99ca649d4"},"inResponseToEntityType":null,"isLocked":false,"isMarkedPaywallOnly":false,"lockedSource":"LOCKED_POST_SOURCE_NONE","mediumUrl":"https:\u002F\u002Fproandroiddev.com\u002Fnow-in-android-with-koin-part-4-fbdc855824ad","primaryTopic":null,"topics":[{"__typename":"Topic","slug":"android-development"}],"isPublished":true,"latestPublishedVersion":"5a101a705abe","visibility":"PUBLIC","postResponses":{"__typename":"PostResponses","count":1},"clapCount":31,"allowResponses":true,"isLimitedState":false,"title":"Now In Android with Koin — part 4","isSeries":false,"sequence":null,"uniqueSlug":"now-in-android-with-koin-part-4-fbdc855824ad","socialTitle":"","socialDek":"","canonicalUrl":"","metaDescription":"","latestPublishedAt":1681744610767,"readingTime":5.357861635220125,"previewContent":{"__typename":"PreviewContent","subtitle":"Let’s use Koin Annotations instead of Koin DSL to configure DI injection in Google’s NowInAndroid app"},"previewImage":{"__ref":"ImageMetadata:1*hVKWuT24riZnx4VzDpQVJQ.png"},"isShortform":false,"seoTitle":"","firstPublishedAt":1680618126934,"updatedAt":1681744610767,"shortformType":"SHORTFORM_TYPE_LINK","seoDescription":"","viewerEdge":{"__ref":"PostViewerEdge:postId:fbdc855824ad-viewerId:lo_788b5fc96ef9"},"isSuspended":false,"license":"ALL_RIGHTS_RESERVED","tags":[{"__ref":"Tag:android"},{"__ref":"Tag:kotlin"},{"__ref":"Tag:dependency-injection"},{"__ref":"Tag:koin"},{"__ref":"Tag:annotations"}],"isNewsletter":false,"statusForCollection":"APPROVED","pendingCollection":null,"detectedLanguage":"en","wordCount":1199,"layerCake":0,"responsesLocked":false}}</script><script src="https://cdn-client.medium.com/lite/static/js/manifest.bbe4ab66.js"></script><script src="https://cdn-client.medium.com/lite/static/js/9865.1496d74a.js"></script><script src="https://cdn-client.medium.com/lite/static/js/main.bbe47cad.js"></script><script src="https://cdn-client.medium.com/lite/static/js/instrumentation.d9108df7.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/reporting.ff22a7a5.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/9120.5df29668.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5049.d1ead72d.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/4810.6318add7.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6618.db187378.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2707.b0942613.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/9977.5b3eb23a.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8599.1ab63137.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5250.9f9e01d2.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5787.e66a3a4d.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2648.26563adf.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8393.826a25fb.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7549.2176f21f.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6589.7c500280.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/3735.afb7e926.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5642.0a97706a.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6546.cd03f950.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6834.08de95de.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7346.72622eb9.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2420.2a5e2d95.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/839.ca7937c2.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7975.d195c6f1.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7394.bf599bc5.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2961.00a48598.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8204.c4082863.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/4391.59acaed3.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/PostPage.MainContent.902ad94b.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8414.6565ad5f.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/3974.8d3e0217.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2527.a0afad8a.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/PostResponsesContent.36c2ecf4.chunk.js"></script><script>window.main();</script></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10