1

I am trying some android development with kotlin. In my case I want to overwrite: ContentProvider where I have to overwrite the function "query". "query" returns "Cursor" type. However, when I create the Cursor instance in the function with database.query I get back a "Cursor?" type. So I can only return Cursor if it is not null, but what do I do if it is null?

This is what it basically looks like:

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?

Any Ideas how to solve that?

Thanks, Sven

UPDATE First of all thanks for the answers.

Annotation seems not to work in my case as I can only access the compiled code and I dont get the option to annotate the source. Maybe I am missing something here.

Implementing my own cursor Seems like overkill especially if I have to do it every time that problem occurs.

So it seems my only option is to return cursor!! But I dont know how exactly to do it. My code is a bit more complicated than in my example, I missed a when statement. This is an updated version:

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
}

Do I really have to implement my own cursor and clutter my code with useless "throw UnsupportedExceptions"?

4

5 回答 5

1

您的选择是:

  • 如果cursornull,则抛出异常:(return cursor!!如果您确定这cursor实际上从未null
  • 如果cursornull,则返回一些微不足道的游标(例如,您自己的实现AbstractCursor表现为空结果集
  • (正如弗兰克在他的评论中所说)将QueryBuilder.query()函数注释为@NotNullhttp ://blog.jetbrains.com/kotlin/using-external-annotations/
于 2014-05-30T05:39:28.347 回答
1

围绕这个主题构建了一些库:

Kotlin的Result库提供了一种很好的方法来处理基于响应值的“做这个或那个”的情况。并有一个真正的回应和一个例外或无效的回应,这就是你所寻求的。

对于 Promises,您可以在Kovenant库中找到相同的内容。有了 Kovenant,promise 可以立即解决,而不必是异步的。所以它作为一个通用的“我有一个结果,或者没有”库。

// ... 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 并不总是必须将错误作为失败类型。它们可以是你想要的任何东西。错误代码、错误消息、数据类或异常(如果您愿意)。

这两个库都为您提供了从单个函数返回替代结果以及基于结果分支代码的方式

这些是 和 的良好 Kotlin 替代OptionalMaybe

使用空值也很好,在这些情况下有许多运算符可以帮助处理空值。 在 Kotlin 中,处理可空值、引用或转换它们的惯用方式是什么,这是另一篇 SO 帖子,涵盖可空性,一般解释一些可用的运算符(包括此处某些答案中使用的“安全调用”运算符)。

于 2015-12-29T20:29:32.157 回答
0
if (db != null){
    //...
} else {
    return null
}

并将返回类型放入光标?

这就是我通常的做法。不知道是好是坏。

于 2017-06-29T17:20:35.203 回答
-1

可能您可以将函数 end : Cursor 更新为 : Cursor?例子:

override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor? {}
于 2020-12-09T12:55:50.490 回答
-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()
}
于 2014-09-30T12:32:20.640 回答