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

如何通过Compose与Hilt在ViewModel间共享实例且随指定VM销毁

实现方案:基于Hilt自定义作用域+Subcomponent

核心思路是创建一个与ViewModel1生命周期绑定的自定义作用域,将Class1实例限定在此作用域内,ViewModel2通过依赖该作用域的实例实现共享,ViewModel1销毁时作用域内的实例随之销毁。

1. 定义自定义作用域注解

用于标记与ViewModel1生命周期绑定的实例范围:

@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class ViewModel1Scope

2. 创建自定义Subcomponent

这个Subcomponent作为自定义作用域的载体,负责提供Class1实例:

@ViewModel1Scope
@Subcomponent
interface ViewModel1Subcomponent {
    // 暴露Class1实例供外部依赖
    fun getClass1(): Class1

    // Subcomponent工厂,用于创建实例
    @Subcomponent.Factory
    interface Factory {
        fun create(): ViewModel1Subcomponent
    }
}

3. 在AppComponent中声明Subcomponent

让Hilt能够创建该Subcomponent的工厂实例:

@Singleton
@Component(modules = [/* 你的其他模块 */])
interface AppComponent {
    // 提供Subcomponent的工厂
    fun viewModel1SubcomponentFactory(): ViewModel1Subcomponent.Factory
}

4. 绑定Class1到自定义作用域

创建Module将Class1实例与ViewModel1Scope绑定:

@Module
@InstallIn(ViewModel1Subcomponent::class)
object Class1Module {
    @Provides
    @ViewModel1Scope
    fun provideClass1(): Class1 {
        return Class1()
    }
}

5. ViewModel1持有Subcomponent实例

ViewModel1通过注入Subcomponent工厂创建实例,并持有Class1:

class ViewModel1 @ViewModelInject constructor(
    private val subcomponentFactory: ViewModel1Subcomponent.Factory
) : ViewModel() {
    // 创建并持有Subcomponent实例,其生命周期与ViewModel1绑定
    private val subcomponent = subcomponentFactory.create()
    // 暴露共享的Class1实例
    val sharedClass1 = subcomponent.getClass1()

    override fun onCleared() {
        super.onCleared()
        // ViewModel1销毁时,subcomponent被回收,Class1实例也会随之销毁
    }
}

6. ViewModel2共享Class1实例

ViewModel2通过ViewModelProvider获取ViewModel1实例,进而拿到共享的Class1:

class ViewModel2 @ViewModelInject constructor(
    private val viewModelProvider: ViewModelProvider
) : ViewModel() {
    // 通过ViewModelProvider获取ViewModel1实例,确保同一作用域下拿到的是同一个实例
    val sharedClass1: Class1 by lazy {
        viewModelProvider.get(ViewModel1::class.java).sharedClass1
    }
}

关键说明

  • 自定义作用域ViewModel1Scope确保Class1实例仅在ViewModel1的生命周期内存在,ViewModel1销毁时,持有的Subcomponent被回收,Class1实例也会被GC清理。
  • 完全规避了@SingletonComponent或@ActivityRetainedComponent的使用,仅基于ViewModel生命周期实现共享与销毁逻辑。
  • 借助ViewModelProvider的特性,在同一个ViewModelStoreOwner(如Activity/Fragment)下,ViewModel1始终是单例实例,保证ViewModel2能拿到同一个Class1对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 23:31:34