安卓跨应用数据共享-ContentProvider和ContentResolver

ContentProvider

一、预备知识

uri对象

content://com.example.app.provider/table1

content://com.example.app.provider/table1/1

使用通配符
*:表示匹配任意长度的任意字符
#:表示匹配任意长度的数字

uri字符串转uri对象:Uri.parse("字符串")


Cursor对象

常用方法:来自Carson_Ho

c.move(int offset); //以当前位置为参考,移动到指定行  
c.moveToFirst();    //移动到第一行  
c.moveToLast();     //移动到最后一行  
c.moveToPosition(int position); //移动到指定行  
c.moveToPrevious(); //移动到前一行  
c.moveToNext();     //移动到下一行  
c.isFirst();        //是否指向第一条  
c.isLast();     //是否指向最后一条  
c.isBeforeFirst();  //是否指向第一条之前  
c.isAfterLast();    //是否指向最后一条之后  
c.isNull(int columnIndex);  //指定列是否为空(列基数为0)  
c.isClosed();       //游标是否已关闭  
c.getCount();       //总数据项数  
c.getPosition();    //返回当前游标所指向的行数  
c.getColumnIndex(String columnName);//返回某列名对应的列索引值  
c.getString(int columnIndex);   //返回当前行指定列的值 

遍历数据

c.moveToFirst();  
while (!c.isAfterLast()) {  
    int id=result.getInt(c.getColumnIndex("id"));  
    // ...
    c.moveToNext();  
}  
c.close();

二、提供方Provider

  1. 写一个ContentProvider的子类,重写方法

    • onCreate:初始化一个SQLiteOpenHelper对象,通过getReadableDatabase和getWritableDatabase获得一个SQLiteDatabase对象,用来操作数据库,给下面的方法使用。(此SQLiteOpenHelper对象可以使用内部类方式定义子类)
    • query
    • insert
    • upadte
    • delete
    • getType:根据uri返回一个MIME
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        SQLiteDatabase db = mDbOpenHelper.getWritableDatabase();
        String[] param = matchParam(uri);
        if (!TextUtils.isEmpty(param[0]) && !TextUtils.isEmpty(param[1])) {
            return db.delete(param[0], "id=?", new String[]{param[1]});
        } else if (TextUtils.isEmpty(param[1])) {
            return db.delete(param[0], selection, selectionArgs);
        }
    
        return 0;
    }
    
    //用来从uri中判断查询的表,和分离路径参数(路径中的id)
    private String[] matchParam(Uri uri) {
        String[] param = new String[]{null, null};
        switch (uriMatcher.match(uri)) {
            case USER_DIR:
                param[0] = "user";
                break;
            case USER_ITEM:
                param[0] = "user";
                // “/”为分隔符,第一个“/”右边元素下标为0;“//”不算
                param[1] = uri.getPathSegments().get(1); 
                break;
        }
        return param;
    }
    
    @Override
    public String getType(@NonNull Uri uri) {
        switch (uriMatcher.match(uri)) {
            case USER_DIR:
                // 多条记录vnd.android.cursor.dir开头
                return "vnd.android.cursor.dir/vnd.cn.adolf.db.provider.user";
            case USER_ITEM:
                // 一条记录vnd.android.cursor.item开头
                return "vnd.android.cursor.item/vnd.cn.adolf.db.provider.user";
        }
        return null;
    }
    
    
  2. 在manifest.xml中注册provider

    <provider
        android:name="provider类路径名"
        android:authorities="一般是 包名.provider"
        android:enabled="true"
        android:exported="true" />
    

github源代码: AdolfDbProvider.java

三、调用方ContentResolver

  1. 使用context.getContentResolver();获得一个ContentResolver对象
  2. 调用ContentResolver对象的insert, delete, update, query
  3. 要传入一个uri:content://provider注册的authorities/表名/id

可以使用一个Manager来管理ContentResolver对象的调用,用来装配ContentResolver所调用方法的参数

public class DbResolverManager {

    private static final String ADOLF_URI = "content://cn.adolf.db.provider/";
    private static DbResolverManager instance; // 懒汉,在需要使用时才实例化
    // private static DatabaseManager instance= new DatabaseManager(context); // 饿汉,初始化时就实例化
    private Context mContext;
    private ContentResolver mResolver;

    private DbResolverManager(Context context) {
        this.mContext = context;
        this.mResolver = context.getContentResolver();
    }

    public static synchronized DbResolverManager getInstance(Context context) {
        if (instance == null) {
            instance = new DbResolverManager(context);
        }
        return instance;
    }

    public Uri addUser(UserBean userBean) {
        Uri uri = Uri.parse(ADOLF_URI + "user");
        ContentValues values = new ContentValues();
        values.put("username", userBean.getUsername());
        values.put("sex", userBean.getSex());
        values.put("motto", userBean.getMotto() + System.currentTimeMillis());
        Uri newUri = mResolver.insert(uri, values);
        return newUri;
    }

    public int deleteUserById(int id) {
        if (findUserById(id) == null)
            return 0;
        Uri uri = Uri.parse(ADOLF_URI + "user/" + id);
        int delete = mResolver.delete(uri, null, null);
        return delete;
    }

    public Cursor findUserById(int id) {
        Uri uri = Uri.parse(ADOLF_URI + "user/" + id);
        Cursor cursor = mResolver.query(uri, null, null, null, null);
        return cursor;
    }
	//...省略其他方法
}

github源代码:DbResolverManager.java

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值