不使用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时,仅需两步:
- 在
MyApplication中添加对应DAO的懒加载属性:val thirdDao by lazy { ThirdDao() } - 更新
InternalRepository的构造函数,传入新DAO实例
无需修改Activity或ViewModelFactory代码,彻底解决重复创建与多处修改的问题。
内容的提问来源于stack exchange,提问作者DevPeter
相关产品推荐
相关产品推荐

