在說Scope之前,讓我們先在代碼里面搞一些事情,這樣發現問題后更加有助于理解Scpoe的概念。
事情是這樣的:
image.png
多次從component中獲取githubService和picasso對象,然后將對象在內存中的地址打印出來。按照感覺來說,每次打印的地址應該都是一致的,但真是這樣嗎?跑一遍試試:
image.png
事實確實殘酷,每次獲取的都不一樣。但是我們想要使用同一個對象,尤其是想OKHttp這樣的網絡鏈接庫,我們想要在Retrofit和Picasso中使用同一個OKHttpClient。
但Dagger默認會為每個依賴重新創建一對象,所以我們需要明確指明告訴Dagger,我們只想為某些依賴創建一個對象,其他需要的時候復用即可(相當于一個單例)。這樣就引出了Scope的作用。
Scope是一個Annotation。首先創建一個GithubApplicationScope
:
image.png
通過注解
@Scope
告訴Dagger這是一個Scope,同時把Rentention設置為@Retention(RetentionPolicy.CLASS)
。那么創建是創好了,那怎么用呢?直接在component上加上這個注解:image.png
這樣就行了?不不不,你需要在每個Module需要提供單例的provider方法上都加上這個注解(比如提供OKHttp的provider)。這樣就告訴Dagger所有這個Component提供的Picasso和githubService都是同一個實例。甚至是提供Context的Provider也可以用這個注解。這樣我們再次運行代碼,看看Log中得到是什么:
image.png
完全一樣的!而且使用的OKHttp對象也是同一個。
這里還不得不提到另一個注解@Singleton。@Singleton是Dagger中最容易讓人誤解的注解。Singleton的作用和Scpoe上面這樣用的效果是相同的。但是Singleton容易給人造成一種誤解就是用Singleton注解后在整個Java代碼中都是單例,但實際上他和Scope一樣,只是在同一個Component是單例。也就是說,如果重新調用了component的build()方法,即使使用了Singleton注解了,但仍然獲取的是不同的對象。所以引用TwistedEquations的原話就是:永遠不要再任何情況下使用Singleton!!!
下面一篇文章將會介紹Qualifier和Named注解的用法。
相關文章:
從實例出發理解Dagger2(一)
從實例出發理解Dagger2(二)
從實例出發理解Dagger2(三)
從實例出發理解Dagger2(四)
從實例出發理解Dagger2(五)
從實例出發理解Dagger2(六)
從實例出發理解Dagger2(七)
參考資料:https://www.youtube.com/watch?v=49dZCUJfzXM&index=4&list=PLuR1PJnGR-Ih-HXnGSpnqjdhdvqcwhfFU