一篇文章带你学习ContentProvider及使用
ContentProvider作为Android应用程序中的四大组件之一,是一个特殊的存储数据的类型,它提供了一套标准的接口用来获取以及操作数据,并实现了在各个应用程序之间数据共享。
构成
关键类:Content Resolver 、Cursor(表示返回结果) 、URI(标识Provider,作为Resolver的查询参数)
内容解析器(Content Resolver)
在ContentProvider使用过程中,需要借用ContentResolver对象作为代理商,间接操作ContentProvider来获取数据。可以通过Context直接获取:
ContentResolver cr = content.getContentResovler();可以通过Content Resolver与任意Content Provider进行交互。
一般,每个Content Resolver都只有一个实例(单例模式),但可以与多个在不同应用或者进程中的Content Resolver进行通信。进程间通信可以通过ContentResolver和ContentProvider进行。
数据模型(data model)
Content Provider将其数据以数据库中简单的表示模型展现,一行表示一条记录,一列表示数据的某种类型和含义。每条记录都有一个数值_ID字段,唯一地标识一条记录。
查询返回结果以Cursor(游标,相似于指针)。
统一资源标识(URI)
URI代表了要操作的数据,URI主要包含两部分信息:1.需要操作的ContentProvider,2.对ContentProvider中的什么数据进行操作,一个URI由以下几个部分组成:
- scheme:ContentProvider(内容提供者)的scheme由Android规定为:content://。
- 主机名(Authority):用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
- 路径(path)可以用来标识我们要操作的数据,路径的构建应根据业务而定。
android定义许多CONTENT_URI常量用于标识自带的Content Provider。如
android.provider.Contacts.Phones.CONTENT_URIandroid.provider.Contacts.Photos.CONTENT_URI创立自己的ContentProvider
我们大家都知道让自己的数据和其它应用程序共享有两种方式:创立自己的Content Provider (即继承自Content Provider的子类)或者者是将自己的数据增加到已有的Content Provider中去,后者需要保证现有的Content Provider和自己的数据类型相同并且具备该 Content Provider的写入的权限。
假如需要创立一个Content Provider,则需要进行的工作主要分为以下3个步骤。
第一步:建立数据的存储系统
数据的存储系统可以由开发人员任意决定,一般来讲,大多数的Content Provider都通过Android的文件存储系统或者SQLite数据库建立自己的数据存储系统。
第二步:扩展 ContentProvider类
开发一个继承自ContentProvider类的子类代码来扩展ContentProvider类,在这个步骤主要的工作是将要共享的数据包装并以ContentResolver和Cursor对象能够访问到的形式对外展现。具体来说需要实现ContentProvider 类中的6个笼统方法。
ContentProvider示例程序(部分):
/** * Created by zhuyifei on 2016/7/13. */public class MyContentProvider extends ContentProvider { private static final int ACCOUNTS = 1; private static final int ACCOUNTS_ID = 2; private static final UriMatcher sUriMatcher; static { sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(TableContracts.AUTHORITY, TableContracts.Accounts.TABLE_PATH, ACCOUNTS); sUriMatcher.addURI(TableContracts.AUTHORITY, TableContracts.Accounts.TABLE_PATH_WITH_PARAM, ACCOUNTS_ID); } @Override public boolean onCreate() { return false; } @Nullable @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } @Nullable @Override public String getType(Uri uri) { return null; } @Nullable @Override public Uri insert(Uri uri, ContentValues values) { return null; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; }}以上方法将会在ContentResolver对象中调用,所以很好地实现这些笼统方法会为ContentResolver提供一个完善的外部接口。除了实现笼统方法外,还可以做少量提高可用性的工作。
定义一个 URI 类型的静态常量,命名为CONTENT_URI。 必需为该常量对象定义一个唯一的URI字符串,一般的做法是将ContentProvider子类的全称类名作为URI字符串,如:“自己设置”。
定义每个字段的列名,假如采用的数据库存储系统为SQLite 数据库,数据表列名可以采用数据库中表的列名。不论数据表中有没有其余的唯一标识一个记录的字段,都应该定义一个”_id”字段来唯一标识一个记录。模式使用 “INTEGER PRIMARY KEY AUTOINCREMENT” 自动升级 一般将这些列名字符串定义为静态常量, 如”_id”字段名定义为一个名为”_ID” 值为“_id”的静态字符串对象。
第三步:在应用程序的AdnroidManifest.xml 文件中公告Content Provider组件。
创立好一个Content Provider必需要在应用程序的AndroidManifest.xml 中进行公告,否则该Content Provider对于Android系统将是不可见的。假如有一个名为MyProvider的类扩展了 ContentProvider类,公告该组件的代码如下:
<provider name=".MyContentProvider(自己设置)" authorities="com.sjtu.demo.provider(TableContracts.AUTHORITY保持一致)" android:exported="false"...../> <!-- 为<provider>标记增加name、authorities等属性-->- name属性为ContentProvider子类的全称类名
- authorities属性唯一标识了一个ContentProvider。还可以通过setReadPermission()和setWritePermission() 来设置其操作权限。当然也可以再上面的 xml中加入 android:readPermission 或者者 android: writePermission属性来控制其权限。
- exported属性表示能否支持其余应用调用当前组件,true表示支持,false表示不支持。默认值:假如包含intent-filter默认值为true;否则为false
- 注意:由于ContentProvider可能被不同的进程和线程调用,所以这些方法必需是线程安全的。
自己是从事了七年开发的Android工程师,不少人私下问我,2019年Android进阶该怎样学,方法有没有?
没错,年初我花了一个多月的时间整理出来的学习资料,希望能帮助那些想进阶提升Android开发,却又不知道怎样进阶学习的朋友。【包括高级UI、性能优化、架构师课程、NDK、Kotlin、混合式开发(ReactNative+Weex)、Flutter等架构技术资料】,希望能帮助到您面试前的复习且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。
资料获取方式:加入Android架构交流QQ群聊:513088520 ,进群即领取资料!!!
点击链接加入群聊【Android移动架构总群】:加入群聊
资料大全
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 一篇文章带你学习ContentProvider及使用