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