AndroidViewModelを使うとhas no zero argument constructorエラーの解決策

先に解決方法。Fragmentを現在の安定版に更新すれば解決します。

#何をしたか
##ViewModelをAndroidViewModelに変更
ViewModelにApplicationが欲しいのでAndroidViewModelを使いたかった

ViewModel呼出部分

```kotlin:MainFragment.kt
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
```

ViewModelをAndroidViewModelに変更するとエラーになる

```diff_kotlin:MainViewModel.kt
- class MainViewModel() : ViewModel() {
+ class MainViewModel(application: Application) : AndroidViewModel(application) {
}
```
##エラーメッセージ
```
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.myapplication, PID: 14629
    java.lang.RuntimeException: Cannot create an instance of class com.myapplication.ui.main.MainViewModel
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
        at com.myapplication.ui.main.MainFragment.onActivityCreated(MainFragment.kt:28)
        at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2619)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:904)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2659)
        at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613)
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1392)
        at android.app.Activity.performStart(Activity.java:7165)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2976)
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1817)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6758)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: java.lang.InstantiationException: java.lang.Class<com.myapplication.ui.main.MainViewModel> has no zero argument constructor
        at java.lang.Class.newInstance(Native Method)
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150) 
        at com.myapplication.ui.main.MainFragment.onActivityCreated(MainFragment.kt:28) 
        at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2619) 
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:904) 
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238) 
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303) 
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2659) 
        at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613) 
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246) 
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542) 
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210) 
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1392) 
        at android.app.Activity.performStart(Activity.java:7165) 
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2976) 
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180) 
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165) 
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1817) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6758) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 
```

#解決方法
##build.gradle(:app)でFragmentを更新
あたかもFactory作って解決するように感じるが...
build.gradle(:app)でFragmentを現在の安定版リリースに変更すると通る
[Android デベロッパー Fragment](https://developer.android.com/jetpack/androidx/releases/fragment?hl)

```diff
dependencies {
+    def fragment_version = "1.2.5"
+    // Java language implementation
+    implementation "androidx.fragment:fragment:$fragment_version"
+    // Kotlin
+    implementation "androidx.fragment:fragment-ktx:$fragment_version"
+    // Testing Fragments in Isolation
+    debugImplementation "androidx.fragment:fragment-testing:$fragment_version"

    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.0'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
```
#原因
AndroidStudioでNewProjectからの初期状態だとFragmentが1.1.0でHasDefaultViewModelProviderFactoryを継承していないため起こる問題のようです。1.2.5では継承され解決しています。今現在だけの問題のようですね。


```java:androidx.fragment.app.Fragment.java-1.1.0
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
        ViewModelStoreOwner, SavedStateRegistryOwner {
```

```java:androidx.fragment.app.Fragment.java-1.2.5
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
        ViewModelStoreOwner, HasDefaultViewModelProviderFactory, SavedStateRegistryOwner {
```

HasDefaultViewModelProviderFactoryを継承していれば、getDefaultViewModelProviderFactoryが呼び出され

```java:ViewModelProvider.java2.3.0
    public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
        this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
                ? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
                : NewInstanceFactory.getInstance());
    }
```

以下のmDefaultFactory取得時にrequireActivity().getApplication()によってApplicationを取得しているのでエラーは出なくなります。

```java:androidx.fragment.app.Fragment.java
    @NonNull
    @Override
    public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
        if (mFragmentManager == null) {
            throw new IllegalStateException("Can't access ViewModels from detached fragment");
        }
        if (mDefaultFactory == null) {
            mDefaultFactory = new SavedStateViewModelFactory(
                    requireActivity().getApplication(),
                    this,
                    getArguments());
        }
        return mDefaultFactory;
    }
```