MainActivity → RealApiViewModel(context) → WanAndroidRepository(context) → DataStoreCacheManager(context) → DataStore存在的问题:
- ❌ 内存泄漏风险:Repository 长期持有 Activity Context
- ❌ 生命周期不匹配:DataStore 应该使用全局 Context
- ❌ 架构不清晰:Context 传递链过长
- ❌ 测试困难:依赖具体的 Activity Context
/**
* 真实 API ViewModel - 使用统一的 UIState 设计
* 🔧 Context 优化:使用 Application Context 避免内存泄漏
*/
class RealApiViewModel(private val context: Context) : ViewModel() {
// 使用 Application Context 避免内存泄漏和生命周期问题
// DataStore 应该使用全局 Context,不依赖具体的 Activity
private val repository = WanAndroidRepository(context.applicationContext)
// ... 其他代码保持不变
}优势:
- ✅ 最小改动:只需修改一行代码
- ✅ 立即生效:解决内存泄漏问题
- ✅ 向后兼容:不影响现有调用方式
使用方式:
// UI 层调用保持不变
val viewModel: RealApiViewModel = remember { RealApiViewModel(context) }/**
* 真实 API ViewModel - 优化版本
* 🔧 架构优化:不再依赖外部传入的 Context
*/
class RealApiViewModelV2 : ViewModel() {
// 直接使用全局 Application,不依赖外部 Context 传递
private val repository = WanAndroidRepository(AppGlobals.getApplication())
// ... 其他代码
}优势:
- ✅ 架构更清晰:ViewModel 不依赖外部 Context
- ✅ 更易测试:可以独立创建 ViewModel
- ✅ 符合原则:单一职责,依赖倒置
- ✅ 通用性强:适用于组件化项目
使用方式:
// UI 层调用更简洁
val viewModel: RealApiViewModelV2 = remember { RealApiViewModelV2() }还可以进一步优化 Repository 层,使用单例模式:
/**
* Repository 单例管理器
*/
object RepositoryManager {
@Volatile
private var instance: WanAndroidRepository? = null
fun getInstance(): WanAndroidRepository {
return instance ?: synchronized(this) {
instance ?: WanAndroidRepository(AppGlobals.getApplication()).also { instance = it }
}
}
}
/**
* ViewModel 进一步简化
*/
class RealApiViewModelV3 : ViewModel() {
// 使用单例 Repository,更符合数据层设计
private val repository = RepositoryManager.getInstance()
// ... 其他代码
}- ✅ 线程安全:使用
@Volatile+synchronized双重检查 - ✅ 反射获取:一次反射,永久缓存
- ✅ 组件化友好:不依赖具体 Application 类名
- ✅ 异常处理:完整的错误处理机制
object AppGlobals {
@Volatile
private var application: Application? = null
fun getApplication(): Application {
if (application == null) {
synchronized(this) {
if (application == null) {
try {
application = Class.forName("android.app.ActivityThread")
.getMethod("currentApplication")
.invoke(null) as Application
} catch (e: Exception) {
e.printStackTrace()
throw RuntimeException("Failed to get Application instance", e)
}
}
}
}
return application!!
}
}- 🎯 数据存储:DataStore、数据库初始化
- 🎯 网络配置:Retrofit、OkHttp 全局配置
- 🎯 工具类:需要 Context 的工具类
- 🎯 组件化:跨模块的 Context 获取
| 特性 | 当前方案 | 方案一 | 方案二 | 方案三 |
|---|---|---|---|---|
| 内存安全 | ❌ | ✅ | ✅ | ✅ |
| 架构清晰度 | ❌ | ✅ | ✅ | |
| 测试友好性 | ❌ | ✅ | ✅ | |
| 改动成本 | - | 很低 | 低 | 中等 |
| 长期维护性 | ❌ | ✅ | ✅ |
修改现有 ViewModel,使用 context.applicationContext
- 创建
AppGlobals工具类 - 创建
RealApiViewModelV2 - 逐步迁移 UI 层调用
根据项目需要,考虑 Repository 单例化
- 快速修复,成本最低
- 适合学习项目、原型项目
- 架构清晰,易于维护
- 适合商业项目、长期维护项目
- 完整的架构设计
- 适合企业级项目、组件化项目
- DataStore 应该使用 Application Context
- ViewModel 不应该直接依赖 Activity Context
- 使用全局 Application 获取更符合架构原则
- 反射获取 Application 是组件化的通用方案
- 考虑单例模式管理全局数据层组件
这样的架构优化不仅解决了内存泄漏问题,还让代码更加清晰、易测试、易维护!🎉