安卓四大组件--ContentProvider

一.ContentProvider实例
1.创建ContentProvider
package com.example.testapplication.ContentProvider;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.example.testapplication.db.MyDataBaseHelper;

public class MyProvider extends ContentProvider {

    //定义上下文
    private Context mContext;
    
    //创建数据库操作工厂
    MyDataBaseHelper mDbHelper = null;
    
    //创建数据库操作对象
    SQLiteDatabase db = null;

    //设置ContentProvider的唯一标识
    //采用包名的形式创建contentprovider的唯一标识
    public static final String AUTOHORITY = "com.example.testapplication.ContentProvider";

    //创建user表的编号
    public static final int User_Code = 1;
    
    //创建job表的编号
    public static final int Job_Code = 2;

    //UriMatcher类使用:在ContentProvider中注册URI
    //创建UriMatcher对象用于注册uri来暴漏contentprovider的对外接口
    private static final UriMatcher mMatcher;
    
    static{
        
        //初始化
        mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        
        //若URI资源路径 = content://com.example.testapplication.ContentProvider/user ,则返回注册码User_Code
        //param1:自己定义的唯一标识,param2:“表名”,param3:区分uri的代码
        mMatcher.addURI(AUTOHORITY,"user", User_Code);
        
        //若URI资源路径 = content://com.example.testapplication.ContentProvider/job ,则返回注册码Job_Code
        mMatcher.addURI(AUTOHORITY, "job", Job_Code);
    }

    //初始化ContentProvider
    @Override
    public boolean onCreate() {

        //获取上下文
        mContext = getContext();

        //在ContentProvider创建时对数据库进行初始化
        //运行在主线程,故不能做耗时操作,此处仅作展示
        mDbHelper = new MyDataBaseHelper(mContext);
        db = mDbHelper.getWritableDatabase();

        //先清空user表,然后再向user表中插入两条数据
        db.execSQL("delete from user");
        db.execSQL("insert into user values(1,'Carson');");
        db.execSQL("insert into user values(2,'Kobe');");

        //先清空job表,然后再向job表中插入两条信息
        db.execSQL("delete from job");
        db.execSQL("insert into job values(1,'Android');");
        db.execSQL("insert into job values(2,'iOS');");

        return true;
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,
                        @Nullable String[] selectionArgs, @Nullable String sortOrder) {

        //根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
        String table = getTableName(uri);

        //table:表名,如果是多表联查,可以将两个表之间加逗号,projection:查询表的对应字段
        //projection:查询表中的字段
        //selectionArgs:对应于selection语句中的占位符的值,值在数组中的位置与占位符在语句中的位置必须一致,否则报异常
        //groupBy:相当于select语group by 后面的关键字
        //having:相当于select语句having关键字后面的部分
        //orderBy:相当于order by关键字后面的部分
        //limit:指定偏移量和获取的记录数,相当于select语句limit关键字后面的部分
        return db.query(table,projection,selection,
                selectionArgs,null,null,sortOrder,null);
    }

    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        return null;
    }

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {

        //根据URI匹配 URI_CODE,从而匹配ContentProvider中对应的表名
        String table = getTableName(uri);

        //向该表中添加数据
        db.insert(table,null,values);

        //当该UIR的ContentProvider数据发生变化时,通知外界(即访问该ContentProvider数据的访问者)
        //其他使用该uri的应用可以通过getContentRes
        mContext.getContentResolver().notifyChange(uri,null);

        return uri;
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection,
                      @Nullable String[] selectionArgs) {
        return 0;
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection,
                      @Nullable String[] selectionArgs) {
        return 0;
    }


    /*
    *根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
    * */
    private String getTableName(Uri uri){
        String tableName = null;
        
        //mMatcher.match(uri)返回值为注册uri时对应的代码
        switch (mMatcher.match(uri)){
            case User_Code:
                //自己在数据库创建类中自己定义的表名
                tableName = mDbHelper.USER_TABLE_NAME;
                break;
            case Job_Code:
                //自己在数据库创建类中自己定义的表名
                tableName = mDbHelper.JOB_TABLE_NAME;
                break;
        }
        return tableName;
    }
}

2.注册ContentProvider
        <!--创建自己的provider-->
        <!--authorities是自己在创建ContentProvider中自定义的唯一标识,通常是包名+类名-->
        <provider android:name=".ContentProvider.MyProvider"
            android:authorities="com.example.testapplication.ContentProvider"
            />
3.通过uri调用处理数据
        //获取指向数据库中user表的uri
        Uri uri_user =           Uri.parse("content://com.example.testapplication.ContentProvider/user");

        //创建与数据库进行数据传递的容器
        ContentValues contentValues = new ContentValues();
        contentValues.put("_id",3);
        contentValues.put("name","zhangyi");

        //获取连接ContentProvider暴漏接口的操作对象ContentResolver
        ContentResolver contentResolver = getContentResolver();
                
        //通过contentResolver向数据库里插入一条数据
        contentResolver.insert(uri_user,contentValues);

        //定义查询user表的字段
        String[] columns = {"_id","name"};

        //通过contentResolver从数据库中查询数据
        Cursor users = contentResolver.query(uri_user, columns,
                        null, null, null);

        //打印获取到的信息
        //getInt("索引"),索引是表字段的索引位置,从"0"开始,获取字段值
        while (users.moveToNext()){
               Log.d(TAG, "onClick: "+"\n"+users.getInt(0)+"\n"+users.getString(1));
        }
4.总结

相关联的类:

SQLiteOpenHelper ContentProvider UriMatcher Uri

ContentValues ContentResolver Cursor

SQLiteOpenHelper:db操作的核心对象,主要用途,创建数据库,创建表,对表进行一系列的操作
ContentProvider:让不同进程之间共享数据,通过Uri暴露出接口,不同进程之间访问相同的uri接口,
实现数据共享。
UriMatcher:对uri进行注册,将接口暴露出来
Uri:是统一资源路径,通过uri指定到对应共享数据的位置
ContentValues:与共享数据交换信息的容器,类似于map,数据是以键值对的形式存储到容器当中的
ContentResolver:其他线程访问数据的核心类,通过这个类,再连接到ContentProvider类中,
实现对数据的操作,通过uri进行定位数据位置
Cursor:游标,通过contentResolver查询数据后的返回值,默认位置不在第一个索引,在-1,
所以每次获取数据时需要将游标指到指定的位置,使用moveToNext()方法将初始的游标移到0索引处,
moveToFirst()方法将游标指向第一个索引处
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值