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

如何扩展Google Android架构Dagger示例?依赖注入问题咨询

解决Dagger-Android中的两个常见需求:非Fragment类使用Presenter + 添加OkHttp网络模块

我完全懂dagger-android刚上手时的混乱感——它的组件绑定、注入逻辑确实比普通Dagger多了不少弯弯绕。下面针对你的两个需求,一步步给你拆解解决方案:


一、在非Fragment类中使用Presenter

首先要明确:Dagger的核心是依赖注入,不管是Fragment、Activity还是普通类,只要能让Dagger管理它的实例,就能注入Presenter。这里分两种常见场景:

1. 你的非Fragment类是可被Dagger创建的普通类

假设你有个自定义类TaskManager,需要用到ToDoPresenter:

  • 第一步:确保你的Presenter是可注入的。要么给Presenter加@Inject构造函数,要么在Module中提供它的实例:
// 示例Presenter:用@Inject构造函数让Dagger自动创建
class ToDoPresenter @Inject constructor(
    private val taskRepository: TaskRepository // 如果有其他依赖,也要确保依赖可注入
) {
    // 你的Presenter逻辑
}
  • 第二步:让你的非Fragment类通过构造函数注入Presenter:
class TaskManager @Inject constructor(
    private val toDoPresenter: ToDoPresenter
) {
    // 直接用toDoPresenter做业务逻辑
    fun handleTaskUpdate(taskId: String) {
        toDoPresenter.updateTaskStatus(taskId)
    }
}
  • 第三步:在需要使用TaskManager的地方(比如Activity/Application)注入它:
class ExampleActivity : AppCompatActivity() {
    @Inject
    lateinit var taskManager: TaskManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // Dagger-Android中,Activity的注入必须先调用这行
        AndroidInjection.inject(this)
        setContentView(R.layout.activity_example)
        
        // 现在可以直接使用taskManager里的Presenter了
        taskManager.handleTaskUpdate("task_001")
    }
}

2. 你的非Fragment类不能修改构造函数(比如第三方类)

如果是这种情况,你需要在Module中手动提供这个类的实例,同时把Presenter作为依赖传进去:

@Module
class CustomClassModule {
    @Provides
    fun provideThirdPartyClass(presenter: ToDoPresenter): ThirdPartyClass {
        return ThirdPartyClass(presenter)
    }
}

然后把这个Module加到对应的Component中(比如AppComponent或者ActivityComponent),之后就可以像普通注入一样使用ThirdPartyClass了。


二、添加提供OkHttp客户端的网络模块

全局的OkHttp客户端属于应用级别的单例依赖,我们需要创建一个独立的NetworkModule,并把它加入AppComponent:

1. 创建NetworkModule

@Module
class NetworkModule {
    // 提供单例的OkHttpClient
    @Provides
    @Singleton
    fun provideOkHttpClient(): OkHttpClient {
        return OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            // 可以添加拦截器、缓存等配置
            .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
            .build()
    }

    // 如果需要Retrofit,也可以在这里一并提供(可选)
    @Provides
    @Singleton
    fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder()
            .baseUrl("https://your-api-domain.com/")
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }
}

2. 将NetworkModule加入AppComponent

打开你的AppComponent接口,把NetworkModule添加到modules列表中:

@Singleton
@Component(
    modules = [
        AndroidInjectionModule::class,
        ApplicationModule::class,
        ActivityBindingModule::class,
        NetworkModule::class // 新增这一行
    ]
)
interface AppComponent : AndroidInjector<ToDoApplication> {
    @Component.Factory
    interface Factory {
        fun create(@BindsInstance application: Application): AppComponent
    }
}

3. 在需要的地方注入OkHttp

现在任何需要OkHttpClient的类,都可以直接通过@Inject获取:

class TaskRepository @Inject constructor(
    private val okHttpClient: OkHttpClient
) {
    // 用okHttpClient发起网络请求
    fun fetchTasks(): Call<List<Task>> {
        val request = Request.Builder()
            .url("https://your-api-domain.com/tasks")
            .build()
        return okHttpClient.newCall(request)
    }
}

一些额外提醒

  • 如果你用的是Kotlin,记得开启kapt插件,Dagger需要它来生成注入代码
  • 所有@Singleton注解的依赖,必须放在AppComponent级别,不能放在Activity/Fragment的Component中
  • 如果你遇到注入失败的问题,可以先检查:
    • 类的构造函数是否加了@Inject
    • Module是否正确加入了Component
    • 注入的地方是否调用了AndroidInjection.inject(this)(Activity/Fragment)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:08:40