版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、依賴注入利器 - Dagger 概述在開發(fā)過程中,為了實(shí)現(xiàn)解耦,我們經(jīng)常使用依賴注入,常見的依賴注入方式有:構(gòu)造方法注入:在構(gòu)造方法中把依賴作為參數(shù)傳遞進(jìn)去setter方法注入:添加setter方法,把依賴傳遞進(jìn)去接口注入:把注入方法抽到一個(gè)接口中,然后實(shí)現(xiàn)該接口,把依賴傳遞進(jìn)去下面用一個(gè)小栗子來說明三種方式的用法:public class PersonService implements DependencyInjecter private PersonDao personDao; / 構(gòu)造方法注入 public PersonService(PersonDao personDao) this
2、.personDao = personDao; / setter方法注入 public void setPersonDao(PersonDao personDao) this.personDao = personDao; / 接口注入:實(shí)現(xiàn)DependencyInjecter接口 Override public void injectPersonDao(PersonDao personDao) this.personDao = personDao; . . 我們來看下使用一般的依賴注入方法時(shí),代碼會(huì)是怎么樣的:public class MainActivity extends AppCompa
3、tActivity private PersonService mService; Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); / 創(chuàng)建PersonService的依賴:personDao PersonDao personDao = new PersonDaoImpl(); / 通過構(gòu)造方法注入依賴 mService = new PersonService(person
4、Dao); 看起來還好是吧?但現(xiàn)實(shí)情況下,依賴情況往往是比較復(fù)雜的,比如很可能我們的依賴關(guān)系如下圖:PersonDaoImpl依賴類A,類A依賴B,B依賴C和D在這種情況下,我們就要寫出下面這樣的代碼了:public class MainActivity extends AppCompatActivity private PersonService mService; Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.l
5、ayout.activity_main); / 創(chuàng)建依賴D D d = new D(); / 創(chuàng)建依賴C C c = new C(); / 創(chuàng)建依賴B B b = new B(c, d); / 創(chuàng)建依賴A A a = new A(b); / 創(chuàng)建PersonService的依賴:personDao PersonDao personDao = new PersonDaoImpl(a); / 通過構(gòu)造方法注入依賴 mService = new PersonService(personDao); MainActivity只是想使用PersonService而已,卻不得不關(guān)注PersonService
6、的依賴是什么、PersonDaoImpl依賴的依賴是什么,需要把整個(gè)依賴關(guān)系搞清楚才能使用PersonService。而且還有一個(gè)不好的地方,一旦依賴關(guān)系變更了,比如A不再依賴B了,那么就得修改所有創(chuàng)建A的地方。那么,有沒有更好的方式呢?Dagger就是為此而生的,讓我們看看使用Dagger后,MainActivity會(huì)變成什么模樣:public class MainActivity extends AppCompatActivity Inject PersonService mService; Override protected void onCreate(Bundle savedInst
7、anceState) super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); / Dagger注入,讀者現(xiàn)在可先不關(guān)注里面做了什么操作 DaggerPersonServiceComponent.create().inject(MainActivity.this); / 注意,mService已經(jīng)是非空了,可以正常使用 mService.update(1, HansChen); . 之前創(chuàng)建A、B、C、D、PersonDaoImpl等依賴的代碼全不見了,只需要調(diào)用一個(gè)注入語句就全搞定了。調(diào)用了注入語句
8、之后,mService就可以正常使用了,是不是挺方便呢?至于這句注入語句具體干了什么,讀者現(xiàn)在可以先不管,后面會(huì)有詳細(xì)說明,這里只是做一個(gè)使用演示而已。我們大概猜想一下,在MainActivity使用PersonService需要做哪些?分析生成依賴關(guān)系圖,如PersonServicePersonDaoImplABC&D根據(jù)依賴關(guān)系圖獲取相關(guān)依賴,比如依次創(chuàng)建D、C、B、A、PersonDaoImpl、PersonService的實(shí)例把生成的PersonService實(shí)例傳遞給MainActivity的mService成員變量其實(shí)Dagger做的也就是上面這些事情了,接下來就讓我們真正開始學(xué)習(xí)
9、Dagger吧聲明需要注入的對(duì)象首先我們應(yīng)該用javax.inject.Inject去注解需要被自動(dòng)注入的對(duì)象,Inject是Java標(biāo)準(zhǔn)的依賴注入(JSR-330)注解。比如下面栗子中,需要注入的對(duì)象就是MainActivity的mService。這里有個(gè)要注意的地方,被Inject注解的變量不能用private修飾public class MainActivity extends AppCompatActivity / 注意,不能被private修飾 Inject PersonService mService; .如何實(shí)例化出依賴?在執(zhí)行依賴注入的時(shí)候,Dagger會(huì)查找Inject注解的
10、成員變量,并嘗試獲取該類的實(shí)例,Dagger最直接的方式就是直接new出相應(yīng)的對(duì)象了。實(shí)例化對(duì)象的時(shí)候,會(huì)調(diào)用對(duì)象的構(gòu)造方法,但假如有多個(gè)構(gòu)造方法,具體用哪個(gè)構(gòu)造方法來實(shí)例化對(duì)象?Dagger肯定是不會(huì)幫我們“擅自做主”的,用哪個(gè)構(gòu)造方法來實(shí)例化對(duì)象應(yīng)該是由我們做主的,所以我們需要給相應(yīng)的構(gòu)造方法添加Inject注解。當(dāng)Dagger需要實(shí)例化該對(duì)象的時(shí)候,會(huì)調(diào)用Inject注解的構(gòu)造方法來實(shí)例化對(duì)象:public class PersonService implements DependencyInjecter private PersonDao personDao; / 用Inject注解,
11、相當(dāng)于告訴Dagger需要實(shí)例化PersonService的時(shí)候,請(qǐng)調(diào)用這個(gè)構(gòu)造方法 Inject public PersonService(PersonDao personDao) this.personDao = personDao; .聰明的你應(yīng)該發(fā)現(xiàn)了,調(diào)用PersonService的構(gòu)造方法需要傳入PersonDao實(shí)例,所以要實(shí)例化PersonService,必須先要實(shí)例化PersonDao,Dagger會(huì)幫我們自動(dòng)分析出這個(gè)依賴關(guān)系,并把它添加到依賴關(guān)系圖里面!Dagger會(huì)嘗試先去實(shí)例化一個(gè)PersonDao,如果PersonDao又依賴于另外一個(gè)對(duì)象A,那么就先嘗試去實(shí)例化A
12、以此類推,是不是很像遞歸?當(dāng)所有依賴都被實(shí)例化出來之后,我們的PersonService當(dāng)然也被構(gòu)造出來了。問題又來了,如果PersonDao是一個(gè)接口呢?Dagger怎么知道這個(gè)接口應(yīng)該怎么實(shí)現(xiàn)?答案是不知道的,那么Dagger怎么實(shí)例化出一個(gè)接口出來?這個(gè)就是Module存在的意義之一了。關(guān)于Module的講解我們會(huì)在后面詳細(xì)說明,我們現(xiàn)在只要知道,Module里面會(huì)定義一些方法,這些方法會(huì)返回我們的依賴,就像:Modulepublic class PersonServiceModule /* * 提供PersonDao接口實(shí)例 */ Provides PersonDao provideP
13、ersonDao(A a) return new PersonDaoImpl(a); Dagger根據(jù)需求獲取一個(gè)實(shí)例的時(shí)候,并不總是通過new出來的,它會(huì)優(yōu)先查找Module 中是否有返回相應(yīng)實(shí)例的方法,如果有,就調(diào)用Module的方法來獲取實(shí)例。比如你用Inject注解了一個(gè)成員變量,Dagger會(huì)查找Module中是否有用Provides注解的,返回該類實(shí)例的方法,有的話就會(huì)調(diào)用provide方法來獲得實(shí)例,然后注入,如果沒有的話Dagger就會(huì)嘗試new出一個(gè)實(shí)例。就像我們現(xiàn)在這個(gè)栗子,PersonService依賴于PersonDao接口,Dagger不能直接為我們new出一個(gè)接口,
14、但我們可以提供一個(gè)Module,在Module中定義一個(gè)返回PersonDao接口實(shí)例的方法,這樣,Dagger就可以解決實(shí)例化PersonDao的問題了。我們?cè)偈崂硪幌铝鞒?,如果我們用Inject注解了一個(gè)成員變量,并調(diào)用注入代碼之后,Dagger會(huì)這樣處理:查找Module中是否有用Provides注解的,返回該類實(shí)例的方法如果有,就調(diào)用那個(gè)provide方法來獲得實(shí)例,然后注入如果沒有,就嘗試調(diào)用相應(yīng)的類中被Inject注解的構(gòu)造方法new出一個(gè)實(shí)例,然后注入如果沒有一個(gè)構(gòu)造方法被Inject注解,Dagger會(huì)因不能滿足依賴而出錯(cuò)所以假如一個(gè)變量被Inject注解,要么在Module中
15、提供provide方法獲取實(shí)例,要么該類提供一個(gè)被Inject注解的構(gòu)造方法,否則Dagger會(huì)出錯(cuò)Module的使用一般而言,Dagger會(huì)獲取所有依賴的實(shí)例,比如當(dāng)需要一個(gè)TestBean的時(shí)候,會(huì)通過new TestBean()創(chuàng)建實(shí)例并注入到類中。但是,以下情況會(huì)就不好處理了:需要生成的是一個(gè)接口,而Dagger不能直接實(shí)例化接口不能在第三方庫的類中添加注解可配置的對(duì)象必須是配置的為了解決以上問題,我們需要定義一個(gè)被Module注解的類,在里面定義用Provides注解的方法。用該方法返回所需的實(shí)例。Modulepublic class PersonServiceModule Prov
16、ides D provideD() return new D(); Provides C provideC() return new C(); Provides B provideB(C c, D d) return new B(c, d); Provides A provideA(B b) return new A(b); /* * 提供PersonDao實(shí)例 */ Provides PersonDao providePersonDao(A a) return new PersonDaoImpl(a); 就像providePersonDao返回了PersonDao接口實(shí)例,Dagger雖然不
17、能直接實(shí)例化出PersonDao接口,但卻可以調(diào)用Module的providePersonDao方法來獲得一個(gè)實(shí)例。providePersonDao方法需要傳入A的實(shí)例,那么這里也構(gòu)成了一個(gè)依賴關(guān)系圖。Dagger會(huì)先獲取A的實(shí)例,然后把實(shí)例傳遞給providePersonDao方法。Component的使用到目前為止,我們雖然知道了:Dagger怎么獲取實(shí)例: 從Module的provide方法中獲取通過Inject注解的構(gòu)造方法new出新的實(shí)例Dagger會(huì)推導(dǎo)provide方法和構(gòu)造方法的參數(shù),形成依賴圖,并“滿足”我們依賴圖的需求,獲取依賴的實(shí)例看樣子需要注入的依賴可以獲取了,但是不是
18、總覺得還有點(diǎn)“零碎”,整個(gè)流程還沒連貫起來?比如,Module既然是一個(gè)類,生成依賴圖的時(shí)候,怎么知道跟哪個(gè)Module掛鉤?即使最后生成了需要的實(shí)例,注入的“目的地”是哪里?怎么才能把它注入到“目的地”?殘缺的這部分功能,正是Component提供的,Component起到了一個(gè)橋梁的作用,貫通Module和注入目標(biāo)。我們來看看最開始那個(gè)例子,我們是怎么進(jìn)行依賴注入的:public class MainActivity extends AppCompatActivity Inject PersonService mService; Override protected void onCrea
19、te(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); PersonServiceComponent component = DaggerPersonServiceComponent.builder() .personServiceModule(new PersonServiceModule() .build(); / 注入,所有Inject注解的成員變量都會(huì)同時(shí)注入 component.inject(MainActivity.this);
20、 / 通過component獲取實(shí)例,注意,這里只是演示用法,其實(shí)mService在component.inject的時(shí)候已經(jīng)完成了注入 mService = component.getPersonService(); 這個(gè)DaggerPersonServiceComponent是什么鬼?DaggerPersonServiceComponent其實(shí)是Dagger為我們自動(dòng)生成的類,它實(shí)現(xiàn)了一個(gè)Component接口(這個(gè)接口是需要我們自己寫的),我們來看下它實(shí)現(xiàn)的接口長什么樣子:/* * 指定PersonServiceModule,當(dāng)需要獲取某實(shí)例的時(shí)候,會(huì)查找PersonServiceMod
21、ule中是否有返回相應(yīng)類型的方法,有的話就通過該方法獲得實(shí)例 * * author HansChen */Component(modules = PersonServiceModule.class)public interface PersonServiceComponent /* * 查找activity中被Inject注解的成員變量,并嘗試獲取相應(yīng)的實(shí)例,把實(shí)例賦給activity的成員變量 * 注意函數(shù)格式:返回值為空、帶有一個(gè)參數(shù) */ void inject(MainActivity activity); /* * Dagger會(huì)嘗試從Module中獲取PersonService實(shí)例
22、,如果Module中不能獲取對(duì)應(yīng)實(shí)例,則通過PersonService的構(gòu)造方法new出一個(gè)實(shí)例 * 注意函數(shù)格式:參數(shù)為空,返回值非空 */ PersonService getPersonService();這個(gè)接口被Component注解修飾,它里面可以定義3種類型的方法:返回值為空,有一個(gè)參數(shù):查找參數(shù)中被Inject注解的成員變量,并嘗試獲取相應(yīng)的實(shí)例(通過Module的provide方法或Inject注解的構(gòu)造方法new出新的實(shí)例),把實(shí)例賦給參數(shù)的成員變量返回值非空,參數(shù)為空:獲取相應(yīng)實(shí)例并返回返回值是Component,參數(shù)是Moduld,通過該方法可以創(chuàng)建SubComponen
23、t實(shí)例既然獲取實(shí)例的時(shí)候,有可能用到Module,那么就必須為這個(gè)Component指定使用的Module是什么。具體做法就是在Component注解中指定modules。 定義好Component之后,Dagger會(huì)自動(dòng)幫我們生成實(shí)現(xiàn)類,這就是Dagger強(qiáng)大的地方!生成的類名格式是:Dagger+Component名。 Component提供了2種方法,一個(gè)是注入式方法,一個(gè)是獲取實(shí)例方法。具體用什么方法,就看個(gè)人需求了。一個(gè)Component其實(shí)也對(duì)應(yīng)了一個(gè)依賴圖,因?yàn)镃omponent使用哪個(gè)Module是確定不變的,依賴關(guān)系無非也就是跟Module和類的定義有關(guān)。一旦這些都確定下來了
24、,在這個(gè)Component范圍內(nèi),依賴關(guān)系也就被確定下來了。額外再說一點(diǎn),在Dagger1中,Component的功能是由ObjectGraph實(shí)現(xiàn)的,Component是用來代替它的。Component定義好之后,build一下工程,Dagger就會(huì)自動(dòng)為我們生成實(shí)現(xiàn)類了,就可以使用自動(dòng)生成的實(shí)現(xiàn)類來進(jìn)行依賴注入了。到現(xiàn)在為止,我們已經(jīng)通過Dagger完成了依賴注入。可能看起來比正常方法麻煩得多,但是Dagger框架可以讓依賴的注入和配置獨(dú)立于組件之外,它幫助你專注在那些重要的功能類上。通過聲明依賴關(guān)系和指定規(guī)則構(gòu)建整個(gè)應(yīng)用程序。熟悉完Dagger基本的使用之后,接下來我們來講解一些稍微高級(jí)
25、一點(diǎn)的用法:Dagger的進(jìn)階使用Components之間的關(guān)系在Dagger中,Component之間可以有兩種關(guān)系:Subcomponents和Component dependencies。他們有什么作用呢?比如在我們應(yīng)用中,經(jīng)常會(huì)有一些依賴我們?cè)诟鱾€(gè)界面都使用得到,比如操作數(shù)據(jù)庫、比如網(wǎng)絡(luò)請(qǐng)求。假設(shè)我們有個(gè)ServerApi的接口,在頁面A、B、C都使用到了,那么我們要在頁面A、B、C的Component里面都能獲取到ServerApi的實(shí)例,但顯然,獲取ServerApi實(shí)例的方法都是一樣的,我們不想寫重復(fù)的代碼。于是我們可定義一個(gè)ApplicationComponent,在里面返回S
26、erverApi實(shí)例,通過Component之間的關(guān)系便可以共享ApplicationComponent提供的依賴圖。下面通過Android中的一個(gè)小栗子來說明Subcomponents和Component dependencies如何使用dependencies先說明下各個(gè)模塊之間的關(guān)系 首先,我們定義一個(gè)ApplicationComponent,它定義了一個(gè)方法,通過它來獲得ServerApi實(shí)例。ApplicationComponent還關(guān)聯(lián)了ApplicationModule,這個(gè)Module是ServerApi實(shí)例的提供者,注意,這個(gè)Moduld還可以返回Context實(shí)例Compo
27、nent(modules = ApplicationModule.class)public interface ApplicationComponent ServerApi getServerApi();Modulepublic class ApplicationModule private final Context mAppContext; ApplicationModule(Context context) mAppContext = context.getApplicationContext(); Provides Context provideAppContext() return
28、mAppContext; Provides ServerApi provideServerApi(Context context) return new ServerApiImpl(context); public class DemoApplication extends Application private ApplicationComponent mAppComponent; Override public void onCreate() super.onCreate(); mAppComponent = DaggerApplicationComponent.builder().app
29、licationModule(new ApplicationModule(this).build(); public ApplicationComponent getAppComponent() return mAppComponent; / 注意,這里有個(gè)dependencies聲明Component(pendencies = ApplicationComponent.class, modules = MainPresenterModule.class)public interface MainPresenterComponent MainPresenter getMainPresenter
30、();Modulepublic class MainPresenterModule private MainView mMainView; public MainPresenterModule(MainView mainView) this.mMainView = mainView; Provides MainView provideMainView() return mMainView; public class MainPresenter private MainView mMainView; private ServerApi mServerApi; Inject public Main
31、Presenter(MainView mainView, ServerApi serverApi) this.mMainView = mainView; this.mServerApi = serverApi; Component中g(shù)etMainPresenter的目的很簡單,就是返回MainPresenter,而MainPresenter又依賴MainView和ServerApi,MainView還好說,在MainPresenterModule中有provide方法,但是ServerApi呢?就像上面說的那樣,如果我們?cè)谶@個(gè)Moduld中也添加相應(yīng)的provide方法,那真是太麻煩了(當(dāng)然,
32、這樣做完全是可以實(shí)現(xiàn)的),所以我們依賴了ApplicationComponent,通過dependencies,在被依賴的Component暴露的對(duì)象,在子Component中是可見的。這個(gè)是什么意思呢?意思有兩個(gè):被依賴Component接口暴露的對(duì)象,可以添加到依賴者的依賴圖中Component接口沒有暴露的對(duì)象,依賴者是不可見的對(duì)于第一點(diǎn)應(yīng)該比較好理解,就像這個(gè)栗子,MainPresenterComponent生成MainPresenter需要ServerApi,而ApplicationComponent中有接口暴露了ServerApi,所以MainPresenterComponent可
33、以獲得ServerApi 對(duì)于第二點(diǎn),假設(shè)MainPresenter還需要傳入一個(gè)Context對(duì)象,我們注意到,ApplicationModule是可以提供Context的,那MainPresenterComponent能不能通過ApplicationComponent獲取Context實(shí)例?答案是不行的,因?yàn)锳pplicationComponent沒有暴露這個(gè)對(duì)象。想要獲取Context,除非ApplicationComponent中再添加一個(gè)getContext的方法。他們之間的關(guān)系可以用下圖描述:Subcomponents讓我們對(duì)上面的栗子改造改造: 去除MainPresenterCo
34、mponent的Component注解,改為Subcomponent:Subcomponent(modules = MainPresenterModule.class)public interface MainPresenterComponent void inject(MainActivity activity); MainPresenter getMainPresenter();在ApplicationComponent中新增plus方法(名字可隨意?。?,返回值為MainPresenterComponent,參數(shù)為MainPresenterModule:Component(modules
35、= ApplicationModule.class)public interface ApplicationComponent MainPresenterComponent plus(MainPresenterModule module);這樣,就構(gòu)建了一個(gè)ApplicationComponent的子圖:MainPresenterComponent。子圖和dependencies的區(qū)別就是,子圖可以范圍父圖所有的依賴,也就是說,子圖需要的依賴,不再需要在父Component中暴露任何對(duì)象,可以直接通過父圖的Moduld提供!他們的關(guān)系變?yōu)榱耍篠copesScopes可是非常的有用,Dagger
36、2可以通過自定義注解限定注解作用域。Singleton是被Dagger預(yù)先定義的作用域注解。沒有指定作用域的Provides方法將會(huì)在每次注入的時(shí)候都創(chuàng)建新的對(duì)象一個(gè)沒有scope的component不可以依賴一個(gè)有scope的組件component子組件和父組件的scope不能相同Module中provide方法的scope需要與Component的scope一致我們通常的ApplicationComponent都會(huì)使用Singleton注解,也就會(huì)是說我們?nèi)绻远xcomponent必須有自己的scope。讀者到這里,可能還不能理解Scopes的作用,我們先來看下默認(rèn)提供的Singlton
37、到底有什么作用,然后再討論Scopes的意義:SingltonSingletons是java提供的一個(gè)scope,我們來看看Singletons能做什么事情。 為Provides注釋的方法或可注入的類添加添加注解Singlton,構(gòu)建的這個(gè)對(duì)象圖表將使用唯一的對(duì)象實(shí)例,比如我們有個(gè)ServerApi 方法一:用Singleton注解類:Singletonpublic class ServerApi Inject public ServerApi() public boolean login(String username, String password) return HansChen.eq
38、uals(username) & 123456.equals(password); 方法二:用Singleton注解Module的provide方法:Modulepublic class ApplicationModule Singleton Provides ServerApi provideServerApi() return new ServerApi(); 然后我們有個(gè)Component:SingletonComponent(modules = ApplicationModule.class)public interface ApplicationComponent ServerApi
39、 getServerApi();然后執(zhí)行依賴注入:public class MainActivity extends AppCompatActivity Inject ServerApi mService; Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ApplicationComponent component = DaggerApplicationComponent.
40、create(); Log.d(Hans, component.getServerApi().toString(); Log.d(Hans, component.getServerApi().toString(); Log.d(Hans, component.getServerApi().toString(); 使用了以上兩種方法的任意一種,我們都會(huì)發(fā)現(xiàn),通過component.getServerApi()獲得的實(shí)例都是同一個(gè)實(shí)例。不過要注意一點(diǎn)的是,如果類用Singleton注解了,但Module中又存在一個(gè)provide方法是提供該類實(shí)例的,但provide方法沒有用Singleton注解
41、,那么Component中獲取該實(shí)例就不是單例的,因?yàn)闀?huì)優(yōu)先查找Module的方法。 這個(gè)單例是相對(duì)于同一個(gè)Component而言的,不同的Component獲取到的實(shí)例將會(huì)是不一樣的。自定義Scope既然一個(gè)沒有scope的component不可以依賴一個(gè)有scope的組件component,那么我們必然需要自定義scope來去注解自己的Component了,定義方法如下:DocumentedScopeRetention(RetentionPolicy.RUNTIME)public interface FragmentScoped 定義出來的FragmentScoped在使用上和Single
42、ton是一樣的,那它和Singleton除了是不一樣的注解之外,還有什么不一樣呢?答案是沒有!我們自定義的scope和Singleton并沒有任何不一樣,不會(huì)因?yàn)镾ingleton是java自帶的注解就會(huì)有什么區(qū)別。那么,這個(gè)scope的設(shè)定是為了什么呢?scope的作用scope除了修飾provide方法可以讓我們獲得在同一個(gè)Component實(shí)例范圍內(nèi)的單例之外,主要的作用就是對(duì)Component和Moduld的分層管理以及依賴邏輯的可讀性。 這里借用一個(gè)網(wǎng)絡(luò)上的圖片說明:ApplicationComponent一般會(huì)用singleton注解,相對(duì)的,它的Module中provide方法也
43、只能用singleton注解。UserComponent是用UserSCope能直接使用ApplicationModule嗎?不能!因?yàn)樗麄z的scope不一致,這就是這個(gè)設(shè)定帶來的好處,防止不同層級(jí)的組件混亂。另外,因?yàn)橛辛藄cope的存在,各種組件的作用和生命周期也變得可讀起來了Lazy注入有時(shí)可能會(huì)需要延遲獲取一個(gè)實(shí)例。對(duì)任何綁定的 T,可以構(gòu)建一個(gè) Lazy 來延遲實(shí)例化直至第一次調(diào)用 Lazy 的 get() 方法。注入之后,第一次get的時(shí)會(huì)實(shí)例化出 T,之后的調(diào)用都會(huì)獲取相同的實(shí)例。public class MainActivity extends AppCompatActivit
44、y implements MainView / 懶加載 Inject Lazy mPresenter; Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MainPresenterComponent component = DaggerMainPresenterComponent.builder() .mainPresenterModule(new MainPresenter
45、Module(this) .applicationComponent(DemoApplication) getApplication().getAppComponent() .build(); component.inject(this); Log.d(Hans, mPresenter.get().toString(); / 實(shí)例化MainPresenter Log.d(Hans, mPresenter.get().toString(); / 跟上次獲取的實(shí)例是同一個(gè)實(shí)例 Provider注入跟Lazy注入不一樣的是,有時(shí)候我們希望每次調(diào)用get的時(shí)候,獲取到的實(shí)例都是不一樣的,這時(shí)候可以用P
46、rovider注入public class MainActivity extends AppCompatActivity implements MainView / Provider Inject Provider mPresenter; Override protected void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MainPresenterComponent component = DaggerMai
47、nPresenterComponent.builder() .mainPresenterModule(new MainPresenterModule(this) .applicationComponent(DemoApplication) getApplication().getAppComponent() .build(); component.inject(this); Log.d(Hans, mPresenter.get().toString(); / 實(shí)例化MainPresenter Log.d(Hans, mPresenter.get().toString(); / 獲取新的MainPresenter實(shí)例 Qualifiers注入到目前為止,我們的demo里,Moduld的provide返回的對(duì)象都是不一樣的,但是下面這種情況就不好處理了:Modulepublic class ApplicationModule . / 返回ServerApi實(shí)例 Provides ServerApi provideServerApiA(Context context) return ew ServerApi
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 【新課標(biāo)Ⅲ卷】高三第二次全國大聯(lián)考語文試卷(含答案)
- 2025年專業(yè)期刊發(fā)行協(xié)議
- 2025年合伙勞動(dòng)分工協(xié)議
- 2025年教育捐贈(zèng)合同樣本
- 2025年度教育機(jī)構(gòu)教學(xué)質(zhì)量擔(dān)保合同全文4篇
- 2025版危品運(yùn)輸企業(yè)安全文化建設(shè)合同3篇
- 2024版智能家居系統(tǒng)集成安裝合同
- 2025年留學(xué)家庭教育咨詢與心理輔導(dǎo)服務(wù)合同4篇
- 2025版學(xué)生入學(xué)校園體育設(shè)施維護(hù)與服務(wù)合同2篇
- 2025年度木材行業(yè)人才培訓(xùn)與服務(wù)合同4篇
- 2024公路瀝青路面結(jié)構(gòu)內(nèi)部狀況三維探地雷達(dá)快速檢測(cè)規(guī)程
- 2024年高考真題-地理(河北卷) 含答案
- 2024光儲(chǔ)充一體化系統(tǒng)解決方案
- 處理后事授權(quán)委托書
- 食材配送服務(wù)方案投標(biāo)方案(技術(shù)方案)
- 足療店?duì)I銷策劃方案
- 封條(標(biāo)準(zhǔn)A4打印封條)
- 2024年北京控股集團(tuán)有限公司招聘筆試參考題庫含答案解析
- 延遲交稿申請(qǐng)英文
- 運(yùn)動(dòng)技能學(xué)習(xí)與控制課件第十章動(dòng)作技能的指導(dǎo)與示范
- 石油天然氣建設(shè)工程交工技術(shù)文件編制規(guī)范(SYT68822023年)交工技術(shù)文件表格儀表自動(dòng)化安裝工程
評(píng)論
0/150
提交評(píng)論