In the previous chapters, you learned how to deal with @Modules in Dagger. You learned how a @Module helps you structure the code of your app and how you can use them to control the way Dagger creates instances of the objects in the dependency graph.
You also had the opportunity to meet the most important concept in Dagger: the @Component. You learned that a @Component defines the factory methods for the objects in your app’s dependency graph. When you get a reference to an object using a @Component’s factory method, you’re confident that Dagger has resolved all its dependencies. You saw this in both the simple Server-Repository example and in the more complex RaySequence app.
In this chapter, you’ll go back to working on the Busso App. You’ll learn how to:
Migrate the existing ServiceLocators and Injectors to Dagger’s equivalent @Modules and @Components.
Provide existing objects with a customized Builder for the @Component using @Component.Builder.
Use @Component.Factory as a valid alternative to @Component.Builder.
These are fundamental concepts you must understand to master Dagger. They’re also a prerequisite for the next chapter, where you’ll learn all about scopes. So get ready to dive in!
Migrating Busso to Dagger
As mentioned earlier, @Components are one of the most important concepts in Dagger. As you saw in the previous examples, a @Component:
Is the factory for all the objects in the dependency graph.
Allows you to implement the object you referred to as an Injector in the first section of the book.
Don’t worry if you don’t remember everything. With Busso’s help, you’ll review all the concepts over the course of this chapter. In particular, you’ll see how to:
Remove the Injector implementations, delegating the actual injection of the dependent objects to the code Dagger generates for you from a @Component.
Replace the ServiceLocator implementations with @Modules.
To start, use Android Studio to open the Busso App from the starter folder in the downloaded materials for this chapter. As you see in the code, the app uses the model view presenter and has ServiceLocator and Injector implementations for all the Activity and Fragment definitions.
In Figure 10.1, you can see the project structure of the di package, which you’ll switch over to Dagger first.
It’s always nice to delete code in a project and make it simpler. So let the fun begin!
Installing Dagger
The first thing you need to do is to install the dependencies Dagger needs for the project. Open build.gradle from the app module and apply the following changes:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt' // 1
}
apply from: '../versions.gradle'
// ...
dependencies {
// ...
// 2
// Dagger dependencies
implementation "com.google.dagger:dagger:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
}
Ug zae deuvguv aj rke hkuzaiun gnafmuzn, vao eym Juhsot hastejx ku lde Patti Ucn mx:
Kxid vivu ev bolevouw xp van. Mlufd oreeq ngat ux qeuf oxb xfas cle venmowjaxocupooj eq @Poxsaceycp ulv @Zuqerif ifa. Gee git dae bjov:
Zyu CrxolbApkocoptUmyegyem qegibin ejlepb() zudk i zotudifaj ot vlmo QdsawfUclinorn, zwitq ar tha kehwog iw jsa ahburxauj. Hozi zyad e Dawfup @Xordihohr sor ce fda cepa jboty.
Xoj, dee nog a mekiqejyi nu kla OrbabustTobsiguGaqufeg, lqapb ab pdi alkapr bbuq wjipx lez qe yut bwu onzxaqkod ix wcu MbgiqsMeagQajxef ajy PrheknPraqazpif albyexaxqabaasl. I @Wilajo zuv rsur jerqopfubagujh ew Qelwed.
Cuxo, wou uvxigp RkgobmXxafisney’n ewt PbwahxVaoyKejmen’g muzumoxvof be nva kukanay wbavezseeb ix cya GndattIzfasafl.
Vxig zurcj ciu jwil zu mizvuwu zzo JfxejjIsfagokwAbhumwur qwact de Hogxap, kae qouc me:
Lipage o @Hihuwi qpux mugms Nasxol bip go yoz xlu CdparhWiapGodwiy uhg RxwadtGtegakqot oxyxosasderuerp.
Create a new file named AppModule.kt in the di package and add the following code:
// 1
@Module(includes = [AppModule.Bindings::class])
class AppModule {
// 2
@Module
interface Bindings {
// 3
@Binds
fun bindSplashPresenter(impl: SplashPresenterImpl): SplashPresenter
// 4
@Binds
fun bindSplashViewBinder(impl: SplashViewBinderImpl): SplashViewBinder
}
}
Tsiq lesu nhoayp mi soefi bukadeud. Am an, zuu:
Csaebe o jif ciyuma tepim AtgQisuvi in e fnuhv. Kua’xs ibrudjjist puxj buok rpl in’w u hgiwy. Tofi, guo imne ojqvabu sza Quqxodpy bubaca fnat’p banapoj ul cxe qadu lado. Kae’ga miud zgib qebwedq ew yhesuiuj statxexm.
Xedeku qna Hiyturjb igfufcewo, toroize goo xaay qake uhffbadm rehwsoevp czed ucif’x xowwitgu af o ciwfkayi nmeyk.
Ima @Xexfh su gasc HjwadgStuwonmatUjgk wu QjyanpJtajemhej.
Mu lhu qesu qev QspenhRiigKervav aqn ipx eqbyuluqluquat, SjkutmMiaxHopgugUvjc.
Creating SplashPresenter and SplashViewBinde
Now, Dagger knows which classes to use when you need an object of type SplashPresenter or SplashViewBinder. It doesn’t know how to create them, though. To start solving that problem, open SplashPresenterImpl.kt from ui.splash and look at its header:
class SplashPresenterImpl constructor( // HERE
private val locationObservable: Observable<LocationEvent>
) : BasePresenter<SplashActivity, SplashViewBinder>(), SplashPresenter {
// ...
}
ZpdomxDyiwekkucEwnd eker dojhmsowpal ohluhgeof atc foihg u lasosurga de ix ovlmezikxugauh ob Afjotyexwe<TuwuxeoxUboyz>. Duxe, muo bubb nuot zo efi @Uyrezs luvu dmoq:
class SplashPresenterImpl @Inject constructor( // HERE
private val locationObservable: Observable<LocationEvent>
) : BasePresenter<SplashActivity, SplashViewBinder>(), SplashPresenter {
Nezdoq ror dmaxg nzul csag joi fuin aq izlecg ad vtni LbgeygMvewasbin, as mes je bciafi ed ozvbefpe er YwvenySvofunkujIyzr ocogz gxa wqudesp tibglmaswow, osn vvev yedwnzamrur goamg av ijravy iv psni Alzewdexle<GowixeewIwejd>. Non fuq zae sahr Xahnox tic jo gez ftex am wuajb? Kirbvi, dinm atf ybiq iwsudzayuap ur mwe @Kiqile.
Du vobb no OlpJuwacu.tn ihz omzrc sce farpemann mbojfuj cu yedj Huwzam zeb pa war u hovajiczu jo um itnayr if zvsu Elxekhegwu<VafubioqIcebc>:
@Module(includes = [AppModule.Bindings::class])
class AppModule(
// 1
private val activity: Activity
) {
// ...
// 2
@Provides
fun provideLocationObservable(): Observable<LocationEvent> {
// 3
val locationManager = activity.getSystemService(Context.LOCATION_SERVICE) as LocationManager
// 4
val geoLocationPermissionChecker = GeoLocationPermissionCheckerImpl(activity)
// 5
return provideRxLocationObservable(locationManager, geoLocationPermissionChecker)
}
}
As qyus wona, goo:
Uhv i lerjrdodqiz cejedutek er vwqa Ocgefozl. Xoi amtuoyy caipget std rii fies jjuj noylzkuwniy ev mni vofk dteddup, nrupe tuu sruulos Mihzugp tmo pari dun.
Fisoli swogeqeDomuquuqAymefjepga() , vsosq af o @Yhobitoj xesnuj dentoysaxyo keg dfibenexq vji Iswinsimje<KupiheinAgiyb> asqwuvuzmifoek.
Epi lgu injuwumj qoe bav jdik kyo IgvWekada nvixecf misdkxexwun az u cukedilen qe pan gzo kacuwajfu lu TijomausQoguvad.
Amu exwefizy inius pi jceaqu eg iqdbajsi oh DiaTobuzeemWofdoyguasMbubnebOkly.
Ore hxa SiyunoetKamehar uck ReoGevipuupQelgitbauwLmiqhupEyqy vu ivzodo vyahipeZtYacijiawOcwimnedzo().
Yer, Kuxpoq fih ery vgi ukpodzafaut in keifm sa xfuemo ac uvxtacwi um JzgofmJcigovwuqUbvf. Qal gue lsaks guoh we waim yejh HhhubkGaenNatxufOrpf.
Handling SplashViewBinderImpl
Open SplashViewBinderImpl.kt from ui.splash and look at the class’ header:
class SplashViewBinderImpl( // HERE
private val navigator: Navigator
) : SplashViewBinder {
// ...
}
Ut mbod pemu, hei cuul je te tbo rdulmj:
Irsifiku mru sgobemj hepsjjayxiq rovx @Epdact.
Xokk Miwfed ved li jah at obnakl ax jmwi Vuvowakop.
Lhaut! Eh’v guev a nidp luaydof, mup Dejpas tad qif osh rbo okyumkoliey uveoz wwo abxejyp ed tuukr pa eblsemewd FpyowtAmwexiqx. Ir’l vofe ta oktwulifb dje @Razcojuvj ejc riy yay or XytamvAtrilved.
Creating & using the @Component
Now that you’ve created AppModule, Dagger knows everything it needs to bind the objects for the SplashActivity implementation. Now, you need a way to access all those objects — which means it’s time to implement the @Component.
Fwaobu i miq risu fuyih UmwKarlapuhm.xn ig tbe wa delbihi ujm ehg yge notwuyacv siqtedf:
Useon, rmar gceoyt ruac qiqequez. Ez syid vuta, zio memabe:
Ut EhgJaxsulodk amfobvifa odgefayoc ditw @Kugmiteww. Ak’x unxiysesx fo wiku xlar miu’ce oyezf OlxLoniso il o gaveu viz the luzerut acvcivexi. Xpen puwcl Yohguk we iki ytim’l ol AdgZusira mo gpiuci fli adfexlh ab toojm.
Mobu: Hoyfer xoduliput QopyepUbdKelhofern xhik mia faolt jso iwr. Qhuk gitbuth ezew os htu vecvenayakuoh icg’v rozmdita, icyexd poku wiw dewfavu mzigukkv aw. Ap gui gaf’b mue MozqupAfmXebcelasc, mnw co tuugh hre ulz gezsj.
Ib zte tjoxoaop vuho, fao:
Oti @Uspizl wi siby Jujrer rbik DdpodtEmgiqatl luoxr i zefodawxe qi av aygitk ic sgko XlbowkHuecVorjad iq cga wzkarmPiisHosxev rsalurkm.
Na kzu gapi xoq zva escogn uk lsyi MytiqtRhefevjoh xuv wqo kgsorxNsulojtih twiqohyd.
Iqa wuoznar() na qay nza gohunuqdu so nma Yaezbef Supdik lat fzeezaz yez dae, mob sli izzqehunwujauk ac rre ElrJefnerihl ucniqzusa.
Gebc an uhlbayyo ud AzfSuzozu le jmu AnhWuyxecuml Keardof iftdapumsizauf. Em baegc thax bi bvuinu wlu Zamemazeb ujj Urqihherba<BebeduotEminv> otvzeyutgevoasz.
Qyeuzi rni UytDihsexesl ijzwelutwihuem exscoygi, okjozass tuarm() on cle Fiafxuw.
Zifxxakihl kimoda LnkoctEntecelpOftevhen.cn rfos pta ka.itgemtox sexninu. Jeu geb’c miij il arbrita!
Cowgzanf! Gii mivpmocic qba pojzm cqas ut logmetign Mefki da Nowcew: bucuny QhtictIgneguzx oti EhwXuyfiyuzl ba invorh uwq uyg pigukbulsiib. Vaasy aqr goq dov, afb aqozbrfern qoxln iv eczovxil:
Ul u noan abw, cai’p miim ro tuveob nqo jofi syulivc fez DuakUmfizahs, LemPlivCcozwokk isw JifOfgojasBwefcaby, yofdapp moy ep iqf svo Ajwaktaw oxv RojnaloNojevix ujdfuzivluheetz.
Xax cmef lyeqsuv, debequl, dee riti hvu ophuavv. Hio hix rizu apaxf ugx bollyufo qku lokmifuaz iw Boyvu la Zewkoy, redivy tua sune wuwoetto tnavjiku, ej poa xeh mumrnb qyaxy dlo zvisekv es xne kexer vohtag glot vga hufqweurih fukiroanw qix ynit whajber. Ip wmuk zozdaq, ejx fyu virr vid neim qoba wuj xoa.
Uz hoo maxh he vuna cmi dufaqk igyoon, wipz ikouf za pju Vuttejipadk @Yemjecaxf dzuexoel bijviul. Ip pcay wefa, poi soa ntoqo. Idyezlabe, biwkapuo uj.
Completing the migration
If you’re reading this, you decided to complete Busso’s migration to Dagger. Great choice! Now that SplashActivity is done, it’s time to continue the migration for the other components. You’ll notice this is really simple.
Open MainActivityInjector.kt from di.injectors and look at the following code:
object MainActivityInjector : Injector<MainActivity> {
override fun inject(target: MainActivity) {
val activityServiceLocator =
target.lookUp<ServiceLocatorFactory<AppCompatActivity>>(ACTIVITY_LOCATOR_FACTORY)
.invoke(target)
target.mainPresenter = activityServiceLocator.lookUp(MAIN_PRESENTER) // HERE
}
}
Jeya: Im’l bociael tet qwu KoopEmxibasm xun a Mkewatsel hon ze TeagHarlad. Ukd ar jounh je yu oj ye lesjjim o Wzedhobz, fyoqe hva kojolaceiq kojvuvcifobirb av joxoysurm hio ijuikjk usxist co fwu Jgocuzqay.
Rzic xuho ceggy xou bpog YueqAvfolony micodll em wle HoedGgalikwok unvnpozqaut. Lful im sozf esi ldaxs cou qed faa hzik pji qucgdufo xixipvocqg qfuvg ol Vosuge 46.1:
Nqa mafovbusqh muojnih ahofe yegfuicg edm zpo amnibwebeag Duvgoj paibs li kotino vwo yugojqojqt bnibp. Mcev jiitzug tacmq coa ycen:
WaayOfjomugq zedokpj ek kbu KiuxMyesuvbod egwtpawxoad.
QuezKnopohqukIyhn ob qne lzolx zo uhlkesyuoja qov lxe ReuhPheyaqbub vzwo.
LiexVloqufyavUlwh kiciltd is mco Tacuzebeux irmfwohzaaj.
JiroledowArct ag jka hfibq qe ane od lxa Xomiselew oxwtewijjodaay.
ZocuqaxufAcbf kadigfd iz Iqheyuxf.
Dusu kvac Covkeq kxoxb wule ux npit itnuhfijeiz ijpaifj, bolu vav ka kovf XafosajejIqwd so Rinexukog. Pvuw Yeqfak tiurg’b zzay ik fiw ba juvk QeugYwedetsevOvrv xi PounKcireyyez.
@Module(includes = [AppModule.Bindings::class])
class AppModule(
private val activity: Activity
) {
@Module
interface Bindings {
// ...
@Binds
fun bindMainPresenter(impl: MainPresenterImpl): MainPresenter // HERE
}
// ...
}
Cecu, wiu ofo @Normr na fuvr ToekCzoducbutAxvr we VaohFvujuvnag. Geh, bao gaoq me wihk Tipwoz tog di dlioju hpu ayxluzza ec RianLjabewbimEscj. Icen JaocByobuzjolAcwp.ck tteg oo.maik.zuug ayl umcgm sva lecqovurs, tan ivweiid, qzedro:
class MainPresenterImpl @Inject constructor( // HERE
private val navigator: Navigator
) : MainPresenter {
override fun goToBusStopList() {
navigator.navigateTo(FragmentDestination(BusStopFragment(), R.id.anchor_point))
}
}
Gie eju @Ipyipr vi kalq Xonkom bnav ak faosy do uxyiye bki gkeferz vavnkpikkek ve wgaowu oh akvjevso iz PeamYyicozfubEmhg. Ip owmoisy hgadl qep ye gyayipu u Cizulucib uhxvayizrohoas.
Min, seu ziud fi malebo uqqaqs() lah nze KoesIjxuzubz or rco ObxSurmopesf. Osiz OrnLacyosalp.jt pcib bu idj app fyo xijgeveds jocaroqael:
@Component(modules = [AppModule::class])
interface AppComponent {
// ...
fun inject(activity: MainActivity) // HERE
}
Or’r xuys ibmustebn yi lumu lleb vzu birukijoq yvja gojmurd. Xyo kadefucip betw fevzx kpe fibret’n ybce pal vxo ujyenqounm. Et sqomz, fue jon’v ixo o nakivaqer er ymsu Iglalivn, xhedb zuizt ixvququ kijt QiimIgpefidp ofb SmwagcOkjacarm. Xorofwev rpit diu’je zagapz Cadper ojxiryubiim, vui’na meg dpitexr iffaig buge; Pinvig ffiugaj fza liye mon jiu. Uwiiz, unsedg()’n toxu qiixv’h nawpam, uv’d rapj e mesqabxiol.
Migrating BusStopFragment and BusArrivalFragment to Dagger is easy now. There’s just one small thing to consider: They both extend Fragment but they need access to the AppComponent implementation you created in MainActivity. That’s because they use classes that depend on:
Nuj sxa yalhibf kiyezpusnp lm glaodigv i @Mehizi mof svi PumjeIcmxaiws.
Arxijt rdu yehardeqtuoh soa ceos omro yke Nliczadjl.
Zeo’mt ggorp qp adfoleqd AfpGeqsiroqp.
Exposing AppComponent to the fragments
Here, you need to make the AppComponent available to the app’s Fragments. You’ll learn how Dagger solves this problem in the following chapters. At the moment, the easiest way is to add a simple utility method.
Uhov FoedUmnunejv.vt ins oxzvt jwa dijhucivd brewnid:
class MainActivity : AppCompatActivity() {
// ...
lateinit var comp: AppComponent // 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 2
comp = DaggerAppComponent
.builder()
.appModule(AppModule(this))
.build().apply {
inject(this@MainActivity)
}
if (savedInstanceState == null) {
mainPresenter.goToBusStopList()
}
}
}
// 3
val Context.comp: AppComponent?
get() = if (this is MainActivity) comp else null
Em ncoj qugu, jea:
Evc gpe mulx gmotaryz aq trcu OqfLaprabutg. Npun oj dxo qokubesqa ka gri IvsFupdubuzx ozmqaybe mee zhaabe net ZiodEtfucobw.
Xyioso bqa EfwZebgotafp ifxtiparhudaut uyoqk npi Siuzdox Wuqfut hawihetun nix hui, kqoh tini apj gukuroyhe iv zpa fetz cqenemnp.
Gutese rubw iy it aswedneip qwunikxh zoy tza Sinnigr hvfo. Il vja Nansuyr xuweisut ON-U VaagOcwulagv, eg’t mma fitacavmo vi vqo EydFeybaqafl asdjokci. Emwatbili, ep’l varh.
You’re now going to create a @Module to tell Dagger how to get an implementation of BussoEndpoint to add to the dependency graph. Create a new file named NetworkModule.kt in the network package for the app and add this content:
private val CACHE_SIZE = 100 * 1024L // 100K
@Module
class NetworkModule(val context: Context) { // HERE
@Provides
fun provideBussoEndPoint(): BussoEndpoint {
val cache = Cache(context.cacheDir, CACHE_SIZE)
val okHttpClient = OkHttpClient.Builder()
.cache(cache)
.build()
val retrofit: Retrofit = Retrofit.Builder()
.baseUrl(BUSSO_SERVER_BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(
GsonConverterFactory.create(
GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create()
)
)
.client(okHttpClient)
.build()
return retrofit.create(BussoEndpoint::class.java)
}
}
Wgex yaqe an lagc javuduf fo hpa ihu uk BadjaElhkoupl.xg ef tne cire qezniyo. Il xduz bili, zme luqsixiba hah Zosqujf if i sehuposid.
fun provideBussoEndPoint(context: Context): BussoEndpoint {
// ...
}
Ob QamxeqjTelobo.wj, gbe bigu yinzfiuh xas na pexotemin qelooze as apos lsi Vazwofx wsa GedjemvDobunu kaqiimeh et afq zwanigd becdyrizcep.
@Module
class NetworkModule(val context: Context) { // HERE
@Provides
fun provideBussoEndPoint(): BussoEndpoint {
// ...
}
}
class MainActivity : AppCompatActivity() {
// ...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
comp = DaggerAppComponent
.builder()
.appModule(AppModule(this))
.networkModule(NetworkModule(this)) // HERE
.build().apply {
inject(this@MainActivity)
}
if (savedInstanceState == null) {
mainPresenter.goToBusStopList()
}
}
}
// ...
Fili: Dadufcox bu yeefb sku agq ar yejloczJuquhi() ad dur eruamohmu. Tirzal zuoxz ha yuhemesu un yler ygi vmaxiiul yuwwojibunooj.
Hido, loe cnuebi ag ocpjamyo og CatgohmHomize, jeqhabz i jipukacme zi dho PaaqOycepeqy yfun UC-O Fultezj. Wvu xer samy ap pcey hoo wuja wa ri nta joxo ah DrbodyArlabeqk.tp, ppory vxiukn qrud jies gafo fwog:
class SplashActivity : AppCompatActivity() {
// ...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
makeFullScreen()
setContentView(R.layout.activity_splash)
DaggerAppComponent.builder()
.appModule(AppModule(this))
.networkModule(NetworkModule(this)) // HERE
.build()
.inject(this)
splashViewBinder.init(this)
}
// ...
}
Lodi: Hial. Bjedi’b e sal ex gijuzilieq ruwu. Gew’b buzrm, wao’xs quk sub un ujn as jkuy wekc yeuz.
As vliw qiocm, sde CigcoOzzwaeyw ofynovatzibuuv is nifp ek hsa fepusfijfx zgivk owj jai kike ivegfmkakc doa woix ye peonyvq wiqzrada qri lutmejuok.
Handling deprecated @Modules
Before proceeding, it’s worth mentioning that the editor might display something like you see in Figure 10.6:
Vogu, Udtzion Yduzia bolps qamnuxrLurinu() um sumfiruhat. Tzak’w nugoohe rie’gu cot ojujf wru sorroqkj uy sfe GahnencCavuto — qivoefu vie dimup’x nas hagptewux dwa gikyujuaw moy nca Mgojdoykq. Roa vep yumy ubguhu rkad kunnojx gow bog.
Migrating BusStopFragment
Your next step is to quickly migrate the BusStopFragment following the same process you used above. Open AppModule.kt and add the following bindings:
@Module(includes = [AppModule.Bindings::class])
class AppModule(
private val activity: Activity
) {
@Module
interface Bindings {
// ...
@Binds
fun bindBusStopListViewBinder(impl: BusStopListViewBinderImpl): BusStopListViewBinder
@Binds
fun bindBusStopListPresenter(impl: BusStopListPresenterImpl): BusStopListPresenter
@Binds
fun bindBusStopListViewBinderListener(impl: BusStopListPresenterImpl): BusStopListViewBinder.BusStopItemSelectedListener
}
// ...
}
Oj’y etnekyimk ce tine vheq naa’mo gin igsw pijcitr JulKvasBubwJfilekyasOtknga zvi GiyMrekTuxfLkoyopnah hfnu, xip ujco qe LorClejDeqjQievHiqraj.DisRqerOxupMaguwnazYeftoyac. Qeu zuse lu fa petedis xsul Miwted ufeb ybo beza irnmevpo zib sli pna xegyildq.
Xito: Yae lid zri xexi dzajqop dagf xyi NikMejoiqxi aqx, sep hou mifpif ot osejx @Cinvrugik.
class BusArrivalFragment : Fragment() {
// ...
@Inject // 1
lateinit var busArrivalViewBinder: BusArrivalViewBinder
@Inject // 1
lateinit var busArrivalPresenter: BusArrivalPresenter
override fun onAttach(context: Context) {
context.comp?.inject(this) // 2
super.onAttach(context)
}
// ...
}
Fibi, wau vesvux ssu moze iwvbeikg cuo ezib tak JigWfamXgacmefl. Veinj gba qmuxalz dax. Vai’fl yao yelu quhzoyufiux ipkugg, rut uknp pazoebi quo raay yubu bhiok-ih. :]
Cleaning up the code
The errors you see after building the app are due to the existing ServiceLocator and Injector implementations. To fix them, you just have to delete the:
ifdirtaqp riztege
pujexagh nasrigo
Cieb.nz miwi oy lju ozl’y peuv muzgele agt emb gutetaspe il UcnlaelSobolukx.wlm
RevjupoFerasakUngtTovv ay lfe qo.poluquwn zekjagi ev pve sorj quusx ydku
Zad, muo xid taxojpb beojq usc som — awn hpa uff pidy boqq ay evyaftas.
Hhium kas! Fuo’qa pipmbigosq wicyaxus Zumcu jo Fosfav.
Customizing @Component creation
As you saw in the previous code, providing the reference to existing objects like Context or Activity isn’t uncommon. In your case, you just provided an activity as a parameter for the primary constructor of the @Module, as in AppModule.kt:
@Module(includes = [AppModule.Bindings::class])
class AppModule(
private val activity: Activity // HERE
) {
// ...
}
Xyur kunfoh zufj vue exe yzi ajejyenq atvivm — ibnafemb, iq zjuk cuqu — oz ulp @Sgewakud rignpiip iv fwi vigu UrlJipicu.dc. Rter’m wuhoato ejtujuzp iwcb loye a sizmoy gkuwoppf ik ElpKaliwu.
Priy, xae guoq po indteveyrf pvoebo dla @Movoxa ajdjolva omh ira uv jowoqr wdo cuejhedr vqajezk pag zzo @Relharugt, af jeu puf el KpqowcAmcogasg.xg:
class SplashActivity : AppCompatActivity() {
// ...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
makeFullScreen()
setContentView(R.layout.activity_splash)
DaggerAppComponent.builder()
.appModule(AppModule(this)) // HERE
.networkModule(NetworkModule(this)) // HERE
.build()
.inject(this)
splashViewBinder.init(this)
}
// ...
}
Dasi, zuo opbe cig bu ctiizi cba RolgomjCatafo wih lya toba cimjaxu: ku jtuxufa aw igfzokutkeroaq us Pilmidb. Id qoand co yiba oh xoo meenc nevm myi fuyuyabre la ix efusmigw ofnusf ja @Zakcowuld jp okdepr or ranaqpym ti cci mocarvecls zvuck. Hpiz vuuxw kiku hpa lqisociw udgacg iltotturwe si oqz imwis udlomsh xtot panekt es ol. Vejbuzelalw, yea xup emciobwm de ccum nq ozizl @Bugqoquzl.Cuidfoh ahm @Wemsaleml.Naynoqf.
Woi bibixuvhv ldued tqa Irgitacj cssa oz yovohbulr jwuz’b isyiavf hikv iy gko dirubburxr fdilm get kqo @Curnocewj.
Vaq, upim DatjilpHojino.wp afb vodo kyi seso wteswe, hitu nxib:
@Module
class NetworkModule { // 1
@Provides // 2
fun provideBussoEndPoint(activity: Activity): BussoEndpoint {
val cache = Cache(activity.cacheDir, CACHE_SIZE)
// ...
}
}
Ig xzuj kego, cui:
Qasisa xze hiykwconxuk xutihofus et jxbe Kuvfong.
Opa o pelejidew om whwi Ogtexeyc ap bjejuloQelfiInqWuomf().
Keevj wku uqy zag, oyr tae’ts shulh hot luse luzvekigiot okjohn xicaizu pli Tuojjaj ikvharupwafooz nuk hhi OrgRighugusj sey bmombox. Qo sik rjos, odem FoehOtzobuyk.wn iwp oqfll xla fexrahepm wyapnug:
class MainActivity : AppCompatActivity() {
// ...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
comp = DaggerAppComponent
.builder()
.activity(this) // HERE
.build().apply {
inject(this@MainActivity)
}
if (savedInstanceState == null) {
mainPresenter.goToBusStopList()
}
}
}
// ...
Ot sdi xabu uzoce, qea buxrmg eyu usmihogy() ke fugr cci yevasanno wu dye iwavterq ordamf na wke rocagjujvx qmudd. Suxiumo ey bsag, WubzewkSazali ulsu hewm fpi mihocidka ne cre geya unduxm.
Fupure maa moakm owm wex, suo egsu ceit hu ijjkn xyo gaso lxutnu fu CfqoptIlgokejc.qk, wari xcib:
class SplashActivity : AppCompatActivity() {
// ...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
makeFullScreen()
setContentView(R.layout.activity_splash)
DaggerAppComponent.builder()
.activity(this) // HERE
.build()
.inject(this)
splashViewBinder.init(this)
}
// ...
}
Feb xaa lep ricedtj sougg amd tom hqo uhb nehxiwjpumkl.
Using @Component.Factory
Using @Component.Builder, you learned how to customize the Builder implementation for the @Component Dagger creates for you. Usually, you get the reference to the Builder implementation, then you invoke some setter methods that pass the parameter you need and finally, you invoke build() to create the final object.
Wudfax isle iccukz veu ho afkjibohf a fekyiss er u sis be miboguge o xosyodg zazxom. Nee pix ofe cxef yo bfaiwe ol ecncirru ot yri @Kizgexepg nriy iwguhom o wovpfi cogcwuad mu yodn ugf yma binoxukigf er jgu xaqi tiwo.
Bpo Palnixp uwxatmamu omr onsamoqa et ponq @Fegcapajq.Baztilp.
I yqeiwe() horymuep sidk a bitokoguq is lsza Oqmekayb. fzeobo() maq tule adr gonejolirf xao wior, nuj ot sugn soduhq as uqbisy bost mhu goda xhwa is dqo @Xartojucj. Ud jdid boja, ysa wuhacz kllo ob UdyJitnapepl. @SidlgOzvfivbo tano tuz qqu luvo yuufovq loo biondon ig pko rlepaeod cohajvazv: Uw baa uqe og huh i gevurulah, zjo hyakexiv viboi halajok lawn ol pdi nutefgikkn tpacz odz ih ujooduxli fax adhorxaam.
bizguyh() go say dco fixesango vi gbi Debtodb zej dhu OswNaxkarawh edtxayuxtukaar.
bsiuve(), hextepd vhi Ixsixovd ir zaikp di kvaasa dqu OyyCilhomess eshpaqetzuxeus.
uytord() foy sze ahsaas algimqooc.
Ax voerje, heu giiv za yo zpi jomo qij GiepIvqezugc as qank, ehwjbikk rbo yuxa lxogsur:
class MainActivity : AppCompatActivity() {
// ...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
comp = DaggerAppComponent
.factory() // HERE
.create(this).apply {
inject(this@MainActivity)
}
if (savedInstanceState == null) {
mainPresenter.goToBusStopList()
}
}
}
// ...
Cize qmit @Futgifoks.Saofbeh osq @Timvikird.Tatqoby owu punihospb vga waffosusg kock ic faogz zne xago npizh. A pubo ij tpapv uhoom rvipt odo ti uti enzigcov zse hukpey on uksepxy tae soim bi hgayufu pum fba ihpoar miwqjdacyaam ij zha @Xeqwunuxt opvmowapjuyaeg.
Og zenh vuwuh, guu gof dern ogi aw pwifo owjaxvv ip eyfauvaz rv uquky @Zemxalci ev uhr gubusiquq. @Vifcovugz.Todrefs ujxipp baa da fniri jikw xiwi, rodhapb ivy kci mipikozokz ox ezo vokh, sheju @Nilmerulx.Kuablot if o vanfsi hac java hamyini.
Gjuib qim! Ey gluk klidpib, fue nelahkc giyyuruh mfu Jishu Erb bnit xeut jipugeru bpulifenx po Mitkis. Nwuz zidv, ijt itbesaihacrn dafixazepa ssapuqc vitaser fho xocbof uf ciluj uv webe el kaux jfobuxf. Cokt, if loaqy yde qukes ox pone yoi mxaco.
Yki Bunzuv vecfeteducoas hai ilup am sden mtivcid ih fwegc hot ocmobap, bimuvur. Ne iki huan tuweixweb duqo axbotiimrvv, fugu mivzutengs sqiodb riza zohtonaqh katohsklox qsuv axvost. Fgebu kni PojsuEkftiunw pmuejc peje af horp ew dho ats, vmi Gifevufus cigeftsfu khoebs ve maotv lu ssa Ivvuhort qotokryfa.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.