我是Android开发新手,需要为大学建立我的第一个项目。大学用的是旧版本的XML和Java,但是我想学Compose,所以我学了Kotlin。
现在,在设置好一切之后,我试图使用hiltViewModel()方法将视图模型注入到可组合函数中,但我得到了一个错误。我看了这个教程:https://www.youtube.com/watch?v=A7CGcFjQQtQ
在让这个工作之后。现在它说找不到数据库类实现,但我希望 Dagger Hilt 会产生这个?对于房间数据库
这是基本代码:
依赖性:
构建梯度:
buildscript {
ext {
compose_version = '1.0.0'
}
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.10"
//->Adding the Dagger Hilt class path here as suggested:
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.38.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
app/build.gradle:
plugins {
id 'com.android.application'
id 'kotlin-android'
//->Adding Kotlin annotation processing plugin and the dagger hilt plugin:
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
android {
compileSdk 31
defaultConfig {
applicationId "ac.gre.mxpenseresit"
minSdk 21
targetSdk 31
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'
useIR = true
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
kotlinCompilerVersion '1.5.10'
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1'
implementation 'androidx.activity:activity-compose:1.4.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
//This version for navigation is hard coded, probably will need to update later, but should be fine for assignment
implementation("androidx.navigation:navigation-compose:2.4.2")
//Room Dependencies:
def room_version = "2.4.2"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
//Coroutine dependency:
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
//->Dagger Hilt Dependency for DI copied from official docs:
implementation "com.google.dagger:hilt-android:2.38.1"
kapt "com.google.dagger:hilt-compiler:2.38.1"
}
import android.app.application import dagger.hilt.android.HiltAndroidApp
/**
* Adding the Hilt Android App dependency for the Application class
*/
@HiltAndroidApp
class MExpenseApp : Application() {
}
主要的
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MXPenseResitTheme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
App(modifier = Modifier)
}
}
}
}
}
主模块:
**
* Setup dependencies:
*/
@Module
@InstallIn(ActivityComponent::class)
object MainModule {
@Provides
@Singleton
fun provideDb(application: Application): MExpenseDb {
return Room
.databaseBuilder(
application,
MExpenseDb::class.java,
"MExpenseDb"
).build()
}
/**
* We are type hinting to the Interface so we can change implementations
*/
@Provides
@Singleton
fun provideTripRepository(mExpenseDb: MExpenseDb): TripRepositoryContract {
return TripRepository(mExpenseDb.tripDao)
}
}
查看模型:
@HiltViewModel
class TripListVm @Inject constructor(
private val tripRepository: TripRepository
) : ViewModel() {
/**
* @var trips
* Get all trips
*/
val trips = tripRepository.getTrips()
val testStr: String = "Test String!"
}
可堆肥:
@Composable
fun TripList(
navController: NavHostController,
modifier: Modifier = Modifier,
tripListVm: TripListVm = hiltViewModel()
) {
Text(text = "Trip List")
TripListItem(
name = "Trip Name",
date = "16/04/1885",
amount = 46.66,
modifier = modifier
)
}
结果:
我也收到一个错误:[匕首/丢失绑定]异常。ac.gre.mxpenseresit.data.repository.TripRepository 不能在没有@Inject构造函数或@Provides注释方法的情况下提供
以下是数据层的代码:
数据库类:
@Database(
entities = [
Trip::class,
Expense::class,
],
version = 1
)
abstract class MExpenseDb : RoomDatabase() {
abstract val tripDao: TripDao
}
刀:
@Dao
interface TripDao {
/**
* Gets all trips
*/
@Query("SELECT * FROM Trip")
fun getTrips(): Flow<List<Trip>>
/**
* Gets trips based on a named search,
* This functionality can be extended later
*/
@Query("SELECT * FROM Trip t WHERE t.name LIKE :name")
suspend fun getTripsBySearchName(name: String)
/**
* Gets trip by Id
*/
@Query("SELECT * FROM Trip WHERE Trip.id = :id")
suspend fun getTripById(id: Long)
/**
*
*/
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun saveTrip(trip: Trip): Long
@Delete
suspend fun deleteTrip(trip: Trip)
}
行程存储库合约(接口):
interface TripRepositoryContract {
fun getTrips(): Flow<List<Trip>>
suspend fun getTripById(id: Long): Trip?
suspend fun getTripsBySearchName(keyword: String): List<Trip>
suspend fun saveTripLocal(trip: Trip)
suspend fun saveTripRemote(trip: Trip)
suspend fun deleteTrip(trip: Trip)
}
行程存储库实现:
class TripRepository (val tripDao: TripDao) : TripRepositoryContract {
override fun getTrips(): Flow<List<Trip>> {
return tripDao.getTrips();
}
override suspend fun getTripById(id: Long): Trip? {
TODO("Not yet implemented")
}
override suspend fun getTripsBySearchName(keyword: String): List<Trip> {
TODO("Not yet implemented")
}
override suspend fun saveTripLocal(trip: Trip) {
TODO("Not yet implemented")
}
override suspend fun saveTripRemote(trip: Trip) {
TODO("Not yet implemented")
}
override suspend fun deleteTrip(trip: Trip) {
TODO("Not yet implemented")
}
}
现在 hiltViewModel() 方法工作正常,但我没有得到一个MExpenseDb_impl类
我看了一下这个堆栈溢出问题:Android room persistent:app database _ Impl不存在
它说要使用保留的依赖关系,我已经有了同样的注释处理,所以我不确定这是否是一个问题
网上所有的教程要么太长
要提供TripRepository
,您需要创建一个带有Hilt's Bind函数的类。例子:
@Module
@InstallIn(SingletonComponent::class)
interface RepositoryModule {
@Binds
@Singleton
fun bindTripRepository(
repository: TripRepository // here the class
): TripRepositoryContract // here the interface that the class implements
}
还需要修改TripRepository。您必须添加@Inject构造函数()
(即使您的类不使用任何依赖项),以便Hill可以创建该类
在您的情况下,它将如下所示:
class TripRepository @Inject constructor(
val tripDao: TripDao
) : TripRepositoryContract {
// ...
}
最后一个更改是在主模块中:
@Module
@InstallIn(SingletonComponent::class)
object MainModule {
// providing the db implementation normally
@Provides
@Singleton
fun provideDb(application: Application): MExpenseDb {
return Room.databaseBuilder(
application,
MExpenseDb::class.java,
"MExpenseDb"
).build()
}
// providing your dao interface to be injected into TripRepository
@Provides
@Singleton
fun provideTripDao(
mExpenseDb: MExpenseDb
): TripDao = mExpenseDb.tripDao
}
请注意,我在Hilt的模块中从ActivityComponent
更改为SingletonComponent
,在这两种情况下,我们都希望它们在整个项目中是单例的,而不仅仅是为活动创建的组件(也可以是单例)。
请在此处查看组件生命周期。
我还建议在您的项目中升级Hilt版本,因为您使用的是非常旧的版本。最新版本是2.42
。
我认为这个视频可以帮助你更好地理解关于Hilt的一些事情。还有一个项目的存储库,它将Hilt和room结合在一起,对你的参考很有用。
重要编辑:
在TripListVm
中,您使用的是私有val tripRepository:TripRepostory
(您实现TripRepocitoryContract的类),不建议直接注入实现类,相反,您应该注入接口(TripReppositoryContrract),并让希尔特负责提供它的实现。因为这就是我们在RepositoryModule
中教希尔特做的
因此,为了使其更理想,TripListVm
将如下所示:
@HiltViewModel
class TripListVm @Inject constructor(
private val tripRepositoryContract: TripRepositoryContract
) : ViewModel() {
// ...
}
我环顾了这里和其他网站,但我想不出解决办法。 一切正常,直到我初始化中的。 我一直在犯这个错误 我有这个格里德尔 当我添加插件和时,它说它们找不到。 但那给了我这些错误 在数据库文件中,我做了如下操作: 并将所有东西连接到RoomViewModel(我也为它创建了一个工厂) 这是我做的 我认为上下文有问题,但我真的不知道。还在学习。。。 请帮帮忙
这是一个自我回答的问题,我想在早些时候问这个问题,因为我的项目中存在代表曝光问题,但经过几个小时的研究,最终还是解决了这个问题。与其保持沉默,我想这可能会对将来的人有所帮助。本教程演示了如何创建Room数据库并在活动/片段中使用它。这里给出的示例用例是查询数据库的大小并更新片段中的视图。 注意:下面的代码中有一些 Dagger-Hilt 依赖项注入,但如果您手动执行自己的依赖项注入,则应应用相同的
当我试图构建我的应用程序时,我遇到了以下编译错误: 持久性模块在Android设置中是独立的。 建筑格拉德尔 ext.androidXRoom=“2.1.0-alpha02” 我试着把kotlin版本,room版本,改回AndroidArch room,但没用。我还尝试了清理项目和使Android Studio的缓存失效。但它不起作用。 编辑:AppDatabase源
错误:查询有问题:[SQLITE_ERROR]SQL错误或缺少数据库(没有这样的表:任务) 显示了这个错误,我怎么可能修复它? 我正在学习这个教程
并且我发现了基于数据库版本4的可能场景的迁移varargs。 我的问题是,假设我使用的是db v1的Room,当我的应用程序到达db v10时,我将不得不编写多少迁移方法? 在sqlite中,我们在中获得已安装应用程序的当前db版本,我们只需通过开关大小写而不使用break语句,以便满足所有db升级。
我是新来的和我试图我的得到一个从它。我试图这样做的它与这是id但问题是我不知道如何返回目标从。 这就是<代码>刀 这是Repository类