将 kotlin 与 ContentResolver 一起使用会导致 IllegalArgumentException

Using kotlin with ContentResolver caused IllegalArgumentException

我正在尝试使用 Kotlin 编写应用程序。我将内容提供者查询 sql 放在另一个进程上。主进程ContentResolver查询时,App崩溃

密码是:

protected fun select(uri: Uri, sql: String, vararg args: Any): Cursor {
    val sArgs = Array(args.size(), { i -> lang.String.valueOf(args.get(i)) })
    return context.getContentResolver().query(uri, null, sql, sArgs, null)
}

public fun selectAllAccounts(): Array<Account> {
    val cursor = select(parseUri(AccountSchema.TABLE_NAME), "select * from " + AccountSchema.TABLE_NAME)
    val accounts = Array(cursor.getCount(), { i ->
        if (!cursor.moveToPosition(i)) {
            throw RuntimeException("Cursor move failed")
        }
        Account(context, cursor)
    })
    return accounts
}

它将抛出 IllegalArgumentException:

05-20 10:27:21.120    3337-3337/com.kescoode.yomail E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.kescoode.yomail, PID: 3337
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.kescoode.yomail/com.kescoode.yomail.ui.activity.HomeActivity}: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter projection
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2212)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2271)
        at android.app.ActivityThread.access0(ActivityThread.java:144)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1205)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5146)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter projection
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:167)
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
        at android.content.ContentProviderProxy.query(ContentProviderNative.java:420)
        at android.content.ContentResolver.query(ContentResolver.java:461)
        at android.content.ContentResolver.query(ContentResolver.java:404)
        at com.kescoode.yomail.db.Dao.select(internal.kt:33)
        at com.kescoode.yomail.db.AccountDao.selectAllAccounts(AccountDao.kt:21)
        at com.kescoode.yomail.App.isLogged(App.kt:28)
        at com.kescoode.yomail.ui.activity.HomeActivity.onCreate(HomeActivity.kt:17)
        at android.app.Activity.performCreate(Activity.java:5231)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2169  

默认情况下,Kotlin 中的所有变量和参数都是非空的。您正在将一个空参数传递给您的函数。如果要传递 null 参数,则需要将 ? 符号添加到参数的类型中,例如 uri: Uri?。但更好的方法是检查您要传递给函数的参数是否为 null 并处理这种情况。 有关更多信息,您可以查看这篇文章 http://kotlinlang.org/docs/reference/null-safety.html

旧 post 但我希望有人会发现它有用。将我的内容提供程序迁移到 Kotlin 时,我遇到了同样的异常,这是因为游标工厂为空。它在 Java 和 java 文档中被允许为 null 与 null 用于默认工厂相同,但在 Kotlin 中被禁止,所以我最终创建了如下自定义游标工厂:

class DatabaseCursorFactory : SQLiteDatabase.CursorFactory {

    override fun newCursor(db: SQLiteDatabase?, driver: SQLiteCursorDriver?, editTable: String?, query: SQLiteQuery?): Cursor {
        return SQLiteCursor(driver, editTable, query)
    }
}

然后在ContentProvider中使用:

override fun onCreate(): Boolean {
    mDatabaseOpenHelper = DatabaseOpenHelper(context, DB_NAME, DatabaseCursorFactory(), DB_VERSION)
    return true
}