Sim*_*ler 5 android delegates kotlin android-room
我目前正在使用Kotlin开发一个新的android应用。我尝试实现Room来进行数据存储,但没有与Kotlin代表一起使用。
我创建了一个Identifier委托,以确保初始化后ID不变。委托看起来像这样:
class Identifier: ReadWriteProperty<Any?, Long> {
private var currentValue = -1L
override fun getValue(thisRef: Any?, property: KProperty<*>): Long {
if (currentValue == -1L) throw IllegalStateException("${property.name} is not initialized.")
return currentValue
}
override fun setValue(thisRef: Any?, property KProperty<*>, value: Long) {
if (currentValue != -1L) throw IllegalStateException("${property.name} can not be changed.")
currentValue = value
}
}
Run Code Online (Sandbox Code Playgroud)
我的实体类如下所示:
@Entity
class Sample {
@delegate:PrimaryKey(autoGenerate = true)
var id by Identifier()
}
Run Code Online (Sandbox Code Playgroud)
当我尝试启动应用程序时,kapt提示我以下错误消息:
Cannot figure out how to save this field into database. You can consider adding a type converter for it.
private final com.myapp.persistence.delegates.Identifier id$delegate = null;
Run Code Online (Sandbox Code Playgroud)
我能以某种方式使它工作而不用TypeConverter为每个代表写一个吗?
use*_*613 17
使用@delegate:Ignore.
我的实体对象和... by lazy属性也有类似的问题。
例如:
var name: String = "Alice"
val greeting: String by lazy { "Hi $name" }
Run Code Online (Sandbox Code Playgroud)
这里的问题是 Room“无法弄清楚如何将此字段保存到数据库中”。我尝试添加“@Ignore”,但收到一条 lint 消息,提示“此注释不适用于目标‘带委托的成员属性’。”
事实证明,在这种情况下正确的注释是@delegate:Ignore.
解决方案:
var name: String = "Alice"
@delegate:Ignore
val greeting: String by lazy { "Hi $name" }
Run Code Online (Sandbox Code Playgroud)
不幸的是,没有 - Room默认情况下为实体中定义的每个字段创建一列,当我们使用时,delegate我们会得到如下生成的代码:
@PrimaryKey(autoGenerate = true)
@NotNull
private final Identifier id$delegate = new Identifier();
public final long getId() {
return this.id$delegate.getValue(this, $$delegatedProperties[0]);
}
public final void setId(long var1) {
this.id$delegate.setValue(this, $$delegatedProperties[0], var1);
}
Run Code Online (Sandbox Code Playgroud)
这就是为什么 Room 尝试为Identifier id$delegate.
但是,如果您只是想确保id在对象初始化后不发生更改,则根本不需要委托,只需将变量标记为final并将其放置在构造函数中,例如:
@Entity
data class Sample(
@PrimaryKey(autoGenerate = true)
val id: Long
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
349 次 |
| 最近记录: |