文章来自:http://blogold.chinaunix.net/u3/90973/showart_2161195.html

Android是如何实现应用程序之间数据共享的?一个应用程序可以将自己的数据完全暴露出去,外界更本看不到,也不用看到这个应用程序暴露的数据是如何 存储的,或者是使用数据库还是使用文件,还是通过网上获得,这些一切都不重要,重要的是外界可以通过这一套标准及统一的接口和这个程序里的数据打交道,例 如:添加(insert)、删除(delete)、查询(query)、修改(update),当然需要一定的权限才可以。
如何将应用程序的数据暴露出去? Android提供了ContentProvider,一个程序可以通过实现一个Content provider的抽象接口将自己的数据完全暴露出去,而且Content providers是以类似数据库中表的方式将数据暴露。Content providers存储和检索数据,通过它可以让所有的应用程序访问到,这也是应用程序之间唯一共享数据的方法。要想使应用程序的数据公开化,可通过2种 方法:创建一个属于你自己的Content provider或者将你的数据添加到一个已经存在的Content provider中,前提是有相同数据类型并且有写入Content provider的权限。
如何通过一套标准及统一的接口获取其他应用程序暴露的数据?Android提供了ContentResolver,外界的程序可以通过ContentResolver接口访问ContentProvider提供的数据。
当前篇主要说明,如何获取其它应用程序共享的数据,比如获取Android 手机电话薄中的信息。
什么是URI?
在学习如何获取ContentResolver前,有个名词是必须了解的:URI。URI是网络资源的定义,在Android中赋予其更广阔的含义,先看个例子,如下:

将其分为A,B,C,D 4个部分:
A:标准前缀,用来说明一个Content Provider控制这些数据,无法改变的;
B:URI的标识,它定义了是哪个Content Provider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的 类名。这个标识在 元素的 authorities属性中说明:
C:路径,Content Provider使用这些路径来确定当前需要生什么类型的数据,URI中可能不包括路径,也可能包括多个;
D:如果URI中包含,表示需要获取的记录的ID;如果没有ID,就表示返回全部;
由于URI通常比较长,而且有时候容易出错,切难以理解。所以,在Android当中定义了一些辅助类,并且定义了一些常量来代替这些长字符串,例如:People.CONTENT_URI
ContentResolver 介绍说明
看完这些介绍,大家一定就明白了,ContentResolver是通过URI来查询ContentProvider中提供的数据。除了URI以外,还必 须知道需要获取的数据段的名称,以及此数据段的数据类型。如果你需要获取一个特定的记录,你就必须知道当前记录的ID,也就是URI中D部分。
前面也提到了Content providers是以类似数据库中表的方式将数据暴露出去,那么ContentResolver也将采用类似数据库的操作来从Content providers中获取数据。现在简要介绍ContentResolver的主要接口,如下:
返回值
函数声明
final Uri
insert(Uri url, ContentValues values)Inserts a row into a table at the given URL.
final int
delete(Uri url, String where, String[] selectionArgs)Deletes row(s) specified by a content URI.
final Cursor
query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)Query the given URI, returning a Cursor over the result set.
final int
update(Uri uri, ContentValues values, String where, String[] selectionArgs)Update row(s) in a content URI.
看到这里,是否感觉与数据库的操作基本一样的?就是这样的,详细解析请参考
Android SQLite解析
篇中的说明,不在此详细说明。
最后一个问题:如何获取ContentResolver?调用getContentResolver (),例如:ContentResolver cr = getContentResolver();
制作ContentResolver实例
以上就完全介绍了如何获取、使用ContentResolver,启动Eclipes,制作一个完整的实例如下:

打开showcontent.java,修改如下:
packagemoandroid.showcontact;
importandroid.app.ListActivity;
importandroid.database.Cursor;
importandroid.os.Bundle;
importandroid.provider.Contacts.Phones;
importandroid.widget.ListAdapter;
importandroid.widget.SimpleCursorAdapter;
publicclassshowcontactextendsListActivity {
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Cursor c = getContentResolver().query(Phones.CONTENT_URI,null,null,null,null);
startManagingCursor(c);
ListAdapter adapter =newSimpleCursorAdapter(this,
android.R.layout.simple_list_item_2, c,
newString[] { Phones.NAME, Phones.NUMBER },
newint[] { android.R.id.text1, android.R.id.text2 });
setListAdapter(adapter);
}
}
然后在AndroidManifest.XML中元素前增加如下许可:
最后运行程序,在模拟器启动后,单击Menu返回到Home界面,打开Contacts选择Contacts标签页,添加2个联系人信息。返回到Home,选择moandroid.showcontact运行,刚添加的2个联系人信息将显示在界面上,如下:

总结说明
ContentResolver的使用极大的方便了应用程序之间共享数据,如何将应用程序的数据完全暴露给给他应用程序使用了.

如何将应用程序的数据暴露出去?
通过以前文章的学习,知道ContentResolver是通过ContentProvider来获取其他与应用程序共享的数据,那么ContentResolver与ContentProvider的接口应该差不多的。
其中ContentProvider负责


  • 组织应用程序的数据;
  • 向其他应用程序提供数据;

ContentResolver则负责

  • 获取ContentProvider提供的数据;
  • 修改/添加/删除更新数据等;

ContentProvider 是如何向外界提供数据的?
Android提供了ContentProvider,一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据完全暴露出去,而 且ContentProviders是以类似数据库中表的方式将数据暴露,也就是说ContentProvider就像一个“数据库”。那么外界获取其提 供的数据,也就应该与从数据库中获取数据的操作基本一样,只不过是采用URI来表示外界需要访问的“数据库”。至于如何从URI中识别出外界需要的是哪个 “数据库”,这就是Android底层需要做的事情了,不在此详细说。简要分析下ContentProvider向外界提供数据操作的接口:
query(Uri, String[], String, String[], String)
insert(Uri, ContentValues)
update(Uri, ContentValues, String, String[])
delete(Uri, String, String[])
这些操作与数据库的操作基本上完全一样,在此不详细说,具体的解析可以参考
Android Sqlite解析
篇中的详细说明。需要特殊说明的地方是URI:

在URI的D部分可能包含一个_ID ,这个应该出现在SQL语句中的,可以以种特殊的方式出现,这就要求我们在提供数据的时候,需要来额外关注这个特殊的信息。AndroidSDK推荐 的方法是:在提供数据表字段中包含一个ID,在创建表时INTEGER PRIMARY KEY AUTOINCREMENT标识此ID字段。
ContentProvider 是如何组织数据的?
组织数据主要包括:存储数据,读取数据,以数据库的方式暴露数据。数据的存储需要根据设计的需求,选择合适的存储结构,首选数据库,当然也可以选择本地其 他文件,甚至可以是网络上的数据。数据的读取,以数据库的方式暴露数据这就要求,无论数据是如何存储的,数据最后必须以数据的方式访问。
可能还有2个问题,是需要关注的。
  • ContentProvider是什么时候创建的,是谁创建的?访问某个应用程序共享的数据,是否需要启动这个应用程序?这个问题在 Android SDK中没有明确说明,但是从数据共享的角度出发,ContentProvider应该是Android在系统启动时就创建了,否则就谈不上数据共享了。 这就要求在AndroidManifest.XML中使用元素明确定义。
  • 可能会有多个程序同时通过ContentResolver访问一个ContentProvider,会不会导致像数据库那样的“脏数 据”?这个问题一方面需要数据库访问的同步,尤其是数据写入的同步,在AndroidManifest.XML中定义ContentProvider的时 候,需要考虑是元素multiprocess属性的值;另外一方面Android在ContentResolver中提供了notifyChange() 接口,在数据改变时会通知其他ContentObserver,这个地方应该使用了观察者模式,在ContentResolver中应该有一些类似 register,unregister的接口。
    至此,已经对ContentProvider提供了比较全面的分析,至于如何创建ContentProvider,可通过2种方法:创建一个属于你自己的 ContentProvider或者将你的数据添加到一个已经存在的ContentProvider中,当然前提是有相同数据类型并且有写入 Content provider的权限。在Android SDK的sample中提供的
    Notepad具体实例
    中去看源代码!
  • 更多相关文章

    1. “罗永浩抖音首秀”销售数据的可视化大屏是怎么做出来的呢?
    2. Nginx系列教程(三)| 一文带你读懂Nginx的负载均衡
    3. 不吹不黑!GitHub 上帮助人们学习编码的 12 个资源,错过血亏...
    4. 说说Android桌面(Launcher应用)背后的故事(二)——应用程序的添
    5. (布局)Android(安卓)应用程序窗体显示状态操作(requestWindowFeatur
    6. android中Media Playback(媒体播放)
    7. android应用程序制定皮肤
    8. Android中实现SQLite数据库CRUD操作的两种方式
    9. AndroidStudio中使用Jacoco统计Android应用程序代码覆盖率

    随机推荐

    1. JavaScript 基本数据类型转换
    2. php种的匿名函数与返回值
    3. Java数据结构之平衡二叉树的原理与实现
    4. 轻松实现织梦网站数据迁移到新站点
    5. electron-builder打包配置详解
    6. DIV水平垂直居中方法
    7. C语言用递归函数实现汉诺塔
    8. Docker 安装 PHP并与Nginx的部署实例讲解
    9. array_values()在php中返回数组的操作实
    10. 递归函数删除缓存目录,数据库简单CURD(增删