Jetpack Compose+MVVM架构中数据源获取Context的推荐方案
在Jetpack Compose MVVM架构中,数据源获取Context的优雅方案
你完全不需要通过View→ViewModel→Repository→DataSource的链路传递Context,这种方式不仅冗余,还会让ViewModel依赖Android框架,破坏其平台无关性(不利于单元测试)。以下是两种推荐的优雅实现方式:
1. 依赖注入(推荐):通过Hilt提供Application Context
Application Context的生命周期与应用一致,不会引发内存泄漏,是数据源类的理想选择。借助Hilt可以轻松将其注入到数据源层,无需手动传递。
步骤示例:
定义数据源类
class MyFileSource(private val app: Application) { fun saveDataToFile(content: String) { val targetFile = File(app.filesDir, "user_data.txt") targetFile.writeText(content) } }
配置Hilt依赖注入模块
@Module @InstallIn(SingletonComponent::class) object AppModule { // 提供Application实例 @Provides fun provideApplication(@ApplicationContext app: Application): Application = app // 提供数据源实例 @Provides fun provideMyFileSource(app: Application): MyFileSource = MyFileSource(app) // 提供Repository实例 @Provides fun provideMyRepository(dataSource: MyFileSource): MyRepository = MyRepository(dataSource) }
ViewModel与Activity层使用
// ViewModel仅依赖Repository,完全不涉及Context class MyViewModel(private val repository: MyRepository) : ViewModel() { fun saveUserContent(content: String) { repository.saveData(content) } } // Activity中通过Hilt获取ViewModel class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { val viewModel: MyViewModel = hiltViewModel() // 调用ViewModel方法完成文件操作 } } }
2. 自定义Application类(无依赖注入时的备选)
如果暂时不想引入依赖注入框架,可以通过自定义Application类暴露全局的Application Context。这种方式简单直接,但灵活性不如依赖注入(不利于单元测试时替换实现)。
步骤示例:
自定义Application类
class MyApp : Application() { companion object { lateinit var instance: MyApp private set } override fun onCreate() { super.onCreate() instance = this } }
记得在AndroidManifest.xml的<application>标签中指定android:name=".MyApp"。
数据源类中直接使用
class MyFileSource { private val appContext = MyApp.instance fun saveDataToFile(content: String) { val targetFile = File(appContext.filesDir, "user_data.txt") targetFile.writeText(content) } }
关键注意事项
- 绝对不要传递Activity Context到数据源/Repository/ViewModel:Activity生命周期短,容易引发内存泄漏。
- 优先选择依赖注入方案:它能更好地解耦代码,提高可测试性,符合现代Android架构规范。
内容的提问来源于stack exchange,提问作者Windowlicker
相关产品推荐
相关产品推荐

