Android MVVM实例化ViewModel报错及AppCompat主题冲突问题求助
解决方案
方案1:不继承AppCompatActivity,直接实现所需接口
ViewModelProvider要求传入的上下文实现ViewModelStoreOwner接口,该接口并非只有AppCompatActivity实现,你可以在自己的BaseActivity中手动实现该接口,同时配套实现LifecycleOwner即可正常使用ViewModel,无需修改现有继承关系和主题配置。
实现代码示例:
import androidx.annotation.NonNull; import android.app.Activity; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleRegistry; import androidx.lifecycle.ViewModelStore; import androidx.lifecycle.ViewModelStoreOwner; public class BaseActivity extends Activity implements ViewModelStoreOwner, LifecycleOwner { private ViewModelStore mViewModelStore; private LifecycleRegistry mLifecycleRegistry; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mViewModelStore = new ViewModelStore(); mLifecycleRegistry = new LifecycleRegistry(this); mLifecycleRegistry.setCurrentState(Lifecycle.State.CREATED); } @NonNull @Override public ViewModelStore getViewModelStore() { return mViewModelStore; } @NonNull @Override public Lifecycle getLifecycle() { return mLifecycleRegistry; } @Override protected void onStart() { super.onStart(); mLifecycleRegistry.setCurrentState(Lifecycle.State.STARTED); } @Override protected void onResume() { super.onResume(); mLifecycleRegistry.setCurrentState(Lifecycle.State.RESUMED); } @Override protected void onDestroy() { super.onDestroy(); mLifecycleRegistry.setCurrentState(Lifecycle.State.DESTROYED); // 页面销毁时清理ViewModel,和系统原生逻辑保持一致 mViewModelStore.clear(); } }
完成上述实现后,你原来的new ViewModelProvider(this).get(LoginViewModel.class)代码可以直接正常运行,不会再报类型转换错误。
方案2:适配AppCompat主题,保留现有自定义样式
如果你选择继承AppCompatActivity,不需要放弃现有自定义标题栏主题,只要将你的自定义主题的父主题修改为AppCompat系主题即可,原有自定义配置完全不需要改动:
<style name="Theme.myTheme.TitleBar" parent="Theme.AppCompat.Light.NoActionBar"> <!-- 这里保留你原来所有的自定义标题栏、页面样式配置 --> </style>
修改后即可解决主题不兼容的报错,原有自定义标题栏效果不会发生任何变化。
核心结论
- 现有应用完全可以正常迁移MVVM架构,不存在技术阻碍
- 继承AppCompatActivity不是使用ViewModel的唯一方案
- 两种方案均不需要修改现有业务逻辑和自定义样式配置
内容的提问来源于stack exchange,提问作者Diego Perez
相关产品推荐
相关产品推荐

