我正在尝试将活动依赖项注入片段演示者。 应用程序结构非常简单。
TabsActivity - viewpager
- TabFragment - 页面项
- [...]
TabsActivity 显示视图 TabsActivityModule - 提供 FragmentManager (例如)和 TabsActivity
的一些内容TabFragmentModule 提供 TabFragment 的内容。 每个 TabFragment 都有自己的 Presenter 。 Presenter 会注入 TabActivityModule 依赖项。
在我的情况下 - Presenter注入 FragmentManager
这是代码:
应用程序类
class App extends Application implements HasActivityInjector {
@Inject
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;
@Override
public AndroidInjector<Activity> activityInjector() {
return dispatchingAndroidInjector;
}
/*
blah blah creating app component onCreate() ...
DaggerAppComponent
.builder()
.context(this)
.build()
.inject(this);
*/
}
根应用程序组件
@Singleton
@Component(modules = {InjectorsModule.class})
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
Builder context(Context context);
AppComponent build();
}
void inject(App app);
}
这是android视图贡献者 InjectorsModule
@Module(includes = {AndroidSupportInjectionModule.class})
public abstract class InjectorsModule {
@ActivityScope
@ContributesAndroidInjector(modules = {TabsActivityModule.class})
abstract TabsActivity tabsActivityInjector();
}
活动 TabsActivityModule
@Module
public abstract class TabsActivityModule {
@Provides
@ActivityScope
public FragmentManager provideFragmentManager(TabsActivity activity) {
return activity.getFragmentManager();
}
@Provides @Named("activity")
@ActivityScope
public Context provideActivityContext(TabsActivity activity) {
return activity;
}
// Here contributes tab fragment
@FragmentScope
@ContributesAndroidInjector(modules = {TabFragmentModule.class})
public abstract TabFragment tabFragment();
}
片段 TabFragmentModule
@Module
public abstract class TabFragmentModule {
@Provides @Named("answer")
@FragmentScope
public int provideSomeInt() {
return 42;
}
}
最后,仅举例来说 - TabPresenter
public class TabPresenter {
@Inject @Named("answer") int mAnswer;
@Inject @Named("activity") mActivityContext;
@Inject FragmentManager mFragmentManager;
@Inject
public TabPresenter() {}
public void doNothingWithAnswerAndContextAndFragmentManager() {
mAnswer *= 1;
}
}
在此之后,构建完成并成功。但是在运行时,我在片段注入时立即得到InvalidStateException:
onAttach(Activity activity) {
AndroidInjection.inject(this);
super.onAttach(activity);
}
异常堆栈跟踪:
FATAL EXCEPTION: main
Process: com.example.drive.dagger2new, PID: 3064
java.lang.RuntimeException:
Unable to start activity
ComponentInfo{com.example.drive.dagger2new/com.example.ui.TabsActivity}:
java.lang.IllegalStateException:
com.example.dagger.modules.main.TabsActivityModule must be set
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2680)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2741)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1488)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6169)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778)
Caused by: java.lang.IllegalStateException: com.example.dagger.modules.main.TabsActivityModule must be set
at com.example.dagger.components.DaggerAppComponent$TabsActivitySubcomponentBuilder.build(DaggerAppComponent.java:116)
at com.example.dagger.components.DaggerAppComponent$TabsActivitySubcomponentBuilder.build(DaggerAppComponent.java:106)
at dagger.android.AndroidInjector$Builder.create(AndroidInjector.java:68)
at dagger.android.DispatchingAndroidInjector.maybeInject(DispatchingAndroidInjector.java:79)
at dagger.android.DispatchingAndroidInjector.inject(DispatchingAndroidInjector.java:104)
at dagger.android.AndroidInjection.inject(AndroidInjection.java:61)
at com.example.base.BaseActivity.onCreate(BaseActivity.java:35)
at com.example.ui.TabsActivity.onCreate(TabsActivity.java:13)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2633)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2741)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1488)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6169)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778)
看了这个,但是,我只是忘了设置一些新的模块实例。但是,我不这样做,因为@ContributesAndroidInjector为我做了。 好的,当我查看生成的代码时,我看到 TabsActivitySubcomponentBuilder 没有TabsActivityModule的setter。
private final class TabsActivitySubcomponentBuilder
extends InjectorsModule_TabsActivityInjector.TabsActivitySubcomponent.Builder {
private TabsActivityModule tabsActivityModule;
private TabsActivity seedInstance;
@Override
public InjectorsModule_TabsActivityInjector.TabsActivitySubcomponent build() {
if (tabsActivityModule == null) {
// Exceptions throws here
throw new IllegalStateException(
TabsActivityModule.class.getCanonicalName() + " must be set");
}
if (seedInstance == null) {
throw new IllegalStateException(TabsActivity.class.getCanonicalName() + " must be set");
}
return new TabsActivitySubcomponentImpl(this);
}
// here we seeing setter for activity
@Override
public void seedInstance(TabsActivity arg0) {
this.seedInstance = Preconditions.checkNotNull(arg0);
}
// and for module??
}
最后, AndroidInjector.Builder 仅设置活动实例:
abstract class Builder<T> implements AndroidInjector.Factory<T> {
@Override
public final AndroidInjector<T> create(T instance) {
// here
seedInstance(instance);
// and here must be seedModule(module), but nothing
return build();
}
/**
* Provides {@code instance} to be used in the binding graph of the built {@link
* AndroidInjector}. By default, this is used as a {@link BindsInstance} method, but it may be
* overridden to provide any modules which need a reference to the activity.
*
* <p>This should be the same instance that will be passed to {@link #inject(Object)}.
*/
@BindsInstance
public abstract void seedInstance(T instance);
/** Returns a newly-constructed {@link AndroidInjector}. */
public abstract AndroidInjector<T> build();
}
也许我不懂东西? 谢谢!
答案 0 :(得分:3)
好的,经过官方dagger repo的一些研究和帮助后,我找到了解决方案:所有子组件抽象模块必须仅提供静态 @Provides 方法,或仅使用构造函数注入,因为没有办法设置模块实例。
答案 1 :(得分:0)
我有同样的错误,经过研究我发现错误导入模块 导入是这样的
import com.google.android.datatransport.runtime.dagger.Module
但应该是
import dagger.Module