【问题标题】:AndroidViewModel instantiated without passing application context?AndroidViewModel 实例化而不传递应用程序上下文?
【发布时间】:2020-03-02 21:20:56
【问题描述】:

我目前正在研究Android Room with a View 示例应用程序,完整的源代码可用here。在这个项目中,定义了一个AndroidViewModel 类型的WordViewModel:

class WordViewModel(application: Application) : AndroidViewModel(application)

请注意构造函数如何要求传入Application 实例。 然而,当我检查MainActivity 时,WordViewModel 被检索到而没有传入 Application实例:

// Get a new or existing ViewModel from the ViewModelProvider.
mWordViewModel = new ViewModelProvider(this).get(WordViewModel.class);

这怎么可能,如何在不传入Application 实例且不使用自定义工厂的情况下检索WordViewModel?

【问题讨论】:

    标签: android android-architecture-components android-viewmodel


    【解决方案1】:

    AndroidX-Activity 1.2.0 的ComponentActivity(因此是AppCompatActivity)实现了HasDefaultViewModelProviderFactory,默认情况下它会从您的Activity/Fragment 中返回一个ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication()),允许您从这个AndroidViewModelFactory 获取应用程序,而无需你必须明确地传递它。

    然后,该工厂使用 __(application) 构造函数通过反射实例化您的 ViewModel。

    不过,最好使用SavedStateViewModelFactory 以便能够以类似的方式(___(application, savedStateHandle))接收SavedStateHandle。

    因此,要解决此问题,您需要在代码中明确添加core-ktx、activity-ktx 和fragment-ktx 的最新版本。

    【讨论】:

    【解决方案2】:

    依赖关系

    def lifecycle_version = "2.2.0"
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
    kapt "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
    
    implementation "androidx.fragment:fragment-ktx:1.2.4"
    

    应用类

    class App : Application() {
        //Code
    }
    

    AndroidViewModel 类

    class TestVM (app : android.app.Application) : AndroidViewModel(app){
        // Cast app to the application class
        val myApplication : App = app as App
    }
    

    在片段中

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val viewModel = ViewModelProvider(this).get(TestVM::class.java)
    }
    

    【讨论】:

    • 这里我没有将上下文传递给视图模型。这意味着 ViewModelStoreOwner。公共 ViewModelProvider(@NonNull ViewModelStoreOwner 所有者) { ... }。那么为什么要降级答案@IgorGanapolsky
    • 神秘。已回滚。
    猜你喜欢
    • 1970-01-01
    • 2017-11-11
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2017-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多