【问题标题】:How to get activity context in ViewModel Android?如何在 ViewModel Android 中获取活动上下文?
【发布时间】:2020-12-24 22:05:27
【问题描述】:

我正在使用 MVVM。我想在应用程序中实现 Firebase Auth。但要实现它,我需要在我的 repo 类中有一个活动上下文。我如何从 ViewModel 中获取它或者有什么简单的方法可用?

这是我需要实现的 firebase 代码:

 PhoneAuthProvider.getInstance().verifyPhoneNumber("+91"+phone,        // Phone number to verify
            60,                 // Timeout duration
            TimeUnit.SECONDS,   // Unit of timeout
            (Activity) context,               // Activity (for callback binding)
            new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
                @Override
                public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) 
               {
                    signInWithPhoneAuthCredential((Activity)context,phoneAuthCredential);
                }

                @Override
                public void onVerificationFailed(@NonNull FirebaseException e) {
                    setLoginFailed(e);

                }

                @Override
                public void onCodeSent(@NonNull String s, @NonNull 
                PhoneAuthProvider.ForceResendingToken forceResendingToken) {
                    super.onCodeSent(s, forceResendingToken);
                    loginResponse.setOnProgress(false);
                    loginResponse.setStatus(true);
                    loginResponse.setCodeVerified(false);
                    loginResponseLiveData.setValue(loginResponse);
                    verificationId =s;

                }
            });

【问题讨论】:

    标签: android firebase mvvm firebase-authentication


    【解决方案1】:
    • 如果您的工作与任何UI 无关,那么您可以使用AndroidViewModel 而不是ViewModel

    • AndroidViewModel 中有一个重要的默认参数ApplicationContext

    • 或者,如果您想要任何特定的活动引用,请在类中初始化 ViewModel 时使用 LiveData<YourActivity> 并设置类引用

    【讨论】:

    • 我不能使用 android 视图模型,因为我需要 firebase 的活动上下文。你能简要解释一下 LiveData 的事情
    • OK 在你查看模型类添加这个第一个 var activityReference: MutableLiveData? = MutableLiveData() 并在您的 Activity 类中添加这一行 viewModel.activityReference?.value = this@SignUpActivity //(您的类引用)然后在您的视图模型中您有当前活动的引用
    • 什么是AndroidViewModel?如何使用它。
    【解决方案2】:

    首先根据official view model guidelines

    注意:ViewModel 不得引用视图、生命周期或任何可能持有对活动内容的引用的类

    因此,根据您的 MVVM 架构,不要将您的活动上下文传递给 ViewModel

    我想在你想要实现的那个方法中你并不特别需要一个活动上下文。您也可以使用应用程序的context

    按照this answer 的这三个步骤来静态访问您的应用程序context

    1. 创建引用context 创建的应用程序类
      public class MyApplication extends Application {
      
          private static Context context;
      
          public void onCreate() {
              super.onCreate();
              MyApplication.context = getApplicationContext();
          }
      
          public static Context getAppContext() {
              return MyApplication.context;
          }
      }
      
    2. 在清单中声明您的应用程序类
      <application android:name="com.xyz.MyApplication">
      
      </application>
      
    3. 在存储库类中静态访问此上下文
      MyApplication.getAppContext()
      

    还可以通过AndroidViewModel 类访问应用程序上下文。但我猜您通常不想从您的 ViewModel 初始化您的存储库。

    【讨论】:

    • 像这样存储上下文可能会导致内存泄漏..我也已经尝试过使用 AndroidViewModel 但你知道它提供应用程序上下文,而不是活动上下文......所以 firebase 给出异常......并要求将上下文从应用程序转换为活动
    • 那么Doug Stevenson 的建议呢,API 是否也提供这样的方法而不需要活动上下文?如果您根本不需要担心弄乱上下文,这可能是最好的解决方案
    【解决方案3】:

    一般来说,ViewModel 对象不应该引用与 Android 平台 API 相关的任何内容,尤其是 Activity 对象。您不希望 ViewModel 在方向更改时保留(和泄漏)活动。在 ViewModel 中保留 Activity 对象是一个巨大的反模式,应该避免。

    相反,您应该使用该 Firebase API 的不同版本。根据API documentation,选择不采取活动的替代方案之一。 API 完成后,您可以将回调冒泡到托管活动以启动任何其他活动。

    【讨论】:

    • 是的,我也认为我违反了 MVVM 的法律......我没有找到替代 inAPI doc.. 所以我应该在活动中处理它!!?
    • 在我的回答中,我链接到了 API 文档,该文档为您提供了不使用 Activity 的 verifyPhoneNumber 的多种替代方案。我建议您使用其中一种替代方法。
    猜你喜欢
    • 2018-12-29
    • 2012-04-11
    • 2012-07-09
    • 2014-03-14
    • 2019-02-17
    • 1970-01-01
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多