任务 ':app:kaptDebugKotlin' 执行失败;使用房间图书馆时

时间:2021-07-11 07:08:09

标签: android android-studio kotlin android-room kapt

我正在尝试使用 Room 库进行数据存储来制作一个简单的图书记录应用程序文件。完成前两个片段后,我决定测试它们。 Building 代码给了我这个错误:

Execution failed for task ':app:kaptDebugKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask$KaptExecutionWorkAction
> java.lang.reflect.InvocationTargetException (no error message)

这是我的房间实现:

实体

package com.example.books.data

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity
data class Book(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,

    @ColumnInfo(name = "book name")
    val bookName: String,
    @ColumnInfo(name = "author name")
    val bookAuthor: String,

    @ColumnInfo(name = "topic")
    val bookTopic: String,
    @ColumnInfo(name = "status")
    val bookStatus: String,
    @ColumnInfo(name = "chapter")
    val chapter: String,

    @ColumnInfo(name = "read percent")
    val readPercent: Double,
    @ColumnInfo(name = "pages read")
    val pagesRead: Int,
    @ColumnInfo(name = "total page")
    val totalPage: Int,

    @ColumnInfo(name = "date")
    val dateCreated: String?,
    @ColumnInfo(name = "last read")
    val lastRead: String?,

    @ColumnInfo(name = "notes")
    val notes: String?
)

package com.example.books.data

import androidx.room.*
import kotlinx.coroutines.flow.Flow

@Dao
interface BookDao {

    @Query("SELECT * FROM book ORDER BY `last read` DESC")
    fun getBooks(): Flow<List<Book>>

    @Query("SELECT * FROM book WHERE id = :id")
    fun getBook(id: Int) : Flow<Book>

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insert(book: Book)
    @Update
    suspend fun update(book: Book)
    @Delete
    suspend fun delete(book: Book)
}

数据库

package com.example.books.data

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase

@Database(entities = [Book::class], version = 1, exportSchema = false)
abstract class BookDatabase : RoomDatabase() {

    abstract fun bookDao(): BookDao

    companion object {
        @Volatile
        private var INSTANCE: BookDatabase? = null

        fun getDatabase(context: Context) : BookDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    BookDatabase::class.java,
                    "book_database"
                )
                    .fallbackToDestructiveMigration()
                    .build()
                INSTANCE = instance
                instance
            }
        }
    }
}

应用


import android.app.Application
import com.example.books.data.BookDatabase

class BookListApplication : Application() {
    val database : BookDatabase by lazy { BookDatabase.getDatabase(this) }
}

Gradle 依赖

dependencies {
    implementation "androidx.room:room-runtime:$room_version"
    implementation "androidx.room:room-ktx:$room_version"
    kapt ("androidx.room:room-compiler:$room_version")
}

这是我的 ViewModel 实现房间属性(仅相关部分):

import androidx.lifecycle.*
import com.example.books.data.Book
import com.example.books.data.BookDao
import kotlinx.coroutines.launch
import java.lang.IllegalArgumentException
import java.time.LocalDate
import java.time.format.DateTimeFormatter

class BookViewModel(private val bookDao: BookDao) : ViewModel() {
    private fun getNewBookRecordEntry(
        name: String, author: String,
        topic: String, chapter: String,
        pageRead: String, totalPage: String
    ) : Book {
        val percent = (pageRead.toDouble() / totalPage.toDouble()) * 100
        val status = if (percent != 100.toDouble()) "Not Finished" else "Finished"

        return Book(
            bookName = name, bookAuthor = author,

            pagesRead = pageRead.toInt(), totalPage = totalPage.toInt(),
            readPercent = percent,

            bookTopic = topic,
            chapter = chapter,
            bookStatus = status,

            dateCreated = LocalDate.now().format(DateTimeFormatter.ofPattern("dd-MM-yyyy")),
            lastRead = null,
            notes = null
        )
    }

    private fun insertRecord(book: Book) {
        viewModelScope.launch {
            bookDao.insert(book)
        }
    }
}

class BookViewModelFactory(private val bookDao: BookDao) : ViewModelProvider.Factory {
    override fun <T : ViewModel?> create(modelClass: Class<T>) : T {
        if (modelClass.isAssignableFrom(BookViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return BookViewModel(bookDao) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}

我尝试使用以下命令运行 gradle 控制台 .\gradlew clean build --debug --stacktrace。 运行一段时间后,命令行给我一个警告,说调试进程可能会舔一些敏感信息,使命令不完整。

当我回到开始的地方时,我决定将其转发给 StackOverflow 社区。我很感激你的时间。谢谢!

1 个答案:

答案 0 :(得分:0)

经过几天的挫折和反复检查,我找到了出路;虽然我不太能接受这个解决方案。

最初,我认为在实现 room 属性时一定存在一些小错误/错别字,但我不知何故错过了,但事实并非如此。

我所做的只是降级 kotlin_versoin。在我 buildscript.extproject build.gradle 中,我改成了这个

buildscript {
    ext {
        ...
        kotlin_version = '1.4.32'
    }
    ...
}

来自

buildscript {
    ext {
        ...
        kotlin_version = '1.5.10'
    }
    ...
}

为了避免 Kotlin jar files in classpath should have same version 警告,我在 kotlin_version 中使用了相同的 kotlin-reflect 以使其与 kotlin-stdlib 兼容。在我的 gradle 依赖项中,我添加了

implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"  //added
...

我不知道为什么它不适用于最新版本。此外,我真的不想降级。

这里有人知道为什么吗?知道答案对我来说会很满意。谢谢!