[英]How do I request injection in Android Fragments and Services?
我正在按照本教程將Dagger 2添加到我的Android項目中。
在設置並創建模塊和組件之后,我可以在Activity中添加依賴項,如下所示:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_account);
ButterKnife.bind(this);
((AppController) getApplication()).getNetComponent().inject(this);
}
我正在努力如何在Fragment和IntentService中注入依賴項?
public class FragmentBrandList extends ListFragment {
}
在這個類我應該請求注入@Override
方法,這將是什么代碼?
在這個類我應該使用@Override方法以及在片段中添加依賴項的代碼是什么?
在Fragment中調用注入的正確位置是onAttach(Context context)
。 這是在哪里聲明注入匕首2用戶指南的部分在這里
@Override
public void onAttach(Context context) {
((AppController) context.getApplicationContext()).getNetComponent().inject(this);
super.onAttach(context);
}
在服務中調用注入的正確位置是onCreate()
@Override
public void onCreate() {
((AppController) getApplication()).getNetComponent().inject(this);
super.onCreate();
}
請注意,在兩種情況下,注入請求都在調用super.onCreate()
。 Dagger用戶指南解釋如下:
在Activity中的super.onCreate()之前調用AndroidInjection.inject()是至關重要的,因為對super的調用會在配置更改期間附加前一個活動實例中的Fragments,而后者會注入Fragments。 為了使Fragment注入成功,必須已經注入了Activity。 對於ErrorProne的用戶,在super.onCreate()之后調用AndroidInjection.inject()是一個編譯器錯誤。
換一種說法:
super.onCreate()
調用重新附加來自先前實例的Fragments super
調用會導致片段被重新注入(因為片段是在onAttach
中注入的) super.onCreate()
之前請求在Activity中注入。 您可以通過查看com.google.dagger:dagger-android
類(如DaggerFragment
和DaggerService
的相關源代碼來查看注入DaggerService
。 在這里查看GitHub回購
對於您的具體示例,請確保已將新注入站點添加到NetComponent:
void inject(FragmentBrandList frag);
void inject(BrandListService service);
第1步:創建ApplicationModule
@Module
public class ApplicationModule {
private final DIApplication application;
public ApplicationModule(DIApplication application) {
this.application = application;
}
@Provides @Singleton
public DIApplication provideApplication() {
return application;
}
@Provides @Singleton
public DogModel provideDogModel() {
return new DogModelImpl("Scooby-doo");
}
}
第2步:創建ApplicationComponent:
@Singleton
@Component(modules = {ApplicationModule.class})
public interface ApplicationComponent {
void inject(DIApplication application);
void inject(BaseActivity activity);
void inject(BaseFragment fragment);
void inject(DogSyncService service);
}
第3步:創建DI類:
public class DependencyInjector {
private static ApplicationComponent applicationComponent;
public static void initialize(DIApplication diApplication) {
applicationComponent = DaggerApplicationComponent.builder()
.applicationModule(new ApplicationModule(diApplication))
.build();
}
public static ApplicationComponent applicationComponent() {
return applicationComponent;
}
private DependencyInjector(){}
}
最后一步:使用以下方式注入:
DependencyInjector.applicationComponent()
您的問題激發了我創建一個使用Dagger2顯示Activity,Fragment和Service注入的Demo項目。 這是git: https : //github.com/write2sv/AndroidDIDagger2/tree/master/app/src/main/java/work/shaggy/didemo
我使用((AppController) getActivity().getApplication()).getNetComponent().inject(this);
在Fragment.onCreate()
方法中。
您可以使用autodagger2來避免編寫所有樣板文件。 我經常使用這種架構:
的build.gradle
apt 'com.github.lukaspili.autodagger2:autodagger2-compiler:1.1'
compile 'com.github.lukaspili.autodagger2:autodagger2:1.1'
YourApp.java
@AutoComponent( modules = YourApp.YourAppModule.class )
public class YourApp extends Application {
private static YourApp instance;
private YourAppComponent component;
public YourAppComponent getComponent() {
return this.component;
}
@Override
public void onCreate() {
super.onCreate();
setupComponent();
}
private void setupComponent() {
component = DaggerYourAppComponent.builder()
.yourAppModule(new YourAppModule(instance))
.build();
}
@dagger.Module
public static class YourAppModule {
private YourApp app;
YourAppModule(YourAppApp application) {
this.app = application;
}
@Provides @AutoExpose(YourApp.class)
Application provideApplication() {
return app;
}
@Provides @AutoExpose(PoswalaApp.class)
Context provideContext() {
return app;
}
@Provides @AutoExpose(YourApp.class)
Retrofit provideApiAdapter() {
return ApiService.getServiceInstance();
}
}
}
YourActivity.java
@AutoComponent(
dependencies = YourApp.class,
modules = YourActivity.YourActivityModule.class
)
public class YourActivity extends BaseActivity implements YourActivityView {
private YourActivityComponent component;
@Inject MyPresenter presenter
// This is an abstract method from BaseActivity
@Override
protected void setupComponent(YourAppComponent appComponent) {
component = DaggerYourActivityComponent.builder()
.yourAppComponent(((YourApp) getApplication()).getComponent())
.yourActivityModule(new YourctivityModule(this))
.build();
}
@Override
protected MyPresenter getPresenter() {
return presenter;
}
@dagger.Module
public static class YourActivityModule {
private YourActivityView view;
YourActivityModule(YourActivityView view) {
this.view = view;
}
@Provides @AutoExpose(YourActivity.class)
YourActivityView provideView() {
return view;
}
// Your other dependencies
}
}
快速解釋:
您的應用程序模塊將具有“通用”依賴關系,但這樣您就可以實現為類使用多個模塊。 你只需要自定義
@AutoComponent(
dependencies = YourApp.class,
modules = { YourActivity.YourActivityModule.class, YourFragment.YourFragmentModule.class }
)
塊。 您可以使用該語法添加任意數量的模塊。
希望這對你有所幫助
你只需要為你要注入的任何東西包含注入方法。
@Singleton
@Component
public interface AppComponent {
void inject(MainActivity activity);
void inject(FragmentBrandList fragmentBrandList);
}
((MyApp) context.getApplicationContext()).getApplicationComponent().inject(MyFragment.this);
我在onAttach(Context context)
方法中添加了這個。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.