AndroidViewModel 在不传递应用程序上下文的情况下实例化?

AndroidViewModel instantiated without passing application context?

我目前正在研究 Android Room with a View 示例应用程序,定义了类型 AndroidViewModel 的完整源代码 here. In this project, an 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

AndroidX-Activity 1.2.0 的 ComponentActivity(因此 AppCompatActivity)实现了 HasDefaultViewModelProviderFactory,其中 returns 来自您的 ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication()) Activity/Fragment 默认情况下,允许您从此 AndroidViewModelFactory 获取应用程序而无需显式传递它。

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

使用 SavedStateViewModelFactory 通常是更好的主意,以便能够以类似的方式 (___(application, savedStateHandle)) 接收 SavedStateHandle

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

依赖关系

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

class App : Application() {
    //Code
}

AndroidViewModel Class

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)
}