我如何要求在Android碎片和服务中注入



我正在关注本教程,将dagger2添加到我的Android项目中。

进行设置并创建模块和组件后,我可以在这样的活动中添加依赖项:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_account);
    ButterKnife.bind(this);
    ((AppController) getApplication()).getNetComponent().inject(this);
}

我在如何将依赖性注入片段和意图方面正在挣扎?

public class FragmentBrandList extends ListFragment {
}

在此类中,我应该在哪种@Override方法中请求注入,该代码将是什么?

在这个类中

在片段内呼叫注射的正确位置是onAttach(Context context)。这在中说明了dagger2用户指南的部分

@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用户指南这样的解释:

至关重要的是,在活动中super.oncreate()之前调用androidIxptive.Indignt(),因为呼叫超级会在配置变化过程中附加上一个活动实例的片段,从而向片段注入片段。为了使片段注入成功,必须已经注入活动。对于errorprone的用户,在super.oncreate()。

换句话说:

  1. 活动 super.onCreate()从上一个实例
  2. 调用call re-Attaches片段
  3. super呼叫要重新注射的原因片段(因为片段被注入onAttach中)
  4. 片段应在注入活动后注入片段,因此在调用super.onCreate()之前请在活动中注入。

您可以随时查看com.google.dagger:dagger-android类(如DaggerFragmentDaggerService)的相关源代码来检查何处。请参阅此处的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的活动,片段和服务注入的演示项目。这是git:https://github.com/write2sv/androiddidagger2/tree/master/app/src/main/java/java/work/work/shaggy/shaggy/didemo

我使用 ((AppController) getActivity().getApplication()).getNetComponent().inject(this);

Fragment.onCreate()方法中。

((MyApp) context.getApplicationContext()).getApplicationComponent().inject(MyFragment.this);

我在片段的onAttach(Context context)中添加了此。

您实际上只需要为任何要注入的注射器方法即可。

@Singleton
@Component
public interface AppComponent {
    void inject(MainActivity activity);
    void inject(FragmentBrandList fragmentBrandList);
} 

您可以使用 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 }
)

块。您可以使用该语法添加尽可能多的模块。

希望这对您有帮助

最新更新