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

Dagger中如何无需为每个Activity单独建模块通用实现进度工具?

解决Dagger中多Activity复用ProgressUtil的通用方案

嘿,很高兴你觉得Dagger好用!针对你遇到的多Activity复用ProgressUtil的问题,确实有很简洁的通用解法,不用为每个Activity单独创建模块。咱们来一步步梳理:

先指出你现有代码的问题

你在ActivityModules里写的@Provides方法会导致Dagger混淆——因为你有多个Activity(MainActivity、PostsActivity),Dagger无法确定要注入哪个Activity实例,编译时肯定会报错。而且其实这个方法是多余的,因为你的ProgressUtil已经用@Inject标记了构造函数,Dagger可以自动处理它的实例化。

通用解决方案步骤

1. 给ProgressUtil添加Activity级别的作用域

给ProgressUtil加上@ActivityScope注解,确保它的生命周期和所属Activity完全绑定,每个Activity都会得到自己独立的ProgressUtil实例,避免跨Activity的状态混乱:

// 如果你用的是原生Dagger,需要先自定义ActivityScope:
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class ActivityScope

@ActivityScope
class ProgressUtil @Inject constructor(val context: Activity) {
    var dialog: Dialog? = null

    fun show() {
        hide()
        dialog = Dialog(context)
        dialog?.let {
            it.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
            it.setContentView(R.layout.progress_dialog)
            it.setCancelable(false)
            it.show()
        }
    }

    fun hide() {
        dialog?.let {
            if (it.isShowing) {
                it.dismiss()
            }
        }
    }
}

2. 清理ActivityModules中的冗余代码

删掉ActivityModules里那个手动创建ProgressUtil的@Provides方法,让@ContributesAndroidInjector自动为每个Activity生成子组件:

@Module
abstract class ActivityModules {
    @ContributesAndroidInjector
    abstract fun contributeMainActivity() : MainActivity

    @ContributesAndroidInjector
    abstract fun contributePostsActivity() : PostsActivity

    // 移除下面这个多余的方法
    // @Provides
    // fun progressUtilMainActivity(activity: Activity): ProgressUtil = ProgressUtil(activity)
}

3. 在Activity中注入并使用ProgressUtil

在需要使用的Activity中,直接通过@Inject注入ProgressUtil即可。如果你有多个Activity都要用到,建议创建一个基础Activity来统一处理注入,减少重复代码:

基础Activity示例

abstract class BaseActivity : AppCompatActivity() {
    @Inject
    lateinit var progressUtil: ProgressUtil

    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this) // 初始化Dagger注入
        super.onCreate(savedInstanceState)
    }
}

具体Activity示例

class MainActivity : BaseActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 直接使用progressUtil
        button.setOnClickListener {
            progressUtil.show()
            // 模拟耗时操作后隐藏
            Handler(Looper.getMainLooper()).postDelayed({
                progressUtil.hide()
            }, 2000)
        }
    }
}

为什么这样可行?

  • @ContributesAndroidInjector会为每个Activity生成独立的Dagger子组件,这个子组件可以自动提供当前Activity的实例作为依赖。
  • 你的ProgressUtil构造函数用@Inject标记,Dagger会自动把当前Activity的实例注入进去,生成对应Activity的ProgressUtil实例。
  • @ActivityScope保证每个Activity的ProgressUtil实例只在该Activity生命周期内有效,避免内存泄漏或状态冲突。

这样一来,所有Activity都可以复用同一个ProgressUtil类,无需为每个Activity单独编写模块,完全符合你的需求!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:26:40