内容提供商:ongreate()类型不匹配 - 上下文? vs上下文(kotlin)

发布于 2025-02-04 00:34:53 字数 4910 浏览 4 评论 0原文

我正在尝试在内容提供商中实现otCreate()方法,并且无法围绕我应采取的措施解决此错误:

“类型不匹配:推断类型是上下文?但是上下文是预期的

是我的数据库Handler.kt

package com.example.rewardreacher

import android.annotation.SuppressLint
import android.content.ContentValues
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.widget.Toast


const val DATABASE_NAME = "GoalDB"
const val TABLE_NAME = "Goals"
const val COL_NAME = "name"
const val COL_FREQUENCY = "frequency"
const val COL_PERFORMED = "performed"
const val COL_ID = "id"

class DatabaseHandler(var context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, 1) {


    override fun onCreate(db: SQLiteDatabase?) {
        // No DB - Then create
        val createTable = "CREATE TABLE $TABLE_NAME (" +
                "$COL_ID INTEGER PRIMARY KEY AUTOINCREMENT," +
                "$COL_NAME VARCHAR(256), " +
                "$COL_FREQUENCY INTEGER(1), " +
                "$COL_PERFORMED INTEGER(256))"

        db?.execSQL(createTable)
    }


    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        db?.execSQL("DROP TABLE IF EXISTS $DATABASE_NAME");
        onCreate(db);
    }

    fun insertData(goal : Goal) {
        val db = this.writableDatabase
        val cv = ContentValues()
        cv.put(COL_NAME, goal.name)
        cv.put(COL_FREQUENCY, goal.frequency)
        cv.put(COL_PERFORMED, goal.performed)

        val result = db.insert(TABLE_NAME, null, cv)

        if (result == (0).toLong())
            Toast.makeText(context, "Failed", Toast.LENGTH_LONG).show()
        else
            Toast.makeText(context, "Success", Toast.LENGTH_LONG).show()
    }

    @SuppressLint("Range")
    fun readData() : MutableList<Goal> {
        val list: MutableList<Goal> = ArrayList()

        val db = this.readableDatabase
        val query = "Select * from $TABLE_NAME"
        val result = db.rawQuery(query, null)
        if (result.moveToFirst()) {
            do {
                val goal = Goal()
                goal.id = result.getString(result.getColumnIndex(COL_ID)).toInt()
                goal.name = result.getString(result.getColumnIndex(COL_NAME))
                goal.frequency = result.getString(result.getColumnIndex(COL_FREQUENCY)).toInt()
                goal.performed = result.getString(result.getColumnIndex(COL_PERFORMED)).toInt()
                list.add(goal)
            } while (result.moveToNext())
        }

        result.close()
        db.close()
        return list
    }


}

和myContentProvider.kt

package com.example.rewardreacher.provider

import android.content.ContentProvider
import android.content.ContentValues
import android.content.UriMatcher
import android.database.Cursor
import android.net.Uri
import com.example.rewardreacher.DatabaseHandler

const val DATABASE_NAME = "GoalDB"
const val GOALS_TABLE = "Goals"
const val COL_NAME = "name"
const val COL_FREQUENCY = "frequency"
const val COL_PERFORMED = "performed"
const val COL_ID = "id"

class MyContentProvider : ContentProvider() {

    private var dbHandler: DatabaseHandler? = null


    override fun onCreate(): Boolean {
        dbHandler =  DatabaseHandler(context)
        return false
    }

    private val GOALS = 1
    private val GOALS_ID = 2

    private val sURIMatcher = UriMatcher(UriMatcher.NO_MATCH)

    init {
        sURIMatcher.addURI(AUTHORITY, GOALS_TABLE, GOALS)
        sURIMatcher.addURI(AUTHORITY, GOALS_TABLE + "/#",
            GOALS_ID)
    }

    companion object {
        val AUTHORITY = "com.example.rewardreacher.provider.MyContentProvider"
        val CONTENT_URI : Uri = Uri.parse("content://" + AUTHORITY + "/" +
                GOALS_TABLE)
    }

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
        TODO("Implement this to handle requests to delete one or more rows")
    }

    override fun getType(uri: Uri): String? {
        TODO(
            "Implement this to handle requests for the MIME type of the data" +
                    "at the given URI"
        )
    }

    override fun insert(uri: Uri, values: ContentValues?): Uri? {
        TODO("Implement this to handle requests to insert a new row.")
    }

    override fun query(
        uri: Uri, projection: Array<String>?, selection: String?,
        selectionArgs: Array<String>?, sortOrder: String?
    ): Cursor? {
        TODO("Implement this to handle query requests from clients.")
    }

    override fun update(
        uri: Uri, values: ContentValues?, selection: String?,
        selectionArgs: Array<String>?
    ): Int {
        TODO("Implement this to handle requests to update one or more rows.")
    }
}

我从未在Android Studio / Kotlin中工作,我想这可能是一个简单的解决方案,但我似乎无法修复它。 ..

I am trying to implement the onCreate() method in my Content provider and can't wrap my head around what I should do to resolve this error:

"Type mismatch: inferred type is Context? but Context was expected

Here is my DatabaseHandler.kt

package com.example.rewardreacher

import android.annotation.SuppressLint
import android.content.ContentValues
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.widget.Toast


const val DATABASE_NAME = "GoalDB"
const val TABLE_NAME = "Goals"
const val COL_NAME = "name"
const val COL_FREQUENCY = "frequency"
const val COL_PERFORMED = "performed"
const val COL_ID = "id"

class DatabaseHandler(var context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, 1) {


    override fun onCreate(db: SQLiteDatabase?) {
        // No DB - Then create
        val createTable = "CREATE TABLE $TABLE_NAME (" +
                "$COL_ID INTEGER PRIMARY KEY AUTOINCREMENT," +
                "$COL_NAME VARCHAR(256), " +
                "$COL_FREQUENCY INTEGER(1), " +
                "$COL_PERFORMED INTEGER(256))"

        db?.execSQL(createTable)
    }


    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        db?.execSQL("DROP TABLE IF EXISTS $DATABASE_NAME");
        onCreate(db);
    }

    fun insertData(goal : Goal) {
        val db = this.writableDatabase
        val cv = ContentValues()
        cv.put(COL_NAME, goal.name)
        cv.put(COL_FREQUENCY, goal.frequency)
        cv.put(COL_PERFORMED, goal.performed)

        val result = db.insert(TABLE_NAME, null, cv)

        if (result == (0).toLong())
            Toast.makeText(context, "Failed", Toast.LENGTH_LONG).show()
        else
            Toast.makeText(context, "Success", Toast.LENGTH_LONG).show()
    }

    @SuppressLint("Range")
    fun readData() : MutableList<Goal> {
        val list: MutableList<Goal> = ArrayList()

        val db = this.readableDatabase
        val query = "Select * from $TABLE_NAME"
        val result = db.rawQuery(query, null)
        if (result.moveToFirst()) {
            do {
                val goal = Goal()
                goal.id = result.getString(result.getColumnIndex(COL_ID)).toInt()
                goal.name = result.getString(result.getColumnIndex(COL_NAME))
                goal.frequency = result.getString(result.getColumnIndex(COL_FREQUENCY)).toInt()
                goal.performed = result.getString(result.getColumnIndex(COL_PERFORMED)).toInt()
                list.add(goal)
            } while (result.moveToNext())
        }

        result.close()
        db.close()
        return list
    }


}

And MyContentProvider.kt

package com.example.rewardreacher.provider

import android.content.ContentProvider
import android.content.ContentValues
import android.content.UriMatcher
import android.database.Cursor
import android.net.Uri
import com.example.rewardreacher.DatabaseHandler

const val DATABASE_NAME = "GoalDB"
const val GOALS_TABLE = "Goals"
const val COL_NAME = "name"
const val COL_FREQUENCY = "frequency"
const val COL_PERFORMED = "performed"
const val COL_ID = "id"

class MyContentProvider : ContentProvider() {

    private var dbHandler: DatabaseHandler? = null


    override fun onCreate(): Boolean {
        dbHandler =  DatabaseHandler(context)
        return false
    }

    private val GOALS = 1
    private val GOALS_ID = 2

    private val sURIMatcher = UriMatcher(UriMatcher.NO_MATCH)

    init {
        sURIMatcher.addURI(AUTHORITY, GOALS_TABLE, GOALS)
        sURIMatcher.addURI(AUTHORITY, GOALS_TABLE + "/#",
            GOALS_ID)
    }

    companion object {
        val AUTHORITY = "com.example.rewardreacher.provider.MyContentProvider"
        val CONTENT_URI : Uri = Uri.parse("content://" + AUTHORITY + "/" +
                GOALS_TABLE)
    }

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
        TODO("Implement this to handle requests to delete one or more rows")
    }

    override fun getType(uri: Uri): String? {
        TODO(
            "Implement this to handle requests for the MIME type of the data" +
                    "at the given URI"
        )
    }

    override fun insert(uri: Uri, values: ContentValues?): Uri? {
        TODO("Implement this to handle requests to insert a new row.")
    }

    override fun query(
        uri: Uri, projection: Array<String>?, selection: String?,
        selectionArgs: Array<String>?, sortOrder: String?
    ): Cursor? {
        TODO("Implement this to handle query requests from clients.")
    }

    override fun update(
        uri: Uri, values: ContentValues?, selection: String?,
        selectionArgs: Array<String>?
    ): Int {
        TODO("Implement this to handle requests to update one or more rows.")
    }
}

I never work in android studio / kotlin and I guess it is probably a simple solution but I can't seem to fix it...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

嘿哥们儿 2025-02-11 00:34:53

您用于创建数据库Handler的上下文具有无效的注释。

public final @Nullable Context getContext() {
    return mContext;
}

因此,您可以通过制作数据库Handler上下文来修复它

class DatabaseHandler(var context: Context?)

,也可以在实例化数据库Handler之前添加NULL检查:

override fun onCreate(): Boolean {
        dbHandler = context?.let { DatabaseHandler(it) }
        return false
    }

The context that you use to create databaseHandler has a nullable annotation.

public final @Nullable Context getContext() {
    return mContext;
}

So you can fix it by making the databaseHandler context nullable

class DatabaseHandler(var context: Context?)

Or you can add a null check before instantiating the databaseHandler :

override fun onCreate(): Boolean {
        dbHandler = context?.let { DatabaseHandler(it) }
        return false
    }
伤感在游骋 2025-02-11 00:34:53

上下文返回一个无效的上下文(a 上下文?),因为它在increate()之前的生命周期为null。根据文档 ,它不再为空,因此可以安全地主张!!

另外,如果没有问题,则应从ongreate返回true

override fun onCreate(): Boolean {
    dbHandler =  DatabaseHandler(context!!)
    return true
}

context returns a nullable Context (a Context?) because it's null in the lifecycle before onCreate(). According to the documentation, inside onCreate(), it is no longer null, so it is safe to assert non-null with !!.

Also, you should be returning true from onCreate if there wasn't a problem.

override fun onCreate(): Boolean {
    dbHandler =  DatabaseHandler(context!!)
    return true
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文