gpt4 book ai didi

dagger-2 - Dagger 2.11 ContributesAndroidInjector Singleton依赖注入(inject)失败

转载 作者:行者123 更新时间:2023-12-03 06:23:42 26 4
gpt4 key购买 nike

我正在探索 Dagger 2.11 中的新 dagger.android。我希望不必创建像 @PerActivity 这样的自定义范围注释。到目前为止,我能够执行以下操作:

1) 定义应用程序范围单例并将它们注入(inject)到事件中。

2) 定义 Activity 范围非单例依赖项,并使用 @ContributesAndroidInjector 将它们注入(inject)到其 Activity 中

我不知道如何让应用程序范围单例和事件范围非单例使用它。

在下面的示例中,我希望我的事件范围 MyActivityDependencyAMyActivityDependencyB 能够访问单例 MyActivityService

以下设置结果:

Error:(24, 3) error: com.example.di.BuildersModule_BindMyActivity.MyActivitySubcomponent (unscoped) may not reference scoped bindings: @Singleton @Provides com.example.MyActivityService com.example.MyActivitySingletonsModule.provideMyActivityService()

这是我的设置。请注意,我定义了单独的 MyActivitySingletonsModuleMyActivityModule 因为我无法在同一模块文件中混合单例和非单例依赖项。

@Module
public abstract class BuildersModule {
@ContributesAndroidInjector(modules = {MyActivitySingletonsModule.class, MyActivityModule.class})
abstract MyActivity bindMyActivity();
}
}

@Module
public abstract class MyActivityModule {
@Provides
MyActivityDependencyA provideMyActivityDependencyA(MyActivityService myActivityService){
return new MyActivityDependencyA(myActivityService);
}
@Provides
MyActivityDependencyB provideMyActivityDependencyB(MyActivityService myActivityService) {
return new MyActivityDependencyB(myActivityService);
}
}

@Module
public abstract class MyActivitySingletonsModule {
@Singleton
@Provides
MyActivityService provideMyActivityService() {
return new MyActivityService();
}
}

@Singleton
@Component(modules = {
AndroidSupportInjectionModule.class,
AppModule.class,
BuildersModule.class})

public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder application(App application);
AppComponent build();
}
void inject(App app);
}

是否可以在不定义自定义范围注释的情况下完成我想做的事情?

提前致谢!

最佳答案

为什么要避免自定义范围? Dagger 2.10+ 中引入的新 dagger.android 依赖注入(inject)框架仍然需要自定义作用域。

"My understanding is @ContributesAndroidInjector removes the need for custom annotation and I was able to prove it by using non-singletons defined in the activity scope without any issues."

@ContributesAndroidInjector(在 v2.11 中提供)不会消除对自定义范围的需要。它只是取代了声明 @Subcomponent 类的需要,而这些类不使用 @Subcomponent.Builder 在运行时注入(inject)组件所需的依赖项。看一下 official dagger.android user guide about @ContributesAndroidInjector 中的以下代码片段;

"Pro-tip: If your subcomponent and its builder have no other methods or supertypes than the ones mentioned in step #2, you can use @ContributesAndroidInjector to generate them for you. Instead of steps 2 and 3, add an abstract module method that returns your activity, annotate it with @ContributesAndroidInjector, and specify the modules you want to install into the subcomponent. If the subcomponent needs scopes, apply the scope annotations to the method as well."

@ActivityScope
@ContributesAndroidInjector(modules = { /* modules to install into the subcomponent */ })
abstract YourActivity contributeYourActivityInjector();

这里的关键是“如果子组件需要作用域,请将作用域注释也应用到方法中。”

查看以下代码,了解如何使用 @Singleton@PerActivity@PerFragment >@PerChildFragment 使用新的 dagger.android 注入(inject)框架自定义作用域。

// Could also extend DaggerApplication instead of implementing HasActivityInjector
// App.java
public class App extends Application implements HasActivityInjector {

@Inject
AppDependency appDependency;

@Inject
DispatchingAndroidInjector<Activity> activityInjector;

@Override
public void onCreate() {
super.onCreate();
DaggerAppComponent.create().inject(this);
}

@Override
public AndroidInjector<Activity> activityInjector() {
return activityInjector;
}
}

// AppModule.java
@Module(includes = AndroidInjectionModule.class)
abstract class AppModule {
@PerActivity
@ContributesAndroidInjector(modules = MainActivityModule.class)
abstract MainActivity mainActivityInjector();
}

// AppComponent.java
@Singleton
@Component(modules = AppModule.class)
interface AppComponent {
void inject(App app);
}

// Could also extend DaggerActivity instead of implementing HasFragmentInjector
// MainActivity.java
public final class MainActivity extends Activity implements HasFragmentInjector {

@Inject
AppDependency appDependency; // same object from App

@Inject
ActivityDependency activityDependency;

@Inject
DispatchingAndroidInjector<Fragment> fragmentInjector;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);

if (savedInstanceState == null) {
addFragment(R.id.fragment_container, new MainFragment());
}
}

@Override
public final AndroidInjector<Fragment> fragmentInjector() {
return fragmentInjector;
}
}

// MainActivityModule.java
@Module
public abstract class MainActivityModule {
@PerFragment
@ContributesAndroidInjector(modules = MainFragmentModule.class)
abstract MainFragment mainFragmentInjector();
}

// Could also extend DaggerFragment instead of implementing HasFragmentInjector
// MainFragment.java
public final class MainFragment extends Fragment implements HasFragmentInjector {

@Inject
AppDependency appDependency; // same object from App

@Inject
ActivityDependency activityDependency; // same object from MainActivity

@Inject
FragmentDependency fragmentDepency;

@Inject
DispatchingAndroidInjector<Fragment> childFragmentInjector;

@SuppressWarnings("deprecation")
@Override
public void onAttach(Activity activity) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Perform injection here before M, L (API 22) and below because onAttach(Context)
// is not yet available at L.
AndroidInjection.inject(this);
}
super.onAttach(activity);
}

@Override
public void onAttach(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Perform injection here for M (API 23) due to deprecation of onAttach(Activity).
AndroidInjection.inject(this);
}
super.onAttach(context);
}

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.main_fragment, container, false);
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);

if (savedInstanceState == null) {
addChildFragment(R.id.child_fragment_container, new MainChildFragment());
}
}

@Override
public final AndroidInjector<Fragment> fragmentInjector() {
return childFragmentInjector;
}
}

// MainFragmentModule.java
@Module
public abstract class MainFragmentModule {
@PerChildFragment
@ContributesAndroidInjector(modules = MainChildFragmentModule.class)
abstract MainChildFragment mainChildFragmentInjector();
}

// MainChildFragment.java
public final class MainChildFragment extends Fragment {

@Inject
AppDependency appDependency; // same object from App

@Inject
ActivityDependency activityDependency; // same object from MainActivity

@Inject
FragmentDependency fragmentDepency; // same object from MainFragment

@Inject
ChildFragmentDependency childFragmentDepency;

@Override
public void onAttach(Context context) {
AndroidInjection.inject(this);
super.onAttach(context);
}

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.main_child_fragment, container, false);
}
}

// MainChildFragmentModule.java
@Module
public abstract class MainChildFragmentModule {
}

// PerActivity.java
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerActivity {
}

// PerFragment.java
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerFragment {
}

// PerChildFragment.java
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerChildFragment {
}

// AppDependency.java
@Singleton
public final class AppDependency {
@Inject
AppDependency() {
}
}

// ActivityDependency.java
@PerActivity
public final class ActivityDependency {
@Inject
ActivityDependency() {
}
}

// FragmentDependency.java
@PerFragment
public final class FragmentDependency {
@Inject
FragmentDependency() {
}
}

// ChildFragmentDependency.java
@PerChildFragment
public final class ChildFragmentDependency {
@Inject
ChildFragmentDependency() {
}
}

有关使用 @ContributesAndroidInjector 和上述自定义范围的完整 dagger.android 2.11 设置指南,请阅读 this article .

关于dagger-2 - Dagger 2.11 ContributesAndroidInjector Singleton依赖注入(inject)失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45226467/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com