ContentProvider的使用,以及工作原理

什么是ContentProvider?

ContentProvider是Android4大组件之一,我们平时使用的机会可能比较少。其底层通过Binder进行数据共享。如果我们要对第三方应用提供数据,可以考虑使用ContentProvider实现。

如何使用

与其他的ContentProvider通信。

要实现与其他的ContentProvider通信首先要查找到对应的ContentProvider进行匹配。android中ContenProvider借助ContentResolver通过Uri与其他的ContentProvider进行匹配通信。

认识Uri 来自:https://www.cnblogs.com/tgyf/p/4696288.html

URI为系统中的每一个资源赋予一个名字,比方说通话记录。每一个ContentProvider都拥有一个公共的URI,用于表示ContentProvider所提供的数据。 Android所提供的ContentProvider都位于android.provider包中, 可以将URI分为A、B、C、D 4个部分来理解。如对于content://com.wang.provider.myprovider/tablename/id:

a、标准前缀——content://,用来说明一个Content Provider控制这些数据;

b、URI的标识——com.wang.provider.myprovider,用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的类名。这个标识在元素的authorities属性中说明,一般是定义该ContentProvider的包.类的名称;

c、路径——tablename,通俗的讲就是你要操作的数据库中表的名字,或者你也可以自己定义,记得在使用的时候保持一致就可以了;

d、记录ID——id,如果URI中包含表示需要获取的记录的ID,则返回该id对应的数据,如果没有ID,就表示返回全部;

对于第三部分路径(path)做进一步的解释,用来表示要操作的数据,构建时应根据实际项目需求而定。如:

a、操作tablename表中id为11的记录,构建路径:/tablename/11;

b、操作tablename表中id为11的记录的name字段:tablename/11/name;

c、操作tablename表中的所有记录:/tablename;

d、操作来自文件、xml或网络等其他存储方式的数据,如要操作xml文件中tablename节点下name字段:/ tablename/name;

e、若需要将一个字符串转换成Uri,可以使用Uri类中的parse()方法,如:

Uri uri = Uri.parse("content://com.wang.provider.myprovider/tablename")

最简单的查询ContentProvider

  1. 通过Context获取ContentResolver
  2. 调用它的query方法
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(Uri.parse(""),null,null,null,null);
if(cursor != null){
   
    while (cursor.moveToNext()){
   
        Log.d("tag","query result "+cursor.getColumnNames());
    }
    cursor.close();
}

实现自己的ContentProvider

实现自的ContentProvider需要继承Android系统的ContentProvider然后实现下面的几个方法。

  • onCreate()
  • query()
  • getType()
  • insert()
  • delete()
  • update()

需要注意的是除了onCreate()其他的方法都运行在binder线程池。

然后在Manifest中声明对应的contentProvider即可。

contentProvider实现

class DataContentProvider : ContentProvider() {
   
    private val tag = "DataContentProvider"

    private var dbHelper:DBHelper? = null

    override fun insert(uri: Uri, values: ContentValues?): Uri? {
   
        return uri
    }

    override fun query(uri: Uri, projection: Array<String>?, selection: String?, selectionArgs: Array<String>?, sortOrder: String?): Cursor? {
   
        val cursor  = dbHelper?.readableDatabase?.query(DBHelper.USER_TABLE_NAME,projection,null,selectionArgs,null,null,sortOrder)
        Log.d(tag,"call query cursor is $cursor")
        return cursor
    }

    override fun onCreate(): Boolean {
   
        dbHelper = DBHelper(this.context)
        val db = dbHelper?.writableDatabase

        db?.execSQL("delete from ${
     DBHelper.USER_TABLE_NAME}");
        db?.execSQL("insert into ${
     DBHelper.USER_TABLE_NAME} values(1,'XW');")
        db?.execSQL("insert into ${
     DBHelper.USER_TABLE_NAME} values(2,'XZ');")
        return true
    }

    override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<String>?): Int {
   
        return 0
    }

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
   
        return 0
    }

    override fun getType(uri: Uri): String? {
   
        return null
    }
}
class DBHelper  //数据库版本号
(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
   
    override fun onCreate(db: SQLiteDatabase) {
    // 创建两个表格:用户表 和职业表
        db.execSQL("CREATE TABLE IF NOT EXISTS $USER_TABLE_NAME(_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)")
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
   }

    companion object {
   
        // 数据库名
        private const val DATABASE_NAME = "demo_provider.db"
        // 表名
        const val USER_TABLE_NAME = "user"
        private const val DATABASE_VERSION = 1
    }
}

Manifest注册如下:

   <provider
            android:name=".contentprovider.DataContentProvider"
            android:authorities="com.txl.demo.content.provider" 
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值