当前位置:操作系统 > 安卓/Android >>

Android数据共享机制ContentProvider

一、简介
Android使用一种称为ContentProvider的概念来将数据抽象为服务,这种内容提供程序的理念看起来像启用了REST的数据提供程序。
要从ContentProvider检索数据或将数据保存到ContentProvider,需要使用一组类似REST的URI。例如,要从封装图书数据库的ContentProvider获取一组图书,需要使用以下形式的URI:
[java]
content://com.android.book.BookProvider/books 
要从图书数据库获得指定图书(如编号为:88图书),则要使用以下类似URI:
[java]
content://com.android.book.BookProvider/books/88 
设备上的任何应用程序都可以通过这些URI来访问或操作数据,所以在应用程序之间的数据共享上ContentProvider扮演着非常主要的角色。
二、Android内置的ContentProvider
Android中存在大量的内置ContentProvider,他们记录在SDK的android.provider包中,如:
Browser
Calllog
Contacts
  People
  Phones
  Photos
  Groups
MediaStore
  Audio
     Albums
     Artists
     Playlists
  Images
  Video
Settings
其中顶级项数据库,较低级的项是表。所以Browser、CAllog,MediaStore和Settings都是封装为ContentProvider的独立SQLite数据库.这些数据库通常具有扩展名.db。仅能从实现包访问,任何来自外部的访问都要通过ContentProvider接口。
三、ContentProvider架构
与网站一样,设备上的每个ContentProvider都会使用字符串注册本身,这个字符串类似网站域名,但称为:授权(Authority)。授权的注册则AndroidManifest.xml中进行。如:
[java]
<provider android:name="BookProvider" android:authorities="com.myCompany.BookProvider"/> 
在进行了授权后,ContentProvider就拥有了以授权前缀开头的URI:
[java]
content://com.myCompany.BookProvider/ 
注意:Android内置的ContentProvider可能没有完全限定的授权名,只有在使用第三方提供的时才使用完全限定名。这也就是为什么有时候仅使用Contacts来引用联系人ContentProvider。
1、Android内容URI的结构
Android中的内容URI类似于Http URL,但他们以content://开头具有一下通用形式:
[java]
Content://*/*/ 
或 
content://authority-name/path-segment1/path-segment2/etc...... 
2、Android MIME类型的结构
就像网站返回给指定URI的MIME类型一样,ContentProvider也负责返回给URI的MIME类型。MIME类型包括两部分:类型和子类型。如:
[java]
text/html 
text/css 
text/xml 
application/pdf 
application/vnd.ms-excel 
类型和子类型对于他们所表示的内容必须是唯一的,且如果类型和子类型不是标准的,则需要在他们前面加上vnd。
3、使用URI读取数据
要从ContentProvider获取数据,需要使用该ContentProvider提供的URI。
如下:为从联系人提供程序获取单行联系人信息
[java]
Uri baseUri = Contacts.People.CONTENT_URI; 
uri myPersonUri = baseUri.withAppendedPath(Contacts.People.CONTENT_URI,"80"); 
Cursor cur = manageQuery(myPersonUri,null,null,null); 
在上面的基础上我们来看看,如何获取一个游标,这个游标包含来自contactsContentProvider的People表的一组特定的列。
[java]
String[] projection = new String[]{ 
    People._ID, 
    People.NAME, 
    People.NUMBER 
}; 
 
Uri mContactsURi = Contacts.People.CONTENT_URI; 
Cursor managedCursor = managedQuery( 
    projection, 
    null, 
    Contacts.People.NAME + "ASC" 
); 
4、使用游标
在使用Android游标前,先了解一些关于游标的的知识。
游标是一个行集合;
读取数据之前,需要使用moveToFirst(),因为游标放在第一行之前;
需要知道列的名称和类型;
所有字段访问都基于列编号,所以必须首先将列名称转换为列编号;
游标可以随意移动;
可以使用游标获取行计数;
使用while循环导航游标:
[java]
if (cur.moveToFirst == false){ 
    return; 

int nameColumnIndex = cur.getColumnIndex(People.NAME); 
String name = cur.getString(nameColumnIndex); 
 
while (cur.moveToNext()){ 
    //获取属性值 

使用for循环导航游标
[java]
int nameColumn = cur.getColumnIndex(People.NAME); 
int ploneColumn = cur.getColumnIndex(People.NUMBER); 
 
for(cur.moveToFirst();!cur.isAfterLast();cur.moveToNext()){ 
    String name = cur.getString(nameColumn); 
    String phoneNumber = cur.getString(phoneColumn); 

5、使用Where子句
ContentProvider提供两种方式来传递where子句:
通过URI;
[java]
String noteUri = "content://com.google.provider.NotePad.notes.80"; 
Cursor managedCursor = managedQuery(noteUri, 
    projection,//返回的列 
    null,//where子句 
    Contacts.People.NAME + "ASC"//排序方式 
); 
通过String子句与一组可替换的字符串数组参数的组合。
[java]
String noteUri = "content://com.google.provider.NotePad.notes"; 
Cursor managedCursor = managedQuery(noteUri, 
    projection,//返回的列 
    "_id=?",//where子句 
    new String[]{80}, 
    Contacts.People.NAME + "ASC"//排序方式 
); 
6、插入记录
android使用ContentValues来保存将插入的单一记录的值,要插入记录,由android.content.ContentResolver使用URI插入记录。下面是个例子:
[java]
ContentValues values = new ContentValues(); 
values.put("title","new Note"); 
values.put("note","this is a new Note"); 
ContentResolver cr = activity.getContentResolver(); 
Uri uri = cr.insert(Notepad.Notes.CONTENT_URI,values); 
7、更新和删除
更新类似插入,方法签名为:
[java]
int numberOfRowsUpdated = activity.getContentResolver().update( 
   Uri uri, 
   ContentValues values, 
   String whereClause, 
   String[] selectionArgs 
); 
类似的删除的方法为:
[java]
int numberOfRowsDeleted = activity.getContentResolver().delete( 
   Uri uri, 
   String whereClause, 
   String[] selectionArgs 
); 
8、下面我们自己实现一个ContentProvider,并进行CRUD操作;
我们将按如下流程来实现:
(1)计划数据库、URI、列名称,创建元数据类来定义所有的这些元数据元素的常量;
(2)扩展抽象类ContentProvider
(3)实现方法:query、insert、update、delete和getType
(4)在描述文件中注册提供程序
具体代码如下:
布局文件:
[java]
<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    > 
<TextView   
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello" 
    /> 
</LinearLayout> 
元数据类:(NotePad.java)
[java]
public class NotePad { 
    //授权 
    public static final String
补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,