我正在尝试使用kotlin进行一些android开发。在我的情况下,我想覆盖:ContentProvider,我必须覆盖函数"查询"。 "查询"返回"光标"类型。但是,当我在带有database.query的函数中创建Cursor实例时,我得到一个" Cursor?"类型。所以我只能返回Cursor,如果它不是null,但如果它是null,我该怎么办?
这基本上就是这样:
override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor {
val cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder)
// make sure that potential listeners are getting notified
cursor?.setNotificationUri(getContext()?.getContentResolver(), uri)
if(cursor != null)
return cursor
else
// what to do here?
任何想法如何解决?
谢谢, 斯文
更新 首先感谢答案。
注释似乎不能在我的情况下工作,因为我只能访问已编译的代码,我没有选择注释源。也许我在这里遗漏了一些东西。
实现我自己的光标看起来有点矫枉过正,特别是每次出现问题时我都必须这样做。
所以看来我唯一的选择是返回光标!!但我不知道究竟是怎么做到的。我的代码比我的例子复杂一点,我错过了一个when语句。这是一个更新版本:
override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor {
val cursor = ??? //how to initialize cursor somehow?
val db = database.getWritableDatabase()
if(db != null) {
val cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder)
// make sure that potential listeners are getting notified
cursor?.setNotificationUri(getContext()?.getContentResolver(), uri)
if(cursor != null)
return cursor
}
// return what here? cursor does not exist
}
我是否真的必须实现自己的光标并使我的代码混乱无用&#34;抛出UnsupportedExceptions&#34;?
答案 0 :(得分:1)
您的选择是:
cursor
为null
,则抛出异常:return cursor!!
(如果您确定cursor
实际上从未null
cursor
为null
,请返回一些微不足道的光标(例如您自己的AbstractCursor
实现,其行为为空结果集QueryBuilder.query()
函数注释为@NotNull
:http://blog.jetbrains.com/kotlin/using-external-annotations/ 答案 1 :(得分:1)
围绕这个主题建立了一些库:
Kotlin的Result库提供了一种很好的方法来处理基于响应值“执行此操作”的情况。并且要获得真正的回应以及您正在寻求的异常或无效响应。
对于Promises,您可以在Kovenant库中找到相同的内容。随着Kovenant承诺可以立即解决,而不必是异步。所以它作为一般用途“我有一个结果,或没有”库。
// ... in my function that returns Promise<Cursor, String>
if (good) {
return Promise.ofSuccess<Cursor, String>(cursor)
}
else {
return Promise.ofFail<Cursor, String>("no database connection")
}
然后在函数的调用者中:
myFuncMakingACursor() success { cursor ->
//called when all is ok, and I have a cursor
} fail {
//called when promise is rejected
} always {
//no matter what result we get, this is always called once.
}
Promise并不总是必须有错误作为失败类型。它们可以是你想要的任何东西。如果您愿意,可以输入错误代码,错误消息,数据类或异常。
这两个库都为您提供了从单个函数返回替代结果的方式,以及根据结果分支代码的方式
这些是Optional
和Maybe
的好Kotlin替代品。
使用空值也很好,并且在这些情况下有许多运算符可以帮助处理空值。 In Kotlin, what is the idiomatic way to deal with nullable values, referencing or converting them是另一个涵盖可空性的SO帖子,一般性地解释了一些可用的运算符(包括这里的一些答案中使用的“安全呼叫”运算符)。
答案 2 :(得分:0)
if (db != null){
//...
} else {
return null
}
并将返回类型设置为Cursor?
这就是我通常做的事情。不知道它是坏还是坏。
答案 3 :(得分:-1)
也许可以将功能end:Cursor更新为:Cursor? 例如:
override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor? {}
答案 4 :(得分:-3)
实际上有一个hack允许你欺骗Kotlin编译器接受null
作为非可空引用。
<强> NullHack.java 强>:
public class NullHack {
private NullHack() {
}
@SuppressWarnings("ConstantConditions")
@NotNull
public static <T> T nullHack(@Nullable T object) {
return object;
}
}
<强> NullHack.kt 强>:
fun <T> T?.nullHack(): T = NullHack.nullHack(this)
然后在ContentProvider
子类中,您可以编写以下代码:
override fun query(uri: Uri, projection: Array<out String>?, selection: String?,
selectionArgs: Array<out String>?, sortOrder: String?): Cursor {
val db = database.getWritableDatabase()!!
val cursor = queryBuilder.query(db, projection, selection, selectionArgs,
null, null, sortOrder)
// make sure that potential listeners are getting notified
cursor?.setNotificationUri(getContext()?.getContentResolver(), uri)
return cursor.nullHack()
}