一、AsyncQueryHandler的使用
该类是谷歌封装的异步查询的Handler,这个类是抽象类但是其并没有抽象方法。具体使用方法如下所示:
package com.study.yang.contentproviderclientdemo.handler
import android.content.AsyncQueryHandler
import android.content.ContentResolver
import android.database.Cursor
import com.study.yang.contentproviderserverdemo.adapter.MyCursorAdapter
class MyAsyncQueryHandler(cr: ContentResolver) : AsyncQueryHandler(cr) {
/**
* 当查询完成之后,自动调用该方法
*/
override fun onQueryComplete(token: Int, cookie: Any?, cursor: Cursor?) {
super.onQueryComplete(token, cookie, cursor)
//判断当前的cookie类型是否是MyCursorAdapter
if (cookie is MyCursorAdapter) {
var cursorAdapter = cookie
cursorAdapter.changeCursor(cursor)
println(cursor)
}
}
}
二、CursorAdapter的使用
该类将Cursor跟适配器相结合,当Cursor中的数据改动后进行自动刷新。具体使用方法如下所示:
package com.study.yang.contentproviderserverdemo.adapter
import android.content.Context
import android.database.Cursor
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CursorAdapter
import android.widget.TextView
import com.study.yang.contentproviderclientdemo.R
class MyCursorAdapter(context: Context?, cursor: Cursor?) : CursorAdapter(context, cursor, true) {
/**
* 当内容发生改变的时候调用该方法
*/
override fun onContentChanged() {
super.onContentChanged()
println("数据更新了")
}
/**
* 创建View的实例时调用
*/
override fun newView(context: Context?, cursor: Cursor?, parent: ViewGroup?): View {
val view = LayoutInflater.from(context).inflate(R.layout.item_layout, null)
var viewHolder = ViewHolder()
viewHolder.tv_name = view.findViewById(R.id.tv_name)
viewHolder.tv_age = view.findViewById(R.id.tv_age)
viewHolder.tv_description = view.findViewById(R.id.tv_description)
view.tag = viewHolder
return view
}
override fun bindView(view: View?, context: Context?, cursor: Cursor?) {
val viewHolder = view?.tag as ViewHolder
val name = cursor?.getString(cursor?.getColumnIndex("name"))
val age = cursor?.getString(cursor?.getColumnIndex("age"))
val description = cursor?.getString(cursor?.getColumnIndex("description"))
viewHolder.tv_name.text = name
viewHolder.tv_age.text = age
viewHolder.tv_description.text = description
}
class ViewHolder {
lateinit var tv_name: TextView
lateinit var tv_age: TextView
lateinit var tv_description: TextView
}
}
三、ContentProvider的使用
Android的四大组件之一,在此处就不用详细介绍了。具体使用方法如下所示:
package com.study.yang.contentproviderserverdemo.provider
import android.content.ContentProvider
import android.content.ContentUris
import android.content.ContentValues
import android.content.UriMatcher
import android.database.Cursor
import android.net.Uri
import com.study.yang.contentproviderserverdemo.database.DBHelper
class UserContentProvider : ContentProvider() {
var matcher = UriMatcher(UriMatcher.NO_MATCH)
lateinit var dbHelper: DBHelper
var table_name = "user"
//代码块将在构造方法之前执行
init {
//添加匹配码,添加
matcher.addURI("com.study.user.provider", "/user/insert", 1)
//添加匹配码,删除
matcher.addURI("com.study.user.provider", "/user/delete", 2)
//添加匹配码,更新
matcher.addURI("com.study.user.provider", "/user/update", 3)
//添加匹配码,查询
matcher.addURI("com.study.user.provider", "/user/query", 4)
}
/**
* 初始化的时候使用
*/
override fun onCreate(): Boolean {
dbHelper = DBHelper(context)
return true
}
//用when代替switch
override fun getType(uri: Uri): String? =
when {
matcher.match(uri) == 1 -> "添加"
matcher.match(uri) == 2 -> "删除"
matcher.match(uri) == 3 -> "更新"
matcher.match(uri) == 4 -> "查询"
else -> ""
}
/**
* 可以根据传入uri的参数来针对处理相应的数据
*/
override fun insert(uri: Uri, values: ContentValues): Uri? {
val db = dbHelper.writableDatabase
val insert = db.insert(table_name, null, values)
var insertAfterUri = ContentUris.withAppendedId(uri, insert)
// db.close() //不能够关闭,否则达不到自动更新的效果
//向外界通知数据发生了变化
context.contentResolver.notifyChange(uri, null)
return insertAfterUri
}
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
val db = dbHelper.writableDatabase
val deleteCount = db.delete(table_name, selection, selectionArgs)
// db.close()
//向外界通知数据发生了变化
context.contentResolver.notifyChange(uri, null)
return deleteCount
}
override fun update(uri: Uri, values: ContentValues?, selection: String?,
selectionArgs: Array<String>?): Int {
val db = dbHelper.writableDatabase
val updateCount = db.update(table_name, values, selection, selectionArgs)
// db.close() //不能够关闭,否则达不到自动更新的效果
//向外界通知数据发生了变化
context.contentResolver.notifyChange(uri, null)
return updateCount
}
override fun query(uri: Uri, projection: Array<String>?, selection: String?,
selectionArgs: Array<String>?, sortOrder: String?): Cursor? {
val db = dbHelper.writableDatabase
val cursor = db.query(table_name, projection, selection, selectionArgs, "", "", sortOrder)
cursor.setNotificationUri(context.contentResolver, uri)
// db.close() //不能够关闭,否则达不到自动更新的效果
return cursor
}
}
四、运行截图
4.1 ContentProviderServerDemo运行截图
4.2 ContentProviderClientDemo运行截图
五、项目源码
注意:因为是进程间的通信,所以ContentProviderClientDemo想要获得ContentProviderServerDemo的数据的话ContentProviderServerDemo的进程必须是启动的