android学习笔记之六:四大组件之ContentProvider

1.使用ContentProvider(内容提供者)共享数据

ContentProvider(内容提供者)是Android中的四大组件之一。主要用于对外共享数据,也就是通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对指定应用中的数据进行增删改查操作。使用ContentProvider对外共享数据的好处是统一了数据的访问方式。

当应用需要通过ContentProvider对外共享数据的步骤:

1.需要继承ContentProvider并重写下面方法:

public class MyContentProvider extends ContentProvider{
    // 在创建ContentProvider时调用
    public boolean onCreate()

    // 用于添加数据到指定Uri的ContentProvider中 
    public Uri insert(Uri uri, ContentValues values) 

    // 用于从指定Uri的ContentProvider中删除数据
    public int delete(Uri uri, String selection, String[] selectionArgs) 

    // 用于更新指定Uri的ContentProvider中的数据
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

    // 用于查询指定Uri的ContentProvider,返回一个Cursor 
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) 

    // 用于返回指定的Uri中的数据的MIME类型
    public String getType(Uri uri)
} 

2.需要在AndroidManifest.xml使用provider对该ContentProvider进行配置,为了能让其他应用找到该ContentProvider, ContentProvider 采用了authorities对它进行唯一标识。

<manifest .... >
        <application android:icon="@drawable/icon" android:label="@string/app_name">
            <provider android:name=".MyContentProvider"   
                android:authorities="com.example.providers.myprovider"/>
        </application>
</manifest>
  • Uri是ContentResolver和ContentProvider进行数据交换的标识。Uri代表了要操作的数据,Uri主要包含了两部分信息:需要操作的ContentProvider和对ContentProvider中的什么数据进行操作。
    • 每个ContentProvider提供公共的Uri来唯一标识其数据集。管理多个数据集的(多个表)的 ContentProvider 为每个数据集提供了单独的Uri。
    • Uri 的标准前缀:以“content://”作为前缀,这个是标准的前缀,表示该数据由 ContentProvider 管理。
    • Uri 的authority部分:该部分是完整的类名。(使用小写形式)。
    • Uri 的path部分(资源部分、数据部分): 用于决定哪类数据被请求。
      被请求的特定记录的id值。如果请求不仅限于某个单条数据,该部分及其前面的斜线应该删除。
    • 为了将一个字符串转换成Uri,Android中提供了Uri的parse()静态方法来实现。
  • 如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头。
    例如:要得到所有person记录的Uri为content://contacts/person,那么返回的MIME类型字符串为
    “vnd.android.cursor.dir/person”
  • 如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头。
    例如:要得到id为1的person记录的Uri为content://contacts/person/1,那么返回的MIME类型字符串应为
    “vnd.android.cursor.item/person”
  • URI和URL的区别
    • URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。
    • URL,是uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。
    • URI是以一种抽象的,高层次概念定义统一资源标识,而URL则是具体的资源标识的方式。
    • URL是一种具体的URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。URI是一种语义上的抽象概念,可以是绝对的,也可以是相对的,而URL则必须提供足够的信息来定位,所以,是绝对的。
  • UriMatcher类的使用
    UriMatcher类用于匹配Uri,它的用法如下:

    (1).注册需要匹配的Uri路径(UriMatcher.NO_MATCH表示不匹配任何路径的返回码)

    UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    

    (2).添加需要匹配uri,如果匹配就会返回匹配码

    uriMatcher.addURI("com.example.provider.myprovider", "person", 1);
    uriMatcher.addURI(“com.example.provider.myprovider", "person/#", 2);
    // *和#是两个通配符,它们用在uri地址中,*可以匹配任何文本,#匹配任何数字。
    

    (3).使用uriMatcher.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数

switch (uriMatcher.match(Uri.parse("content://com.example.provider.myprovider/person/1"))) { 
    case 1:
        break;
    case 2:
        break;
    default: //不匹配
        break;
}

2.使用ContentResolver操作ContentProvider中的数据

  • 当外部应用需要对ContentProvider中的数据进行增加、删除、修改和查询操作时,可以使用ContentResolver类来完成,要获取ContentResolver对象,可以使用Context提供的getContentResolver()方法。
  • ContentResolver 类提供了与ContentProvider类相同签名的四个方法:

public Uri insert(Uri uri, ContentValues values)
该方法用于往ContentProvider增加数据。

public int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于从ContentProvider删除数据。

public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs)
该方法用于修改ContentProvider中的数据。

public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder)
该方法用于从ContentProvider中查询数据。

  • 使用ContentResolver对ContentProvider中的数据进行增加、删除、修改和查询操作:
ContentResolver contentResolver = getContentResolver();
Uri uri = Uri.parse("content://com.example.provider.myprovider/person");

//增加数据
ContentValues values = new ContentValues();
values.put("name", "yuechao");
values.put("age", 21);
resolver.insert(uri, values);  

//查询数据
Cursor cursor = contentResolver.query(uri, null, null, null, null);
while(cursor.moveToNext()){
    //根据索引值获取数据
    String name = cursor.getString(cursor.getColumnIndex("name"));
    int age = cursor.getInt(cursor.getColumnIndex("age"));
}

//修改数据
ContentValues updateValues = new ContentValues();
updateValues.put("name", "shuaige");
contentResolver.update(uri, updateValues, null, null);

// 删除数据
contentResolver.delete(uri, values, "name = ?", new String[] {"shuaige"});

3.使用内容观察者(ContentObserver)监听ContentProvider中数据的变化

如果ContentProvider的访问者需要知道ContentProvider中的数据发生变化,可以在ContentProvider发生数据变化时调用getContentResolver().notifyChange(uri, null)来通知注册在此URI上的访问者。

public class MyContentProvider extends ContentProvider {
    public Uri insert(Uri uri, ContentValues values) {
        db.insert("person", "personid", values);
        getContext().getContentResolver().notifyChange(uri, null);
    }
}

如果ContentProvider的访问者需要得到数据变化通知,必须使用ContentObserver对数据(数据采用uri描述)进行监听,当监听到数据变化通知时,系统就会调用ContentObserver的onChange()方法:

Uri uri = Uri.parse("content://com.example.provider.myprovider/person");
getContentResolver().registerContentObserver(,true, new MyObserver(new Handler()));
public class MyObserver extends ContentObserver{
    public MyObserver(Handler handler) {
        super(handler);
    }

    //内容观察者收到数据库发生改变的通知时,会调用此方法
    @Override
    public void onChange(boolean selfChange) {

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值