出來混早晚要還的,技術債Dagger2:Android篇(中)@Scope、@Singleton

前言

上篇文章,咱們聊完了簡單的Dagger2應用。java

出來混早晚要還的,技術債Dagger2:基礎篇android

出來混早晚要還的,技術債Dagger2:Android篇(上)dom

而且結尾留下了一個問題:生命週期問題。 我相信瞭解過Dagger的小夥伴,必定知道Scope的概念。甚至也知道@Singleton這個註解。ide

今天就把這個坑填上。讓咱們一塊兒聊一聊@Scopepost

正文

1、理解@Scope

首先,我們必需要明確@Scope做用對象:學習

  • 首先,它被用在提供依賴的地方,好比:@Provides@Inject構造方法。
  • 其次,只要提供依賴的地方使用了@Scope,那麼對應的Component必定要被一樣的@Scope修飾。

對於Dagger來講,@Scope表達的意思是:被@Scope所標識的Component的生命週期內,只要是@Scope所標識提供依賴的方法,那麼所提供的依賴都是單例!ui

很差理解?上段簡單的代碼:this

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface MDove {
}

@Module
public class MDoveModule {
    // 這裏用@MDove標識,並提供一個A類
    @MDove
    @Provides
    AppleBean provideA() {
        return new A();
    }
    // 這裏沒有用@MDove標識,並提供一個B類
    @Provides
    OrgranBean provideB() {
        return new B();
    }
}

@MDove
@Component(modules = {MDoveModule.class})
public interface MDoveComponent {
    void inject(MDoveActivity mMDoveActivity);
}

public class FuriteScopeActivity extends AppCompatActivity {
    @Inject A a1; // 爲縮減行數
    @Inject A a2;
    @Inject B b1;
    @Inject B b2;
    MDoveComponent mMDoveComponent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // 省略代碼
        Log.e("MDove", "a1:" + a1.toString());
        Log.e("MDove", "a2:" + a2.toString());
        Log.e("MDove", "b1:" + b1.toString());
        Log.e("MDove", "b2:" + b2.toString());
    }
}
複製代碼

打印結果是什麼樣子呢?spa

a1:dfecc873d

a2:dfecc87

b1:f3867b4

b2:3d52fdd

這下應該可以理解上面文字的含義了吧?。

總結一下就是:Dagger2中的@Scope,保證了在@Scope標記下的Component做用域內 ,只要被@Scope註解的方法,所提供的依賴,會保持單例 。 必定要好好理解這段話!

@Singleton也是一種@Scope一樣知足上述總結。

2、@Singleton一樣如此

這裏必須加粗聲明!不要看到Singleton,就想固然覺得單例!

@Singleton和單例沒有半毛錢關係!

@Singleton只是自定義的@Scope而已,只要是標識了@Scope註解,那麼此Component所注入的依賴就是單例,和@Singleton沒有任何關係。

這裏咱們想叫什麼名字均可以!@Skr@Kunkun、、@Fanfan...啥都行!均可以保證單例。

總之就是一句話:在@Scope註解標記的Component的做用域內所注入的實例是單例的 。

3、上點代碼

其實,寫完1、二關於@Scope的內容就算已經結束了。不過總覺的若是不加點代碼彷佛渾身不得勁,仍是整點代碼吧。

這裏的代碼,仍是「拿來主義」,用國外一些哥們的。不得不認可人家在博客方面仍是挺用心噠。

原Demo地址

3.一、自定義@Scope

@Scope
public @interface MainActivityScope {}
複製代碼

3.二、建立使用此@Scope的Component

@Component(dependencies = RandomUserComponent.class)
@MainActivityScope
public interface MainActivityComponent {
    RandomUserAdapter getRandomUserAdapter();
    RandomUsersApi getRandomUserService();
}
複製代碼

這裏提到的類,咱們均可以在上一篇文章出來混早晚要還的,技術債Dagger2:Android篇(上),找到對應的代碼實現。這裏就不對展開了。

依賴關係圖以下:

3.三、建立對應的@Module

@Module
public class MainActivityModule {
    private final MainActivity mainActivity;
    
    public MainActivityModule(MainActivity mainActivity) {
        this.mainActivity = mainActivity;
    }
    // 注意理解這裏的@MainActivityScope
    @Provides
    @MainActivityScope
    public RandomUserAdapter randomUserAdapter(Picasso picasso){
        return new RandomUserAdapter(mainActivity, picasso);
    }
}
複製代碼

有了之1、二的鋪墊,這裏就不難理解了吧。加了@MainActivityScope,咱們的randomUserAdapter(Picasso picasso)MainActivityComponent生命週期內,就會永葆單例。不然每次都會new。

3.四、提供MainActivityComponent所需的依賴

public class RandomUserApplication extends Application {
    private RandomUserComponent randomUserApplicationComponent;

    public static RandomUserApplication get(Activity activity){
        return (RandomUserApplication) activity.getApplication();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        randomUserApplicationComponent = DaggerRandomUserComponent.builder()
                .contextModule(new ContextModule(this))
                .build();
    }

    public RandomUserComponent getRandomUserApplicationComponent(){
        return randomUserApplicationComponent;
    }
}
複製代碼

3.五、MainActivity

public class MainActivity extends AppCompatActivity {
    // 省略
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    // 省略
    MainActivityComponent mainActivityComponent = DaggerMainActivityComponent.builder()
           .mainActivityModule(new MainActivityModule(this))
           .randomUserComponent(RandomUserApplication.get(this).getRandomUserApplicationComponent())
           .build();
    randomUsersApi = mainActivityComponent.getRandomUserService();
    mAdapter = mainActivityComponent.getRandomUserAdapter();
    // 省略
  }
}
複製代碼

此狀況下,不管咱們調用多少次mainActivityComponent.getRandomUserAdapter();咱們拿到的RandomUserAdapter都是單例的。

有興趣的下夥伴能夠跑一跑Demo哦~~

尾聲

關於@Scope到此就結束了。下一篇內容會針對@Component.Builder@SubComponent的展開梳理。

爭取儘快結束Dagger2,的內容。

我是一個應屆生,最近和朋友們維護了一個公衆號,內容是咱們在從應屆生過渡到開發這一路所踩過的坑,以及咱們一步步學習的記錄,若是感興趣的朋友能夠關注一下,一同加油~

我的公衆號:鹹魚正翻身
相關文章
相關標籤/搜索