本文主要阐述dagger-android库的简明用法,帮助小白入门哈,其他重要概念,请参考其他大神的BLOG。
官方指南
https://dagger.dev/dev-guide/android.html
依赖
//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类
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写上
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
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
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>{ }
}
模块的内容
package com.example.daggerandroid;
import dagger.Module;
import dagger.Provides;
/**
* Author by linrh , Email ruihanl@126.com, Date on 2019/8/30 0030.
* 最终实际的module
*/
@Module
public class PicModule {
@Provides
Pic getPic(){
return new Pic();
}
}
最后在Activity中这样调用。
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都放在里面
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);
}
然后再统一初始化就可以
@Singleton
@Component(modules = {
UserModule.class,
ActivityModule.class,
// MainActivityModule.class,
// SecondActivityModule.class,
AndroidSupportInjectionModule.class})
public interface YourApplicationComponent {
void inject(YourApplication application);
}