簡體   English   中英

如何在Android片段和服務中請求注入?

[英]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()是一個編譯器錯誤。

換一種說法:

  1. Activity super.onCreate()調用重新附加來自先前實例的Fragments
  2. 這個super調用會導致片段被重新注入(因為片段是在onAttach中注入的)
  3. 應該在注入Activity之后注入片段,因此在調用super.onCreate()之前請求在Activity中注入。

您可以通過查看com.google.dagger:dagger-android類(如DaggerFragmentDaggerService的相關源代碼來查看注入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.

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