最新Dagger-Android使用指南

本文主要阐述dagger-android库的简明用法,帮助小白入门哈,其他重要概念,请参考其他大神的BLOG。

官方指南

https://dagger.dev/dev-guide/android.html

依赖

1
2
3
4
5
6
7
8
//dagger相关
    def dagger = "2.27"
    implementation "com.google.dagger:dagger:$dagger"
    annotationProcessor "com.google.dagger:dagger-compiler:$dagger"

    implementation "com.google.dagger:dagger-android:$dagger"
    implementation "com.google.dagger:dagger-android-support:$dagger" // if you use the support libraries
    annotationProcessor "com.google.dagger:dagger-android-processor:$dagger"

先看下最后要实现的效果
在这里插入图片描述
通过一句话的inject, 完成注入,不用写dagger的模板代码。

接下来看看是怎么写

修改Application类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.example.daggerandroid;

import android.app.Application;

import javax.inject.Inject;

import dagger.android.AndroidInjector;
import dagger.android.DispatchingAndroidInjector;
import dagger.android.HasAndroidInjector;

public class YourApplication extends Application implements HasAndroidInjector {
    @Inject
    DispatchingAndroidInjector<Object> dispatchingAndroidInjector;

    @Override
    public void onCreate() {
        super.onCreate();
        DaggerYourApplicationComponent.create()
                .inject(this);
    }

    @Override
    public AndroidInjector<Object> androidInjector() {
        return dispatchingAndroidInjector;
    }
}

在创建相应的component,这里指明了需要实例化的Module,比如MainActivityModule,并且要把AndroidSupportInjectionModule写上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.example.daggerandroid;


import javax.inject.Singleton;

import dagger.Component;
import dagger.android.support.AndroidSupportInjectionModule;

@Singleton
@Component(modules = {
        MainActivityModule.class,
        AndroidSupportInjectionModule.class})
public interface YourApplicationComponent {
    void inject(YourApplication application);

}

实现MainActivityModule

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.example.daggerandroid;


import dagger.Binds;
import dagger.Module;
import dagger.android.AndroidInjector;
import dagger.multibindings.ClassKey;
import dagger.multibindings.IntoMap;

/**
 * 指定含有下级的模块
 */
@Module( subcomponents = MainActivitySubcomponent.class)
public abstract class MainActivityModule {
    @Binds
    @IntoMap
    @ClassKey(MainActivity.class)
    abstract AndroidInjector.Factory<?>  bindYourAndroidInjectorFactory(MainActivitySubcomponent.Factory factory);

}

实现MainActivitySubcomponent,此处指明包含的picModule

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.example.daggerandroid;

import dagger.Subcomponent;
import dagger.android.AndroidInjection;
import dagger.android.AndroidInjector;

/**
 * 包含有子模块
 */
@Subcomponent(modules = PicModule.class)
public interface MainActivitySubcomponent extends AndroidInjector<MainActivity> {

    @Subcomponent.Factory
    public interface Factory extends AndroidInjector.Factory<MainActivity>{ }


}

模块的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.example.daggerandroid;



import dagger.Module;
import dagger.Provides;

/**
 * Author by linrh , Email [email protected], Date on 2019/8/30 0030.
 * 最终实际的module
 */
@Module
public class PicModule {

    @Provides
    Pic getPic(){
        return new Pic();
    }
}

最后在Activity中这样调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.example.daggerandroid;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import javax.inject.Inject;

import dagger.android.AndroidInjection;

public class MainActivity extends AppCompatActivity {

    @Inject
    Pic pic;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        AndroidInjection.inject(this);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        pic.getUrl();
    }
}

以上是最基本的用法


举一反三

可以新建一个ActivityModule,把所有的module都放在里面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.example.daggerandroid;

import dagger.Binds;
import dagger.Module;
import dagger.android.AndroidInjector;
import dagger.multibindings.ClassKey;
import dagger.multibindings.IntoMap;


@Module(subcomponents = {
        MainActivitySubcomponent.class,
        SecondActivitySubcompont.class})
public abstract class ActivityModule {
   
    @Binds
    @IntoMap
    @ClassKey(MainActivity.class)
    abstract AndroidInjector.Factory<?>  bindMain(MainActivitySubcomponent.Factory factory);


    @Binds
    @IntoMap
    @ClassKey(SecondActivity.class)
    abstract AndroidInjector.Factory<?>  bindSecond(SecondActivitySubcompont.Factory factory);
   
}

然后再统一初始化就可以

1
2
3
4
5
6
7
8
9
10
11
@Singleton
@Component(modules = {
        UserModule.class,
        ActivityModule.class,
//        MainActivityModule.class,
//        SecondActivityModule.class,
        AndroidSupportInjectionModule.class})
public interface YourApplicationComponent {
    void inject(YourApplication application);

}