ContentProvider使用

作为四大组件之一,ContentProvider 算是我直接使用次数最少的一个了。主要提供应用程序之间共享数据的接口

一、创建ContentProvider 实例

ContentProvider是一个抽象类。创建MyProvider类继承ContentProvider,实现6个抽象方法:onCreategetTypequeryinsertdeleteupdate

onCreate()方法会在创建的时候调用一次。其它方法通过ContentResolver的增删改查方法触发。

所以我们只需要在对应的方法下对数据库进行增删改查就行了。

public class MyProvider extends ContentProvider {

    private static final String TAG = "MyProvider";

    @Override
    public boolean onCreate() {
        Log.d(TAG, "onCreate, Thread:" + Thread.currentThread().getName());
        return false;
    }

    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        Log.d(TAG, "getType, Thread:" + Thread.currentThread().getName());
        return null;
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        Log.d(TAG, "query, Thread:" + Thread.currentThread().getName());
        return SqlHelper.getInstance().query(TeacherTable.TABLE_NAME, projection, selection, selectionArgs);
    }

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
        Log.d(TAG, "insert, Thread:" + Thread.currentThread().getName());
        SqlHelper.getInstance().insert(TeacherTable.TABLE_NAME, values);
        return null;
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
        Log.d(TAG, "delete, Thread:" + Thread.currentThread().getName());
        SqlHelper.getInstance().delete(TeacherTable.TABLE_NAME, selection, selectionArgs);
        return 0;
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
        Log.d(TAG, "update, Thread:" + Thread.currentThread().getName());
        SqlHelper.getInstance().update(TeacherTable.TABLE_NAME, values, selection, selectionArgs);
        return 0;
    }
}
二、注册ContentProvider
        <provider
            android:authorities="test.com.provider.MyProvider"
            android:name=".provider.MyProvider"
//            android:process=":provider"
//            android:permission="com.zy.android.PROVIDER"
            />
  • authorities : 是ContentProvider 的唯一标识,所以最好加上包名前缀
  • name : 需要注册的ContentProvider 名
三、使用

1、插入:

 Uri uri = Uri.parse("content://test.com.provider.MyProvider");
 ContentValues values = new ContentValues();
 values.put(TeacherTable.COLUMN_NAME, "张三");
 values.put(TeacherTable.COLUMN_GRADE,"1");
 values.put(TeacherTable.COLUMN_CLS,"3");
 values.put(TeacherTable.COLUMN_ID, id);
 getContentResolver().insert(uri,values);

在Uri 中指明ContentProvider 的标识,也就是注册的authorities属性值。
固定写法:Uri.parse("content://authorities")

通过getContentResolver()获得ContentResolver对象。

2、删除

getContentResolver().delete(uri, "name = ?", new String[]{"张三"});

3、修改

ContentValues values2 = new ContentValues();
values2.put(TeacherTable.COLUMN_NAME, "王二麻子");
values2.put(TeacherTable.COLUMN_GRADE,"1");
values2.put(TeacherTable.COLUMN_CLS,"3");
//values.put(TeacherTable.COLUMN_ID, id);
getContentResolver().update(uri, values2, "name = ? ", new String[]{"张三"});

将张三修改成王二麻子

4、查询

Cursor cursor = getContentResolver().query(uri, null, "name = ? ", new String[]{"张三"}, "1");            

查询操作会返回一个Cursor对象,通过对Cursor 操作,获得值。

        if (cursor == null){
            return;
        }
        cursor.moveToFirst();
        StringBuffer sb = new StringBuffer();
        while (!cursor.isAfterLast()){
            sb.append("ID:" + cursor.getInt(cursor.getColumnIndex(TeacherTable.COLUMN_ID))
                    + " name:" + cursor.getString(cursor.getColumnIndex(TeacherTable.COLUMN_NAME))
                    + " grade:"+ cursor.getString(cursor.getColumnIndex(TeacherTable.COLUMN_GRADE))
                    + " cls: " + cursor.getString(cursor.getColumnIndex(TeacherTable.COLUMN_CLS))
                    + "\n"
            );
            cursor.moveToNext();
        }
        cursor.close();

ContentProvider的query方法需要返回Cursor 才行,否则获得的是一个空对象。

TeacherTable表结构

public class TeacherTable {
    //表名
    public static final String TABLE_NAME = "teacher";
    //列
    public static final String COLUMN_ID    = "id";
    public static final String COLUMN_NAME  = "name";
    public static final String COLUMN_GRADE = "grade";
    public static final String COLUMN_CLS   = "cls";

    //创建teacher表
    public static final String CREATE_TABLE = "CREATE TABLE "  //"CREATE TABLE IF NOT EXISTS "
            + TABLE_NAME + "("
            + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
            + COLUMN_NAME + " TEXT,"
            + COLUMN_GRADE + " TEXT,"
            + COLUMN_CLS + " TEXT"
            + ")";

    private int id;
    private String name;
    private String grade;
    private String cls;
}

SqlHelper

/**
 * Created by zy
 * date 2019/12/24 0024.
 * desc:
 */
public class SqlHelper extends SQLiteOpenHelper {
    //数据库名
    private static final String DB_NAME = "test_db";
    //数据库版本
    private static final int DB_VERSION = 1;

    public static SqlHelper instance;

    public static SqlHelper getInstance(){
        if (instance == null){
            instance = new SqlHelper(MyApp.context);
        }
        return instance;
    }

    /**
     * @param context 上下文
     *                数据库名称
     *                数据库游标工厂类(可选)
     *                数据库版本
     */
    public SqlHelper(@Nullable Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建教师表
        db.execSQL(TeacherTable.CREATE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        String drop = "DROP TABLE IF EXISTS ";
        //drop older table existed
        db.execSQL(drop + TeacherTable.TABLE_NAME);

        onCreate(db);
    }

    /**
     * 插入
     *
     * @param tableName 表名
     * @param values
     * @return 插入是否成功
     */
    public boolean insert(String tableName, ContentValues values) {
        SQLiteDatabase db = this.getWritableDatabase();
        long res = db.insert(tableName, null, values);
        return res != -1;
    }

    /**
     * 根据条件删除
     * @param tableName
     * @param where
     * @param args
     * @return
     */
    public boolean delete(String tableName, String where, String[] args) {
        try {
            SQLiteDatabase db = this.getWritableDatabase();
            db.delete(tableName, where, args);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 修改
     * @param tableName
     * @param id
     * @param values
     * @return
     */
    public boolean update(String tableName, String id, ContentValues values) {
        try {
            SQLiteDatabase db = this.getWritableDatabase();
            db.update(tableName, values, TeacherTable.COLUMN_ID + " = ? ", new String[]{id});
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("tag","update Exception: " + e.toString());
        }
        return false;
    }

    /**
     * 更新
     * @param tableName
     * @param values
     * @param selection
     * @param selectionArgs
     */
    public void update(String tableName, ContentValues values, String selection, String[] selectionArgs){
        SQLiteDatabase db = this.getWritableDatabase();
        db.update(tableName, values, selection, selectionArgs);
    }

    /**
     * 查询
     * @param tableName
     * @param columns
     * @param selection
     * @param selectionArgs
     * @return
     */
    public Cursor query(String tableName, String[] columns, String selection, String[] selectionArgs) {
        try {
            SQLiteDatabase db = this.getReadableDatabase();
            Cursor cursor = db.query(tableName, columns, selection, selectionArgs, null, null, null);
            return cursor;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
总结

关于SQLite使用,可以看我的另一篇文字:Android SQLite简单使用

因为四大组件中ContentProvider主动使用频率比较低,所以没有去过多深入了解,只是记录使用方式。

其它三大组件工作流程:

Activity的启动流程

BroadcastReceiver 工作过程

Service启动流程

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值