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

时间:2015-05-20 02:32:39

标签: android kotlin

我尝试用Kotlin编写应用程序。我把contentprovider查询sql放在另一个进程上。在主进程中通过ContentResolver查询时,应用程序崩溃了。

代码是:

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.access$800(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  

2 个答案:

答案 0 :(得分:11)

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

答案 1 :(得分:1)

旧帖子,但我希望有人会发现它有用。当我将内容提供者迁移到Kotlin时,遇到了同样的异常,这是因为游标工厂为null。在Java中允许为null,并且Java doc声明默认工厂使用null,但在Kotlin中禁止使用null,因此我最终创建了如下的自定义光标工厂:

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
}