Android四大应用组件之ContentProvider初探

理解

  1. 首先谈一谈为什么要有ContentProvider?

当一个应用想要访问另一个应用的数据库时,由于每个应用的数据库文件时应用私有的,不能直接访问,这时,被访问的应用就需要一个对外的数据库内容提供者,也就是ContentProvider。

<provider
	<!--自定义ContentProvider需要继承于ContentProvider,并在功能清单文件中注册-->
         android:authorities="com.sank.ar_8_contentprovider_1_bi.personprovider"
          android:name=".PersonProvider"
          android:exported="true"	/>
  1. 什么是ContentResolver?

ContentResolver又称内容提供者解析类,用来解析被访问者暴露的ContentProvider。

  1. 两者之间的关联

ContentProvider和ContentResolver之间使用URI进行通信。

URI:

URI包含URL与URN,是一个包含请求地址的类。

主要使用的两个工具类:

UriMatcher : 用于匹配Uri的容器

//添加一个合法的URI
void addURI(String authority,String path, int code) ;

//匹配指定的uri, 返回匹配码
int match(Uri uri);

ContentUris : 解析uri的工具类

//解析uri, 得到其中的id
long parseId(Uri contentUri)

//添加id到指定的uri中
Uri withAppendedId(Uri contentUri, long id)

Demo

  1. ContentProvider:
  • SQLite数据库部分:
public class DBHelper extends SQLiteOpenHelper {
    public DBHelper(Context context) {
        super(context, "sank.db", null, 1);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table person(" +
                "_id integer primary key autoincrement," +
                "name varchar(20))");
        db.execSQL("insert into person " +
                "(name) values ('TOM')");
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

  • 自定义Provider类:
public class PersonProvider extends ContentProvider {
    //用来存放所有的合法的uri的容器
    private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
    //保存一些合法的uri
    //content://com.sank.ar_8_contentprovider_1_bi.personprovider/person    不根据id操作
    //content://com.sank.ar_8_contentprovider_1_bi.personprovider/person/3  根据id操作
    static {
        matcher.addURI("com.sank.ar_8_contentprovider_1_bi.personprovider"
                ,"/person",1);
        matcher.addURI("com.sank.ar_8_contentprovider_1_bi.personprovider"
                ,"/person/#",2);
    }
    private DBHelper dbHelper;
    @Override
    public boolean onCreate() {
        dbHelper = new DBHelper(getContext());
        return false;
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection,
                        @Nullable String selection, @Nullable String[] selectionArgs,
                        @Nullable String sortOrder) {
        //得到Sql链接对象
        SQLiteDatabase database = dbHelper.getReadableDatabase();
        //匹配uri,返回code
        int code = matcher.match(uri);
        if(code==1){//如何合法,进行查询
            //不根据id查询
            Cursor cursor = database.query("person", projection, selection, selectionArgs,
                    null, null, null);
            return cursor;
        }else if(code==2){
            //根据id查询
            long id = ContentUris.parseId(uri);
            Cursor cursor = database.query("person", projection, "_id=?", new String[]{id + ""},
                    null, null, null);
            return cursor;
        }else{
            //如何不合法,抛出异常
            throw new RuntimeException("uri不合法");
        }
    }

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

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
        //建立链接
        SQLiteDatabase database = dbHelper.getReadableDatabase();
        //匹配uri,返回code
        int code = matcher.match(uri);
        //检查uri是否合法
        if(code==1){
            long id = database.insert("person", null, values);
            //将id添加到uri中
            uri = ContentUris.withAppendedId(uri,id);
            database.close();
            return uri;
        }else{
            database.close();
            throw new RuntimeException("uri不合法");
        }
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
        //建立链接
        SQLiteDatabase database = dbHelper.getReadableDatabase();
        //匹配uri,返回code
        int code = matcher.match(uri);
        //删除的个数
        int deleteCount = -1;
        //检查uri是否合法
        if(code==1){
            deleteCount = database.delete("person", selection, selectionArgs);
        }else if(code ==2){
            long id = ContentUris.parseId(uri);
            database.delete("person", "_id=" + id, null);
        } else{
            database.close();
            throw new RuntimeException("uri不合法");
        }
        database.close();
        return deleteCount;
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
        //建立数据库链接
        SQLiteDatabase database = dbHelper.getReadableDatabase();
        //匹配uri
        int code = matcher.match(uri);
        //更新的行数
        int updateCount;
        //检查是否合法
        if (code == 1) {
            updateCount = database.update("person", values, selection, selectionArgs);
        } else if (code == 2) {
            long id = ContentUris.parseId(uri);
            updateCount = database.update("person", values, "_id=" + id, null);
        }else {
            database.close();
            throw new RuntimeException("uri不合法");
        }
        database.close();
        return updateCount;
    }
}
  1. ContentResolver:
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    /*
        CRUD
     */
    public void insert(View view) {
        //得到ContentResolver对象
        ContentResolver resolver = getContentResolver();
        Uri uri = Uri.parse("content://com.sank.ar_8_contentprovider_1_bi.personprovider/person/");
        ContentValues values = new ContentValues();
        values.put("name","mary");
        uri = resolver.insert(uri,values);
        Toast.makeText(this,uri.toString(),Toast.LENGTH_SHORT).show();
    }

    public void delete(View view) {
        ContentResolver resolver = getContentResolver();
        Uri uri = Uri.parse("content://com.sank.ar_8_contentprovider_1_bi.personprovider/person/2");
        int deleteCount = resolver.delete(uri,null, null);
        Toast.makeText(this,"deleteCount="+deleteCount,Toast.LENGTH_SHORT).show();
    }

    public void update(View view) {
        ContentResolver resolver = getContentResolver();
        Uri uri = Uri.parse("content://com.sank.ar_8_contentprovider_1_bi.personprovider/person/1");
        ContentValues values = new ContentValues();
        values.put("name","Tom2");
        int updateCount = resolver.update(uri, values, null, null);
        Toast.makeText(this,"updateCount="+updateCount,Toast.LENGTH_SHORT).show();
    }

    public void query(View view) {
        //得到ContentResolver对象
        ContentResolver resolver = getContentResolver();
        //调用query,得到cursor对象
        Uri uri = Uri.parse("content://com.sank.ar_8_contentprovider_1_bi.personprovider/person");
        Cursor cursor = resolver.query(uri, null, null, null, null);
        //取出cursor中的数据
        assert cursor != null;
        while(cursor.moveToNext()){
            int id = cursor.getInt(0);
            String name = cursor.getString(1);
            Toast.makeText(this,id+" : "+name,Toast.LENGTH_SHORT).show();
        }
        cursor.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值