Android Kotlin语言学习第三课:自定义ContentProvider和SQlite学习增删改查

发布时间:2023-06-09 19:30

一:创建主界面增删改查

/**
 * @author zhiqiangRuan
 * @ClassName
 * @Date  2022/7/4
 */
class FiveActivity : BaseActivity(), View.OnClickListener {
    lateinit var addData: Button
    lateinit var deleteData: Button
    lateinit var queryData: Button
    lateinit var updataData: Button
    var bookId: String? = null
    override fun initView() {
        addData = findViewById

Android Kotlin语言学习第三课:自定义ContentProvider和SQlite学习增删改查_第1张图片
二:Xml文件




    

三:自定义的MyProvider

package com.cnstrong.leke.helloworld

import android.content.ContentProvider
import android.content.ContentValues
import android.content.UriMatcher
import android.net.Uri
import java.lang.RuntimeException

/**
 * @author zhiqiangRuan
 * @ClassName 自定义ContentProvider
 * @Date  2022/7/4
 */
class MyProvider : ContentProvider() {

    private val bookDir = 0
    private val bookItem = 1

    private val categoryDir = 2
    private val categoryItem = 3

    /**
     * 每一个ContentProvider定义唯一标识URI  URI*/
    private var dbHelper: MySqliteDataHelper? = null

    private val authority = "com.cnstrong.leke.helloworld.provider"

    /**UriMatcher本质上是一个文本过滤器,用在contentProvider中帮助我们过滤,分辨出查询者想要查询哪个数据表。*/
    private val uriMatcher by lazy {
        //常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
        val mathcher = UriMatcher(UriMatcher.NO_MATCH)
        //如果match()方法匹配content://com.cnstrong.leke.helloworld.provider/book路径,返回匹配码为1
        mathcher.addURI(authority, "book", bookDir)
        //如果match()方法匹配content://com.cnstrong.leke.helloworld.provider/book/通配符 路径,返回匹配码为2
        mathcher.addURI(authority, "book/#", bookItem)

        mathcher.addURI(authority, "category", categoryDir)
        mathcher.addURI(authority, "category/#", categoryItem)
        mathcher
    }

    /**创建数据*/
    /**
     * override fun onCreate(): Boolean {
    dbHelper = context?.let {
    MySqliteDataHelper(it, "BookStore.db", 1)
    return true
    }
    return false

    ------------------------------
    这里用到了Kotlin let操作符
    obj.let{} 或obj?.let{}
    第一种写法,如果确定obj不为null,可以使用,
    第二种写法相当于java的非空判断,当obj不为空时,才执行大括号内的代码段,相对java的空判断来说简洁一些,值得使用。
    //在函数体内使用it替代object对象去访问其公有的属性和方法
    } */
    override fun onCreate() = context?.let {
        MySqliteDataHelper(it, "BookStore.db", 1)
        true
    } ?: false


    /**查询数据*/

    override fun query(
        uri: Uri,
        projection: Array?,
        selection: String?,
        selectionArgs: Array?,
        sortOrder: String?
    ) = dbHelper?.let {
        //查询数据
        val db = it.writableDatabase
        val cursor = when (uriMatcher.match(uri)) {
            bookDir -> db.query("Book", projection, selection, selectionArgs, null, null, sortOrder)
            bookItem -> {
                val bookId = uri.pathSegments[1]
                db.query("Book", projection, "id=?", arrayOf(bookId), null, null, sortOrder)
            }
            categoryDir -> db.query(
                "Category",
                projection,
                selection,
                selectionArgs,
                null,
                null,
                sortOrder
            )
            categoryItem -> {
                val categoryId = uri.pathSegments[1]
                db.query("Category", projection, "id=?", arrayOf(categoryId), null, null, sortOrder)
            }
            else->null
        }
        cursor

    }

    /**
     * 得到数据类型*/

    override fun getType(uri: Uri) = when (uriMatcher.match(uri)) {
        bookDir -> "vnd.android.cursor.dir/vnd.com.cnstrong.leke.helloworld.provider.book"
        bookItem -> "vnd.android.cursor.item/vnd.com.cnstrong.leke.helloworld.provider.book"
        categoryDir -> "vnd.android.cursor.dir/vnd.com.cnstrong.leke.helloworld.provider.category"
        categoryItem -> "vnd.android.cursor.item/vnd.com.cnstrong.leke.helloworld.provider.category"
        else -> null
    }

    /**插入数据
     *
     *  override fun insert(uri: Uri, values: ContentValues?): Uri? {
    //获取到SQLiteDatabase 对象
    val db = dbHelper?.writableDatabase
    val uriReturn = when (uriMatcher.match(uri)) {
    bookDir, bookItem -> {
    val newBookId = db?.insert("Book", null, values)
    Uri.parse("content://$authority/book/$newBookId")
    }
    categoryDir, categoryItem -> {
    val newCategoryId = db?.insert("Category", null, values)
    Uri.parse("content://$authority/category/$newCategoryId")
    }
    else -> null
    }
    return uriReturn


    }*/

    override fun insert(uri: Uri, values: ContentValues?) = dbHelper?.let {
        //获取到SQLiteDatabase 对象
        val db = it.writableDatabase
        val uriReturn = when (uriMatcher.match(uri)) {
            bookDir, bookItem -> {
                val newBookId = db.insert("Book", null, values)
                Uri.parse("content://$authority/book/$newBookId")
            }
            categoryDir, categoryItem -> {
                val newCategoryId = db.insert("Category", null, values)
                Uri.parse("content://$authority/category/$newCategoryId")
            }
            else ->null
        }
        uriReturn


    }

    /**删除数据*/

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array?) =
        dbHelper?.let {
            //删除数据
            val db = it.writableDatabase
            val deleteRows = when (uriMatcher.match(uri)) {
                bookDir -> db.delete("Book", selection, selectionArgs)
                bookItem -> {
                    //筛选条件参数
                    val bookId = uri.pathSegments[1]
                    db.delete("Book", "id=?", arrayOf(bookId))
                }
                categoryDir -> db.delete("Category", selection, selectionArgs)
                categoryItem -> {
                    val categoryId = uri.pathSegments[1]
                    db.delete("Category", "id=?", arrayOf(categoryId))
                }
                else -> 0
            }
            deleteRows

        } ?: 0

    /**更新数据*/

    override fun update(
        uri: Uri,
        values: ContentValues?,
        selection: String?,
        selectionArgs: Array?
    ) = dbHelper?.let {
        val db = it.writableDatabase
        val updateRows = when (uriMatcher.match(uri)) {
            bookDir -> db.update("Book", values, selection, selectionArgs)
            bookItem -> {
                val bookId = uri.pathSegments[1]
                db.update("Book", values, "id=?", arrayOf(bookId))
            }
            categoryDir -> db.update("Category", values, selection, selectionArgs)
            categoryItem -> {
                val categoryId = uri.pathSegments[1]
                db.update("Category", values, "id=?", arrayOf(categoryId))
            }
            else -> 0
        }
        updateRows

    } ?: 0
}

四:MySqliteDataHelper 数据库创建的帮助类

package com.cnstrong.leke.helloworld

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.widget.Toast

/**
 * @author zhiqiangRuan
 * @ClassName
 * kotlin 构造函数 参数
 * val context: Context 上下文
 * name: String  数据库名,库名 xxx.db
 * version: Int 版本号,用来数据库升级的
 * @Date  2022/7/4
 */
class MySqliteDataHelper(val context: Context, name: String, version: Int) :
    SQLiteOpenHelper(context, name, null, version) {

    private val book = "create table Book( " +
            "id integer primary key autoincrement," +
            "author text," +
            "price real," +
            "pages integer," +
            "name text)"


    private val category = "create table Category( " +
            "id integer primary key autoincrement," +
            "category_name text," +
            "category_code integer)"


    /**使用SQliteDatabase创建数据表
     *
     * 1.这个方法,第一次打开数据库时候才会走
     * 2.在清除数据之后再一次运行-->打开数据库,这个方法会走
     * 3.没有清除数据,不会走这个方法
     * 4.数据库升级的时候这个方法不会走
     * */
    override fun onCreate(db: SQLiteDatabase?) {
        db?.execSQL(book)
        db?.execSQL(category)
        Toast.makeText(context, "create books success", Toast.LENGTH_SHORT).show()

    }


    /**
     * 1.第一次创建数据库的时候,这个方法不会走
     *
     *2.清除数据再次运行(相当于第一次创建)这个方法不会走
     *
     * 3.数据库已经存在,而且版本升高的时候,这个方法才会调用*/
    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        //根据版本号判断
        if (oldVersion <= 1) {
            db?.execSQL("alter table Book add column category_id")
        }
    }


    /**这个方法是数据库降级操作
     *
     * 1.新版本比旧版本低时候才会执行
     *
     * 2.如果不执行降级操作会抛出异常*/

    override fun onDowngrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        super.onDowngrade(db, oldVersion, newVersion)
    }
}

五:MyProvider的AndroidManifest配置




    
    
    
    

    
        
            
                

                
            
        
        
        

        

        
    

六:遇到的问题
Android Kotlin语言学习第三课:自定义ContentProvider和SQlite学习增删改查_第2张图片

不知道什么原因,有大神知道吗,需要指导一下

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号