如何扩展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
相关产品推荐
相关产品推荐

