簡體   English   中英

如何在Android中使用Dagger2輕松注入活動對象?

[英]How to use Dagger2 in Android to inject activity objects easier?

在Android上,使用Dagger2時,我必須在每個使用apiService活動上調用以下行:

@Inject
public ApiService apiService;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    DaggerApiComponent.builder()
                      .activityModule(new ActivityModule(this))
                      .build()
                      .inject(this);

    //...
}

如何將其總結為:

DaggerApiComponent.builder()
                  .activity(this)
                  .build()
                  .inject(this);

甚至更簡單一些:

MyApplication.injectApiService(this);

如何在我的活動中更改組件和模塊以使用帶有較少復制粘貼代碼的Dagger2?

這是我的ApiComponent

@Singleton
@Component(modules = ApiModule.class)
public interface ApiComponent {

    void inject(MainActivity activity);
    void inject(...
}

這是ApiModule

@Module(includes = {RetrofitModule.class, ActivityModule.class})
public class ApiModule {

    @Singleton
    @Provides
    public static ApiService provideApiService(Activity activity) {
        //...
    }
}

ActivityModule

@Module
public class ActivityModule {

    private final Activity context;

    public ActivityModule(Activity context) {
        this.context = context;
    }

    @Singleton
    @Provides
    public Activity provideActivityContext() {
        return context;
    }
}

您可以使用Android Activity注入器,其用法在此處進行了詳細說明

這種“ DI”的方法有兩個問題:

  • 就像OP所說的那樣:我們需要在需要注射的任何地方復制並粘貼該樣板,這既繁瑣又難於重構。
  • 被注入者(例如Activity )不應該知道@Inject實例來自哪里,它關心的只是“嘿,給我一個實例”。

為了解決上述問題, dagger.android進行了救援。

  1. 為每個組件創建AndroidInjector
// App component
@Singleton
@Component(
    modules = [
        AndroidSupportInjectionModule::class, // build-in module
        ActivityBindingModule::class,            
        AppModule::class
    ]
)
interface AppComponent : AndroidInjector<MainApplication> {
    // we need to bind `MainApplication` instance to this component,
    // so we have a builder here.
    @Component.Builder
    abstract class Builder : AndroidInjector.Builder<MainApplication>()
}
// Each controller (e.g. `Activity` / `Fragment` / `Service`) subcomponents
@Module
abstract class ActivityBindingModule {
    // will generate a FooActivitySubcomponent under ActivityBindingModule's component
    @ActivityScoped
    @ContributesAndroidInjector(modules = [FooModule::class])
    internal abstract fun fooActivity(): FooActivity

    @ActivityScoped
    @ContributesAndroidInjector(modules = [BarModule::class])
    internal abstract fun barActivity(): BarActivity
}
  1. 連接您的AndroidInjector ,以便它可以使用步驟1中提供的注射器為我們進行注射。
// App component
class MainApplication : DaggerApplication() {

    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.builder().create(this)
    }
}
// Each controller subcomponents
class FooActivity : DaggerAppCompatActivity() {
    @Inject lateinit var foo: Foo

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState) 
        // no need to call inject() here anymore!
        foo.doSth()
    }
}

舉一個具體的例子:檢查出iosched

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM