Android ViewModel没有零参数构造函数,KotlinJetpack Compose

lmvvr0a8  于 2023-10-23  发布在  Kotlin
关注(0)|答案(2)|浏览(186)

我试图使一个应用程序与API调用,但当我启动,它崩溃与错误,搜索整个互联网,找不到什么错了。这是一个错误:

  • 原因:java.lang.InstantiationException:java.lang.Class<com.lobo.lobo.ViewModels.DishesViewModel>没有零参数构造函数 *

我的项目结构:

我的代码:
DishApplication.kt:

package com.lobo

import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class DishApplication:Application() {
}

api.models:

class DishList : ArrayList<DishListItem>()

data class DishListItem(
    val activeCount: Int,
    val actualPrice: Int,
    val description: String,
    val dishId: Int,
    val isLobobox: Int,
    val name: String,
    val orders: List<Order>,
    val originalPrice: Int,
    val photo: String,
    val tags: List<String>
)

data class Order(
    val actualPrice: Int,
    val customerId: String,
    val orderId: Int,
    val originalPrice: Int,
    val status: String
)

api.requests.GetDishList:

import com.lobo.lobo.data.api.APIConstants
import retrofit2.http.GET
import com.lobo.lobo.data.api.models.DishList
import retrofit2.http.Header

interface GetDishList {

    @GET(APIConstants.DISH_LIST)
    suspend fun getDishes(@Header("Authorization") authHeader: String): DishList

}

API常量:

object APIConstants {
    const val BASE_URL = "my_server_link"
    const val DISH_LIST = "list_dishes"
}

data.repository.DishRepo:

class DishRepo @Inject constructor(
    private val dishList : GetDishList
){
    suspend fun getDishList(authHeader: String) : DishList{
        return dishList.getDishes(authHeader)
    }
}

lobo.di.DishAPIModule:

@Module
@InstallIn(SingletonComponent::class)
object DishAPIModule {

    @Provides
    @Singleton
    fun provideGetDishList(retrofit: Retrofit): GetDishList {
        return retrofit.create(GetDishList::class.java)
    }

    @Provides
    @Singleton
    fun provideRetrofit(): Retrofit {
        return Retrofit.Builder()
            .baseUrl(APIConstants.BASE_URL)
            .build()
    }

}

lobo.ViewModels.DishesViewModel:

@HiltViewModel
class DishesViewModel @Inject constructor(
    private val dishRepo: DishRepo
) : ViewModel() {

    private val _dishes = MutableLiveData<DishList>()
    val dishes: LiveData<DishList> = _dishes

    fun getDishes(authHeader: String) {
        viewModelScope.launch {
            val dishList = dishRepo.getDishList(authHeader)
            _dishes.postValue(dishList)
        }
    }
}

Dishes.kt(snippet):

@Composable
fun ListOfDishesScreen(navController: NavController) {
    var showDialog by rememberSaveable { mutableStateOf(false) }
    var checkedState by remember { mutableStateOf(false) }

    val viewModel: DishesViewModel = viewModel()

    LaunchedEffect(Unit) {
        viewModel.getDishes("Bearer my_token")
        Log.d("WTF", "token send")
    }

    val dishes by viewModel.dishes.observeAsState()
//some code here
                dishes?.forEach { dish ->
                    DishAPICard(
                        dishName = dish.name,
                        dishPhoto = dish.photo ,  // You will need to load the image from the URL.
                        actualPrice = dish.actualPrice,
                        navController = navController
                    )
                    Spacer(modifier = Modifier.height(16.dp))
                }

MainActivity.kt:

import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        WindowCompat.setDecorFitsSystemWindows(window, false)
        super.onCreate(savedInstanceState)
        setContent {
            val is_auth = false
            val navController = rememberNavController()

            NavHost(navController, startDestination = if (is_auth) "lol" else "dish_list") {
                composable("dish_list"){ ListOfDishesScreen(navController = navController)}

还添加了我的构建Gradle文件(MB有一个依赖错误,我尝试了一切)
build.gradle(项目):

buildscript {
    ext {
        compose_ui_version = '1.2.0'
        hilt_version = '2.43'
    }
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    id 'com.android.application' version '7.4.1' apply false
    id 'com.android.library' version '7.4.1' apply false
    id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
    id 'com.google.dagger.hilt.android' version '2.43' apply false
}

build.gradle(Module:app):

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
}
apply plugin: 'kotlin-kapt'


android {
    namespace 'com.lobo.lobo'
    compileSdk 33

    defaultConfig {
        applicationId "com.lobo.lobo"
        minSdk 29
        targetSdk 33
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables {
            useSupportLibrary 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'
    }
    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerExtensionVersion '1.2.0'
    }
    packagingOptions {
        resources {
            excludes += '/META-INF/{AL2.0,LGPL2.1}'
        }
    }
}

dependencies {

    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
    implementation 'androidx.activity:activity-compose:1.3.1'
    implementation "androidx.compose.ui:ui:$compose_ui_version"
    implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version"
    implementation 'androidx.compose.material:material:1.2.0'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
    androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
    debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
    debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"
    implementation "androidx.compose.runtime:runtime-livedata:$compose_ui_version"
    implementation 'com.google.accompanist:accompanist-systemuicontroller:0.17.0'
    implementation "com.google.accompanist:accompanist-insets:0.17.0"// Please use the latest version


    // Jetpack Compose Integration
    implementation "androidx.navigation:navigation-compose:2.5.3"

    implementation "com.squareup.retrofit2:retrofit:2.9.0"
    implementation "com.squareup.retrofit2:converter-gson:2.6.0"
    implementation "io.coil-kt:coil-compose:1.3.2"

    implementation 'com.google.dagger:dagger:2.43'
    kapt 'com.google.dagger:hilt-compiler:2.43'
    kapt 'com.google.dagger:dagger-compiler:2.43'
    implementation "com.google.dagger:hilt-android:2.43"
    kapt "com.google.dagger:hilt-android-compiler:2.43"
    kapt "androidx.hilt:hilt-compiler:1.0.0"

    implementation 'androidx.activity:activity-compose:1.3.1'  // Make sure you use the latest version
    implementation 'androidx.activity:activity:1.3.1'  // Make sure you use the latest version
}

堆栈跟踪的完整错误消息:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.lobo.lobo, PID: 24136
    java.lang.RuntimeException: Cannot create an instance of class com.lobo.lobo.ViewModels.DishesViewModel
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.kt:204)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:322)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:304)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.kt:278)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.kt:128)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:187)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:153)
        at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModel.kt:215)
        at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModel.kt:156)
        at com.lobo.lobo.DishesKt.ListOfDishesScreen(Dishes.kt:386)
        at com.lobo.lobo.ComposableSingletons$MainActivityKt$lambda-1$1$2$11.invoke(MainActivity.kt:67)
        at com.lobo.lobo.ComposableSingletons$MainActivityKt$lambda-1$1$2$11.invoke(MainActivity.kt:67)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.navigation.compose.NavHostKt$NavHost$4$2.invoke(NavHost.kt:163)
        at androidx.navigation.compose.NavHostKt$NavHost$4$2.invoke(NavHost.kt:162)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
        at androidx.compose.runtime.saveable.SaveableStateHolderImpl.SaveableStateProvider(SaveableStateHolder.kt:84)
        at androidx.navigation.compose.NavBackStackEntryProviderKt.SaveableStateProvider(NavBackStackEntryProvider.kt:65)
        at androidx.navigation.compose.NavBackStackEntryProviderKt.access$SaveableStateProvider(NavBackStackEntryProvider.kt:1)
        at androidx.navigation.compose.NavBackStackEntryProviderKt$LocalOwnersProvider$1.invoke(NavBackStackEntryProvider.kt:52)
        at androidx.navigation.compose.NavBackStackEntryProviderKt$LocalOwnersProvider$1.invoke(NavBackStackEntryProvider.kt:51)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
        at androidx.navigation.compose.NavBackStackEntryProviderKt.LocalOwnersProvider(NavBackStackEntryProvider.kt:47)
        at androidx.navigation.compose.NavHostKt$NavHost$4.invoke(NavHost.kt:162)
        at androidx.navigation.compose.NavHostKt$NavHost$4.invoke(NavHost.kt:141)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.animation.CrossfadeKt$Crossfade$4$1.invoke(Crossfade.kt:115)
        at androidx.compose.animation.CrossfadeKt$Crossfade$4$1.invoke(Crossfade.kt:110)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.animation.CrossfadeKt.Crossfade(Crossfade.kt:124)
        at androidx.compose.animation.CrossfadeKt.Crossfade(Crossfade.kt:55)
        at androidx.navigation.compose.NavHostKt.NavHost(NavHost.kt:141)
        at androidx.navigation.compose.NavHostKt$NavHost$5.invoke(Unknown Source:13)
        at androidx.navigation.compose.NavHostKt$NavHost$5.invoke(Unknown Source:10)
        at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:145)
E/AndroidRuntime:     at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2351)
        at androidx.compose.runtime.ComposerImpl.skipToGroupEnd(Composer.kt:2641)
        at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:248)
        at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:247)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
        at androidx.compose.ui.platform.CompositionLocalsKt.ProvideCommonCompositionLocals(CompositionLocals.kt:177)
        at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:123)
        at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:122)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
        at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
        at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt.ProvideAndroidCompositionLocals(AndroidCompositionLocals.android.kt:114)
        at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$4.invoke(Unknown Source:8)
        at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$4.invoke(Unknown Source:10)
        at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:145)
        at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2351)
        at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Composer.kt:2618)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3205)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3183)
        at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:252)
        at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
        at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3183)
        at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:3148)
        at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:746)
        at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:876)
        at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:107)
        at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:485)
        at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:454)
        at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
        at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
        at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
        at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:970)
        at android.view.Choreographer.doCallbacks(Choreographer.java:796)
        at android.view.Choreographer.doFrame(Choreographer.java:727)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
        Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [androidx.compose.runtime.PausableMonotonicFrameClock@875fdae, androidx.compose.ui.platform.MotionDurationScaleImpl@1c374f, StandaloneCoroutine{Cancelling}@af7cedc, AndroidUiDispatcher@6b24be5]
    Caused by: java.lang.InstantiationException: java.lang.Class<com.lobo.lobo.ViewModels.DishesViewModel> has no zero argument constructor
        at java.lang.Class.newInstance(Native Method)
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.kt:202)
            ... 86 more
I/Process: Sending signal. PID: 24136 SIG: 9

我尝试更改依赖项和@Composable对象,但仍然出现相同的错误

6rqinv9w

6rqinv9w1#

我觉得你需要改变

val viewModel: DishesViewModel = viewModel()

val viewModel: DishesViewModel by viewModels()

Dishes.kt中。

np8igboo

np8igboo2#

您在模块中缺少provide方法。您的viewModel依赖于存储库,并且您注解了hilt以提供这种依赖。Hilt不能提供在该组件的模块中找不到的依赖项。

@Module
 @InstallIn(SingletonComponent::class)
 object DishAPIModule {

@Provides
@Singleton
fun provideGetDishList(retrofit: Retrofit): GetDishList {
    return retrofit.create(GetDishList::class.java)
    }

@Provides
@Singleton
fun provideRetrofit(): Retrofit {
    return Retrofit.Builder()
        .baseUrl(APIConstants.BASE_URL)
        .build()
    }

@Provides
@Singleton
fun provideDishRepo(dishList : GetDishList): DishRepo {
    return DishRepo(dishList)
    }

}

现在hilt可以提供DishRepo对象给viewModel了。

相关问题