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
相关产品推荐
相关产品推荐

