我尝试用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
答案 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
}