【问题标题】:MVVM - get context in a Model classMVVM - 在模型类中获取上下文
【发布时间】:2020-04-13 14:33:21
【问题描述】:

我正在使用 MVVM 构建我的 Android 应用程序,我需要将模型连接到数据库。而不是 Room,我使用的是 SQLiteOpenHelper 并连接到我需要上下文的数据库。但由于这是一个非活动课程,我很难得到它。

我当前的解决方案如下所示,但我不断收到内存泄漏警告。

public class MyApplication extends Application {

    private static MyApplication mContext;

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = this;
    }

    public static MyApplication getContext() {
        return mContext;
    }
}

有更好的解决方案或最佳实践吗?

编辑:不使用 Dagger

【问题讨论】:

    标签: java android mvvm android-sqlite viewmodel


    【解决方案1】:

    您可以使用 Factory 将上下文传递给 ViewModel,例如:

    public class ViewModelClass extends ViewModel{
          private Context context;
          public ViewModelClass(Context context){
               this.context = context;
          }
    }
    

    和工厂类

    public class ViewModelFactory implements ViewModelProvider.Factory{
    private Context context;
    
        public ViewModelFactory(Context context){
        this.context = context;
        }
        @Override
            public <T extends ViewModel> T create(Class<T> modelClass) {
                if (modelClass.isAssignableFrom(ViewModelClass.class)) {
                    return (T) new ViewModelClass(context);
                }
                throw new IllegalArgumentException("Unknown ViewModel class");
            }
       }
    

    当你使用 ViewModel 时定义工厂

    ViewModelFactory viewModelFactory = new ViewModelFactory(context);
    

    然后像这样传递它:

    viewModel = ViewModelProviders.of(this, viewModelFactory).get(ViewModelClass.class)
    

    【讨论】:

      【解决方案2】:

      您的解决方案有效,但您违反了 MVVM 模式中的 Dependency Inversion 规则。因此,您应该使用构造函数注入或Dagger 之类的框架来实现Dependency Injection 模式,以将context 传递给您的模型层。您的内存泄漏也是因为违反了此规则,并且通过实施依赖注入,不需要在不同层中具有多个访问权限的全局变量,这可能会导致内存泄漏。

      【讨论】:

      • 我了解 DI 的工作原理,但如何将上下文传递给模型?
      • 您可以将其从您的视图传递给 ViewModel,然后在您的 ViewModel 中使用构造函数甚至方法参数将其传递给模型。此外,您可以使用 Dagger 等依赖注入框架直接注入它。 @dmak2709
      • 我的存储库类是单例,所以我仍然收到同样的警告......
      • 有时 Android Studio 只是显示警告而不考虑您的使用情况。特别是当您使用静态全局对象时。使用 LeakCanary 库检查内存泄漏或抑制它。 @dmak2709
      • 是的,如果您只是在一种方法中使用它,则将其作为方法参数而不是构造函数传递。 @dmak2709
      猜你喜欢
      • 2018-12-29
      • 2019-02-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-04
      • 1970-01-01
      • 2017-11-25
      • 1970-01-01
      • 2012-06-14
      相关资源
      最近更新 更多