Android中应用程序之间的数据共享
来源:互联网 发布:手机淘宝在哪开店 编辑:程序博客网 时间:2024/06/03 18:41
一、概述
如何将应用程序的数据暴露出去?Android提供了一种统一的接口,即ContentProvider,一个程序可以通过实现一个Content provider的抽象接口将自己的数据完全暴露出去,而且Content providers是以类似数据库中表的方式将数据暴露。Content providers存储和检索数据,通过它可以让所有的应用程序访问到,这也是应用程序之间唯一共享数据的方法。要想使应用程序的数据公开化,可通过2种方法:创建一个属于你自己的Content provider或者将你的数据添加到一个已经存在的Content provider中,前提是有相同数据类型并且有写入Content provider的权限。
如何通过统一的接口获取其他APP暴露的数据呢?Android提供了ContentResolver,APP通过ContentResolver访问ContentProvider中的数据(通过Uri查询数据)。
二、ContentProvider的使用
2.1 特点:
a、使用ContentProvider对外共享数据的好处是统一了数据的访问方式。
b、ContentProvider基本不需要用户与它的对象交互,系统会自动唤醒所有注册了的provider;
c、ContentProvider的OnCreate方法,并不是一直被系统调用的<网上好多人是误导,本人亲测,只有你第一次安装该apk的时候才会被调用>
d、ContentProvider通过uri来访问数据;
2.2 使用步骤
a、继承ContentProvider,并重写一些重要的方法:
public class PersonContentProvider extends ContentProvider{ public boolean onCreate() public Uri insert(Uri uri, ContentValues values) public int delete(Uri uri, String selection, String[] selectionArgs) public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) public String getType(Uri uri)}
b、在AndroidManifest.xml使用<provider>对该ContentProvider进行配置,为了能让其他应用找到该ContentProvider ,ContentProvider采用了authorities(主机名/域名)对它进行唯一标识,你可以把ContentProvider看作是一个网站(想想,网站也是提供数据者),authorities 就是他的域名:
<manifest.... > <application android:icon="@drawable/icon" android:label="@string/app_name"> <provider android:name=".PersonContentProvider"(需与a中继承的类名一致) android:authorities="com.ljq.providers.personprovider"/> </application></manifest>
c、当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver 类提供了与ContentProvider类相同签名的四个方法。
三、ContentProvider各种方法的重写
3.1 query
// 查询 @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); switch (sUriMatcher.match(uri)) { // 查询所有 case TASKS: qb.setTables(TASK_LIST_TABLE_NAME); qb.setProjectionMap(sTaskListProjectionMap); break; // 根据ID查询 case TASK_ID: qb.setTables(TASK_LIST_TABLE_NAME); qb.setProjectionMap(sTaskListProjectionMap); qb.appendWhere(Tasks._ID + "=" + uri.getPathSegments().get(1)); break; default: throw new IllegalArgumentException("Uri错误! " + uri); } // 使用默认排序 String orderBy; if (TextUtils.isEmpty(sortOrder)) { orderBy = TaskList.Tasks.DEFAULT_SORT_ORDER; } else { orderBy = sortOrder; } // 获得数据库实例 SQLiteDatabase db = mOpenHelper.getReadableDatabase(); // 返回游标集合 Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy); c.setNotificationUri(getContext().getContentResolver(), uri); return c; }
参数分析:
返回值:
Cursor对象
函数体分析:
a、SQLiteQueryBuilder:一个用来构造SQL查询语句的辅助类,可以方便的去访问SQLiteDatabase. 在构造SQL查询语句时,它同样也需要指定表名,指定列名,指定where条件。其中的方法使用如下:
setTables方法设置了它查询工作将要针对的表;
setProjectionMap方法:不同的uri设置了不同的projection map;
(这个map是对用户查询操作传入的column名和数据表中存在的column名进行了一个映射,这样一来,有些数据库中抽象的表的column名就可以通过这个projection map实现重新命名,以达到方便开发者做一些类似于数据库表联接(join)操作的目的。一般情况下数据库中的表的column名就已经够清晰了,所以你可以不用再在projection map里面做一些column重命名的操作了——也就是说,你可以将这个map对象中的key和value都设为同样的值(接下来的代码会有体现)。)
疑问:SQLiteDatabase不是有query吗,为什么要通过SQLiteQueryBuilder来查询呢?SQLiteQueryBuilder能提供什么?
b、UriMatcher类的使用
首先第一步,初始化:
private static final UriMatcher sUriMatcher;
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);(UriMatcher.NO_MATCH 表示不匹配任何路径的返回码)
第二步注册需要的Uri:
sUriMatcher.addURI(TaskList.AUTHORITY, "taskLists", TASKS);
sUriMatcher.addURI(TaskList.AUTHORITY, "taskLists/#", TASK_ID); (# 号为通配符,* 号为任意字符)
第三部,与已经注册的Uri进行匹配:
sUriMatcher.match(uri) (返回TASKS或者TASK_ID)
match方法匹配后会返回一个匹配码Code,即在使用注册方法addURI时传入的第三个参数。
c、setNotificationUri方法的使用(http://www.myexception.cn/database/487982.html)
3.2 insert的实现(以SQLiteDatabase.insert和ContentValues为基础,参见SQLiteDatabase知识点)
3.2.1 函数分析
原型:Uri android.content.ContentResolver.insert(Uri url,ContentValues values);
作用:在给定Uri对应的数据表中插入一行。If the content provider supports transactions the insertion will be atomic.
参数:
Uri url 要插入的表对应的Uri
ContentValues values 要插入行的内容。The key is the column name for the field。如果内容为空,将创建一个空行。
3.2.2 实现过程
a、检查Uri的有效性(UriMatcher)
if (sUriMatcher.match(uri) != TASKS) { throw new IllegalArgumentException("错误的 URI: " + uri); }
b、创建ContentValues对象,将参数中传递进来的values传递给该对象
ContentValues values; if (initialValues != null) { values = new ContentValues(initialValues); } else { values = new ContentValues(); }
c、创建SQLiteDatabase对象,利用SQLiteDatabase.insert方法插入新行
// 获得数据库实例 SQLiteDatabase db = mOpenHelper.getWritableDatabase(); // 保存数据返回行ID long rowId = db.insert(TASK_LIST_TABLE_NAME, Tasks.CONTENT, values);
if (rowId > 0) { Uri taskUri = ContentUris.withAppendedId(TaskList.Tasks.CONTENT_URI, rowId); getContext().getContentResolver().notifyChange(taskUri, null); return taskUri; } throw new SQLException("插入数据失败 " + uri);
疑问:
a、关于监视器的问题还没弄懂,参见
http://www.cnblogs.com/bastard/archive/2012/06/02/2531663.html
http://blog.csdn.net/xiazdong/article/details/7706977
http://blog.csdn.net/java2009cgh/article/details/7367940
b、关于异常的使用也没有深入。
3.3 delete的实现
http://blog.sina.com.cn/s/blog_69092aea0101879o.html
http://www.w3school.com.cn/sql/sql_and_or.asp
四、ContentResolver的使用
4.1 概述
4.2 常用方法
参看资料:
http://blog.csdn.net/feng88724/article/details/6331396
- Android中应用程序之间的数据共享
- Android 应用程序之间数据共享
- Android 应用程序之间数据共享—ContentProvider
- Android 应用程序之间数据共享—ContentResolver
- Android 应用程序之间数据共享—ContentResolver
- Android 应用程序之间数据共享—ContentResolver
- Android 应用程序之间数据共享—ContentResolver
- Android 应用程序之间数据共享—ContentProvider
- Android 应用程序之间数据共享—ContentResolver
- Android Application - 应用程序之间数据共享
- Android 应用程序之间数据共享—ContentProvider
- Android 应用程序之间数据共享—ContentResolver
- Android 应用程序之间数据共享—ContentProvider
- Android 应用程序之间数据共享—ContentResolver
- Android 应用程序之间数据共享—ContentProvider
- Android 应用程序之间数据共享—ContentProvider
- Android 应用程序之间数据共享—ContentResolver
- Android 应用程序之间数据共享—ContentResolver
- 泛型类 泛型方法
- Mac OS将就整个文件夹中的资源编译了.APP文件中
- 按照要求的输入输出格式进行日期字符串的转化
- [JavaScript] 兼容IE、FireFox、Chrome等浏览器的xml处理函数(xml同步/异步加载、xsl转换、selectSingleNode、selectNodes)
- 双击dhtmlgrid行,openwin方法弹出层,并传参到弹出层页面
- Android中应用程序之间的数据共享
- IOS7 UIPickerView
- DB基本概念之 --- 触发器
- Deep Learning in NLP (一)词向量和语言模型
- 菜单,菜单条,菜单项的使用
- 网站在移动端的打开速度慢怎么办
- Microsoft Application Center Test (ACT)微软测试工具
- 火狐安装不上flash插件
- 保存Activity的状态