簡體   English   中英

java.lang.RuntimeException:無法創建 class com.example.cookpadapp.viewmodel.CookpadViewModel+ 的實例

[英]java.lang.RuntimeException: Cannot create an instance of class com.example.cookpadapp.viewmodel.CookpadViewModel+ at

我正在開發配方 android 應用程序並使用 koin 依賴注入但是當我運行項目時出現以下異常]

java.lang.RuntimeException: Cannot create an instance of class com.example.cookpadapp.viewmodel.CookpadViewModel
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.kt:188)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:238)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:113)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:169)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:139)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:44)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:31)
        at com.example.cookpadapp.CookpadFragment.getViewModel(CookpadFragment.kt:21)
        at com.example.cookpadapp.CookpadFragment.initObservers(CookpadFragment.kt:41)
        at com.example.cookpadapp.CookpadFragment.onViewCreated(CookpadFragment.kt:30)
        at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2987)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:546)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
        at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)
        at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3065)
        at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2988)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:546)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
        at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128)
        at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3072)
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:251)
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:502)
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1392)
        at android.app.Activity.performStart(Activity.java:7252)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3000)
        at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:185)
        at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:170)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:147)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:73)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1858)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:201)
        at android.app.ActivityThread.main(ActivityThread.java:6820)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:922)
     Caused by: java.lang.InstantiationException: java.lang.Class<com.example.cookpadapp.viewmodel.CookpadViewModel> has no zero argument constructor
        at java.lang.Class.newInstance(Native Method)

在我的 CookpadViewModel.kt 下面

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.cookpadapp.domain.use_case.GetRecipeUseCase
import com.example.cookpadapp.domain.utils.fold
import com.example.cookpadapp.model.Recipe
import com.example.cookpadapp.model.RecipeResponse
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class CookpadViewModel(private val recipeUseCase: GetRecipeUseCase) : ViewModel() {

    var cookpad = MutableLiveData<RecipeResponse>()

    // Expose to the outside world
    val error = MutableLiveData<String>()
    var progress = MutableLiveData(false)


    init {
        getRecipes()
    }

    fun getRecipes() {
        progress.postValue(true)
        viewModelScope.launch(Dispatchers.IO) {
            recipeUseCase.invoke()
                .fold({  recipeResponse->
                    cookpad.postValue(recipeResponse)
                }, {
                   error.postValue(it.message)
                })
            progress.postValue(false)
        }
    }

    fun onRecipeClicked(recipe: Recipe) {

  

} }

在我的 CookpadFragment.kt 下面

package com.example.cookpadapp

import android.os.BaseBundle
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import com.example.cookpadapp.databinding.FragmentCookpadBinding
import com.example.cookpadapp.ui.BaseFragment
import com.example.cookpadapp.ui.adapter.RecipeAdapter
import com.example.cookpadapp.viewmodel.CookpadViewModel
import org.koin.androidx.viewmodel.ext.android.viewModel

// TODO: item_recipe, RecipeAdapter, fragment_cookpad
class CookpadFragment : BaseFragment<FragmentCookpadBinding>() {

    override val layoutId: Int = R.layout.fragment_cookpad

    private val viewModel: CookpadViewModel by viewModels()

    private val adapter = RecipeAdapter(arrayListOf()) { recipe ->
        viewModel.onRecipeClicked(recipe)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initViews()
        initObservers()
    }

    private fun initViews() {
        binding.recipeRV.adapter = adapter
        binding.swipeRefresh.setOnRefreshListener {
            viewModel.getRecipes()
        }
    }

    private fun initObservers() {
        viewModel.cookpad.observe(viewLifecycleOwner) { recipes ->
            adapter.update(recipes)
        }
        viewModel.progress.observe(viewLifecycleOwner) { loading ->
            binding.swipeRefresh.isRefreshing = loading
        }
    }
}

在我實現 koin 邏輯的 Modules.kt 下方

object Modules {

    val viewModels = module {
        viewModel { CookpadViewModel(get()) }
        viewModel{DetailCookpadViewModel(get())}
    }

    val apiModule = module {

        factory { CookpadRepository(get()) }
        factory { GetRecipeUseCase(get()) }
        factory { GetRecipeDetailsUseCase(get()) }


        single<CookpadInterface> {
            provideRetrofit(get<OkHttpClient>())
        }

        factory<OkHttpClient> {
            provideOkHttpClient(get<Cache>())
        }

        factory<Cache> {
            provideCache(get<Context>())
        }
    }
}


fun provideCache(context: Context): Cache {
    val cacheSize: Long = 10 * 1024 * 1024
    return Cache(context.cacheDir, cacheSize)
}

fun provideOkHttpClient(cache: Cache): OkHttpClient {
    val logger = HttpLoggingInterceptor().apply {
        level = HttpLoggingInterceptor.Level.BODY
    }

    return OkHttpClient.Builder()
        .connectTimeout(60, TimeUnit.SECONDS)
        .writeTimeout(60, TimeUnit.SECONDS)
        .readTimeout(60, TimeUnit.SECONDS)
        .cache(cache)
        .addInterceptor(logger)
        .build()
}

fun provideRetrofit(okHttpClient: OkHttpClient): CookpadInterface {
    return Retrofit.Builder()
        .baseUrl(Constants.BASE_URL)
        .client(okHttpClient)
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(CoroutineCallAdapterFactory.invoke())
        .build()
        .create(CookpadInterface::class.java)
}

GetRecipeUseCase.kt 下面

class GetRecipeUseCase(
    private val cookpadRepository: CookpadRepository
) {

    suspend operator fun invoke() = cookpadRepository.getRecipes()
}

我想知道我到底在哪里犯了錯誤我遵循了所有stackoverflow的答案它沒有解決我的問題

我通過在 CookpadFragment 中導入和添加我的視圖模型來解決我的問題

private val viewModel: CookpadViewModel by viewModel()
import org.koin.androidx.viewmodel.ext.android.viewModel

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM