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

不使用Room DB,如何在MVVM架构中正确单例化DAO与Repository?

基于Sugar ORM的Kotlin MVVM全局单例配置方案

问题现状

当前代码在Activity中手动实例化DAO与Repository,新增DAO时需修改多处代码,且存在重复创建实例的风险,不符合MVVM架构中单一职责与全局资源统一管理的要求。

解决方案:在Application层统一管理单例

通过将DAO、Repository的实例化逻辑移至Application类,并使用懒加载确保全局唯一实例,简化后续ViewModel与Activity的代码。


1. 改造Application类(Kotlin)

将原Java版Application转为Kotlin,通过lazy懒加载实现DAO与Repository的全局单例:

class MyApplication : Application() {
    // 全局单例DAO,首次调用时初始化
    val firstDao by lazy { FirstDao() }
    val secondDao by lazy { SecondDao() }
    
    // 全局单例Repository,依赖DAO实例
    val internalRepository by lazy { InternalRepository(firstDao, secondDao) }

    override fun onCreate() {
        super.onCreate()
        SugarContext.init(this)
        // 其他应用初始化逻辑
    }
}

注意:需在AndroidManifest.xml中指定该Application类:

<application
    android:name=".MyApplication"
    ...>
    ...
</application>

2. 优化ViewModelFactory

修改Factory,直接从Application获取全局Repository,无需手动传入:

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.CreationExtras

class FirstViewModelFactory : ViewModelProvider.Factory {
    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(modelClass: Class<T>, extras: CreationExtras): T {
        // 从Extras中获取Application实例
        val application = extras[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as MyApplication
        val repository = application.internalRepository
        
        return FirstViewModel(repository) as T
    }
}

3. 简化Activity代码

无论Activity是Java还是Kotlin,都无需再手动实例化DAO与Repository:

Kotlin版Activity
class FirstActivity : AppCompatActivity() {
    private lateinit var viewModel: FirstViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_first)
        
        // 直接通过Factory获取ViewModel
        viewModel = ViewModelProvider(this, FirstViewModelFactory()).get(FirstViewModel::class.java)
    }
}
Java版Activity
public class FirstActivity extends AppCompatActivity {
    private FirstViewModel viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);
        
        viewModel = new ViewModelProvider(this, new FirstViewModelFactory()).get(FirstViewModel.class);
    }
}

新增DAO的便捷性

后续新增DAO时,仅需两步:

  1. 在MyApplication中添加对应DAO的懒加载属性:val thirdDao by lazy { ThirdDao() }
  2. 更新InternalRepository的构造函数,传入新DAO实例

无需修改Activity或ViewModelFactory代码,彻底解决重复创建与多处修改的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 09:20:22