java.lang.RuntimeException:无法创建类yodgorbek.komilov.musobaqayangiliklari.viewmodel.MainViewModel的实例

时间:2019-11-12 19:28:00

标签: android kotlin mvvm viewmodel android-lifecycle

我正在开发新闻,并且已经在片段类中实现了viewmodel,但是我运行的代码是从片段类中获取以下异常

java.lang.RuntimeException: Cannot create an instance of class yodgorbek.komilov.musobaqayangiliklari.viewmodel.MainViewModel
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:184)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:241)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:164)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:130)
        at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment.onCreateView(TopHeadlinesFragment.kt:38)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2663)
        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:201)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1425)
        at android.app.Activity.performStart(Activity.java:7825)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3294)
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
     Caused by: java.lang.InstantiationException: java.lang.Class<yodgorbek.komilov.musobaqayangiliklari.viewmodel.MainViewModel has no zero argument constructor
        at java.lang.Class.newInstance(Native Method)
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:182)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:241) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:164) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:130) 
        at yodgorbek.komilov.musobaqayangiliklari.ui.TopHeadlinesFragment.onCreateView(TopHeadlinesFragment.kt:38) 
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600) 
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881) 
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238) 
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303) 
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439) 
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079) 
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869) 
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824) 
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727) 
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2663) 
        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:201) 
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1425) 
        at android.app.Activity.performStart(Activity.java:7825) 
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3294) 
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221) 
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201) 
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7356) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

在我遇到异常的TopHeadlinesFragment下方

class TopHeadlinesFragment : Fragment() {

lateinit var viewModel: MainViewModel
var topHeadlinesAdapter: TopHeadlinesAdapter? = null
val showError = SingleLiveEvent<String>()

//3
override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    val view = inflater.inflate(
        R.layout.fragment_top_headlines
        , container, false
    )
    viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
    val recyclerView = view.findViewById(R.id.recyclerView) as RecyclerView
    val pb = view.findViewById(R.id.pb) as ProgressBar
    return view

    viewModel.loadNews(viewLifecycleOwner, Observer { result ->
        when (result) {
            is UseCaseResult.Success<*> -> {
                pb.visibility = View.GONE
                result.data as List<Deferred<SportNewsResponse>>
                topHeadlinesAdapter?.articleList


            }

            is Error -> {
                showError.value = result.message
                pb.visibility = View.GONE


            }


        }
    })
}
}

在MainViewModel.kt下面,其中我已实现ViewModel

class MainViewModel(
    private val sportNewsInterface: SportNewsInterface

) : ViewModel(), CoroutineScope {
    // Coroutine's background job
    private val job = Job()
    // Define default thread for Coroutine as Main and add job
    override val coroutineContext: CoroutineContext = Dispatchers.Main + job

    private val showLoading = MutableLiveData<Boolean>()
    private val sportList = MutableLiveData<List<Deferred<SportNewsResponse>>>()
    val showError = SingleLiveEvent<String>()

    fun loadNews(
        viewLifecycleOwner: LifecycleOwner,
        observer: Observer<Any>
    ) {
        // Show progressBar during the operation on the MAIN (default) thread
        showLoading.value = true
        // launch the Coroutine
        launch {
            // Switching from MAIN to IO thread for API operation
            // Update our data list with the new one from API
            val result = withContext(Dispatchers.IO) {
                sportNewsInterface.getNews()
            }
            // Hide progressBar once the operation is done on the MAIN (default) thread
            showLoading.value = false
            when (result) {

                is UseCaseResult.Success<*> -> {
                    sportList.value = result.data as List<Deferred<SportNewsResponse>>
                }
                is Error -> showError.value = result.message
            }
        }


    }

    override fun onCleared() {
        super.onCleared()
        // Clear our job when the linked activity is destroyed to avoid memory leaks
        job.cancel()
    }
}

NewsRepository.kt以下

interface NewsRepository {
    // Suspend is used to await the result from Deferred
    suspend fun getNewsList(): UseCaseResult<Deferred<List<SportNewsResponse>>>
}

class NewsRepositoryImpl(private val sportNewsInterface: SportNewsInterface) : NewsRepository {
    override suspend fun getNewsList(): UseCaseResult<Deferred<List<SportNewsResponse>>> {
        /*
         We try to return a list of cats from the API
         Await the result from web service and then return it, catching any error from API
         */
        return try {
            val result = sportNewsInterface.getNews()
            UseCaseResult.Success(result) as UseCaseResult<Deferred<List<SportNewsResponse>>>
        } catch (ex: Exception) {
            UseCaseResult.Error(ex)
        }
    }
}

在UseCaseResult.kt下面

sealed class UseCaseResult<out T : Any>() {
    class Success<out T : Any>(val data: T) : UseCaseResult<List<SportNewsResponse>>()

    class Error(val exception: Throwable) : UseCaseResult<Nothing>()

}

在app.gradle下面

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "yodgorbek.komilov.musobaqayangiliklari"
        minSdkVersion 15
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        dataBinding {
            enabled = true
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }


    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation 'org.koin:koin-android-viewmodel:1.0.0-RC-1'
    implementation 'org.koin:koin-android:0.9.3'
    def lifecycle_version = "2.1.0"
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.1'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.0'
    implementation "org.koin:koin-androidx-viewmodel:2.0.1"
    implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    // ViewModel and LiveData
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    // alternatively - just ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
    // For Kotlin use lifecycle-viewmodel-ktx
    // alternatively - just LiveData
    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
    // alternatively - Lifecycles only (no ViewModel or LiveData). Some UI
    //     AndroidX libraries use this lightweight import for Lifecycle
    implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"

    annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
    // For Kotlin use kapt instead of annotationProcessor
    // alternately - if using Java8, use the following instead of lifecycle-compiler
    implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"

    // optional - ReactiveStreams support for LiveData
    implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version"
    // For Kotlin use lifecycle-reactivestreams-ktx
    implementation 'com.google.android.material:material:1.0.0'
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.recyclerview:recyclerview:1.0.0'
    implementation 'com.github.bumptech.glide:glide:4.8.0'
    // optional - Test helpers for LiveData
    testImplementation "androidx.arch.core:core-testing:$lifecycle_version"
    implementation 'com.squareup.picasso:picasso:2.71828'
    implementation 'com.google.android.material:material:1.0.0-alpha3'
    implementation 'com.github.florent37:shapeofview:1.3.2'
    implementation 'com.github.AppIntro:AppIntro:5.1.0'

    implementation 'androidx.cardview:cardview:1.0.0'

    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'

    implementation 'com.squareup.okhttp3:okhttp:4.2.1'
    implementation "com.squareup.okhttp3:logging-interceptor:4.2.1"

    def room_version = "2.2.1"

    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor

    // optional - Kotlin Extensions and Coroutines support for Room
    implementation "androidx.room:room-ktx:$room_version"

    // Core library
    androidTestImplementation 'androidx.test:core:1.0.0'

    // AndroidJUnitRunner and JUnit Rules
    androidTestImplementation 'androidx.test:runner:1.1.0'
    androidTestImplementation 'androidx.test:rules:1.1.0'

    // Assertions
    androidTestImplementation 'androidx.test.ext:junit:1.0.0'
    androidTestImplementation 'androidx.test.ext:truth:1.0.0'
    androidTestImplementation 'com.google.truth:truth:0.42'

    // Espresso dependencies
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
    androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.1.0'
    androidTestImplementation 'androidx.test.espresso:espresso-intents:3.1.0'
    androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.1.0'
    androidTestImplementation 'androidx.test.espresso:espresso-web:3.1.0'
    androidTestImplementation 'androidx.test.espresso.idling:idling-concurrent:3.1.0'
    androidTestImplementation 'com.agoda.kakao:kakao:2.2.0'
    androidTestImplementation 'com.21buttons:fragment-test-rule:2.0.1'
    debugImplementation 'com.21buttons:fragment-test-rule-extras:2.0.1'

    androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.1.0'


    implementation 'com.github.bumptech.glide:glide:4.10.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
}

在自定义ViewModelParameterizedProvider.kt下面

类ViewModelParameterizedProvider {

companion object {


    lateinit var provider: ViewModelProvider

    private var viewModelStore: ViewModelStore? = null

    fun of(fragment: Fragment): Companion {
        viewModelStore = ViewModelStores.of(fragment)
        return this@Companion
    }

    fun of(fragment: android.app.Fragment): Companion {
        val fragAct: FragmentActivity = fragment.activity as FragmentActivity;
        return of(fragAct)
    }

    fun of(activity: FragmentActivity): Companion {
        viewModelStore = ViewModelStores.of(activity)
        return this@Companion
    }


    fun with(constructorParams: Array<out Any>) =
        viewModelStore?.let { ViewModelProvider(it, parametrizedFactory(constructorParams)) }

    private fun parametrizedFactory(constructorParams: Array<out Any>) = ParametrizedFactory(constructorParams)
}

 class ParametrizedFactory(private var constructorParams: Array<out Any>) : ViewModelProvider.Factory {
     override fun <T : ViewModel?> create(modelClass: Class<T>): T {
         if (modelClass == null) {
             throw IllegalArgumentException("Target ViewModel class can not be null")
         }
         Log.w("ParametrizedFactory", "Don't use callbacks or Context as parameters in order to avoid leaks!!")
         return when (constructorParams.size) {
             0 -> {
                 modelClass.newInstance()
             }
             else -> {
                 val parameterClasses: Array<Class<*>> = constructorParams.map { param -> param.javaClass }.toList().toTypedArray()
                 modelClass.getConstructor(*parameterClasses).newInstance(*constructorParams)
             }
         }
     }
 }
     }

0 个答案:

没有答案