You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dagger 2.11在Fragment注入Retrofit遇阻及架构疑问求助

解决Fragment中Dagger 2.11+ Retrofit注入问题及架构困惑

问题1:不用DaggerFragment实现Fragment注入

首先你完全不用被迫把BaseFragment改成DaggerFragment,问题出在注入时机和全局配置上,咱们一步步修正:

  1. 先搞定Application和Activity的注入基础配置

    • 你的Application需要继承DaggerApplication,或者手动实现HasActivityInjector来提供Activity的注入器:
      class MyApp : Application(), HasActivityInjector {
          @Inject lateinit var dispatchingActivityInjector: DispatchingAndroidInjector<Activity>
      
          override fun onCreate() {
              super.onCreate()
              DaggerAppComponent.create().inject(this)
          }
      
          override fun activityInjector(): AndroidInjector<Activity> {
              return dispatchingActivityInjector
          }
      }
      
    • 宿主Activity要实现HasFragmentInjector,并注入Fragment的分发注入器,这样Dagger才能识别并注入Fragment:
      class MainActivity : AppCompatActivity(), HasFragmentInjector {
          @Inject lateinit var dispatchingFragmentInjector: DispatchingAndroidInjector<Fragment>
      
          override fun onCreate(savedInstanceState: Bundle?) {
              AndroidInjection.inject(this)
              super.onCreate(savedInstanceState)
              setContentView(R.layout.activity_main)
          }
      
          override fun fragmentInjector(): AndroidInjector<Fragment> {
              return dispatchingFragmentInjector
          }
      }
      
  2. 修正Fragment的注入时机
    你当前的onAttach重载写法混乱了,应该统一在onAttach(Context)中调用注入,并且放在super.onAttach(context)之前执行。修改你的BaseFragment:

    open class BaseFragment : Fragment() {
        override fun onAttach(context: Context) {
            AndroidInjection.inject(this)
            super.onAttach(context)
        }
    }
    

    这样HomeFragment继承后会自动在附着时完成注入,不用重复写注入逻辑,你之前同时注入activity和自身的操作完全没必要,反而会引发问题。

  3. 把HomeFragment关联到Dagger组件
    你需要通过@ContributesAndroidInjector告诉Dagger如何注入这个Fragment。比如创建一个Activity关联的Module:

    @Module
    abstract class ActivityModule {
        @ContributesAndroidInjector
        abstract fun contributeMainActivity(): MainActivity
    
        @ContributesAndroidInjector
        abstract fun contributeHomeFragment(): HomeFragment
    }
    

    然后在AppComponent中引入这个Module和你的Retrofit提供Module:

    @Singleton
    @Component(modules = [AndroidInjectionModule::class, ActivityModule::class, RetrofitModule::class])
    interface AppComponent {
        fun inject(app: MyApp)
    }
    

    这里的RetrofitModule是提供Retrofit单例的类,比如:

    @Module
    class RetrofitModule {
        @Provides
        @Singleton
        fun provideRetrofit(): Retrofit {
            return Retrofit.Builder()
                .baseUrl("https://your-api-base-url.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .build()
        }
    }
    

问题2:是否需要为每个Activity单独创建Module和Component?

完全不用手动为每个Activity写Component!Dagger 2.11引入的@ContributesAndroidInjector就是为了简化这个流程:

  • 如果多个Activity依赖逻辑相似:可以共用全局Module,甚至在@ContributesAndroidInjector中不指定专属Module,直接复用Retrofit这类全局单例依赖。
  • 如果Activity有独特依赖需求:再为它单独创建一个Module,通过@ContributesAndroidInjector(modules = [XXXActivityModule::class])关联,这样该Activity的自动生成Subcomponent会同时包含全局依赖和专属依赖。

简单说,@ContributesAndroidInjector会帮你自动生成对应的Subcomponent,你只需要通过抽象Module声明关联关系就行,既保证架构清晰,又减少重复代码。

最后简化你的HomeFragment,去掉冗余代码:

class HomeFragment : BaseFragment() {
    @Inject lateinit var retrofit: Retrofit

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        // 此时retrofit已被正确注入
        println("----Retrofit----"+retrofit.baseUrl())
        return inflater.inflate(R.layout.fragment_home, container, false)
    }
}

内容的提问来源于stack exchange,提问作者vishal sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:00:41