Contacts的数据存储原理
来源:互联网 发布:软件测试实战项目 编辑:程序博客网 时间:2024/06/03 12:17
http://blog.sina.com.cn/s/blog_4ad8d46c010144cb.html
Contacts的数据存储原理(一)
Android平台中提供了5种数据存储的方式,分别是:
SQLite数据库存储数据、
Contacts的数据存储(二)
数据库的创建主要通过ContactsDatabaseHelper和LegacyApiSupport来进行创建。当应用加载完成后,每一个注册的contentprovider都会调用ContentProvider的onCreate()方法,完成contentprovider的初始化操作。当调用ContactsDatabaseHelper的OnCreate()之后,先完成自己模块内定义的操作,然后执行LegacyApiSupport中的crateDatabase()。
SyncStateContentProvider
ContactsDatabaseHelper创建数据表及索引,主要创建contacts,raw_contacts, stream_items, stream_item_photos, photo_files,packages, mimetypes, data, phone_lookup, name_lookup,nickname_lookup, groups, agg_exceptions, settings,visible_contacts,directories,calls,voicemail_status,activities,status_updates,properties,accounts,data_usage_stat。索引是针对某个表而建立的,只会影响数据表内数据。
ContactsDatabaseHelper创建视图,在本模块主要创建了Contacts,raw_Contacts,Data和Groups相关的视图。主要有:view_data,view_raw_contacts,view_contacts,view_raw_entities,view_entities,view_data_usage_stat,view_stream_items和view_groups。
ContactsDatabaseHelper创建触发器,主要创建了以下几个触发器,具体作用可以参考代码:raw_contacts_deleted,raw_contacts_marked_deleted,data_updated,data_deleted,groups_update1,groups_auto_add_updated1。
ContactsDatabaseHelper创建索引,主要创建name_lookup表的索引name_lookup_index,raw_contacts表的索引raw_contact_sort_key1_index和raw_contact_sort_key2_index。
ContactsDatabaseHelper加载nickname_lookup数据,首先删除nickname_lookup表数据,并获取数组common_nicknames中预定义的数据,然后全部插入到nickname_lookup表。
LegacyApiSupport模块创建数据库,主要完成了两个行为:创建视图和Settings表。
LegacyApiSupport模块创建视图,主要有view_v1_people,view_v1_organizations,view_v1_contact_methods,view_v1_phones,view_v1_extensions,view_v1_groups,view_v1_group_membership,view_v1_photos。
LegacyApiSupport模块创建settings表,主要是创建v1_settings数据表。
Contacts的数据存储(三)
数据库操作
数据库的操作对于用户来说,无非就是增加、删除、修改、查询,所以本节也主要针对以上几个方面进行讨论和分析。
数据库操作,主要分为两个模块ContactsProvider2和LegacyApiSupport进行处理。用户通过传递参数Uri,先匹配ContactsProvider2中定义的Uri,如果匹配成功则进行数据操作并返回。如果匹配不成功,则进入LegacyApiSupport中进行匹配,进行数据操作。
数据库涉及到读操作的行为,主要是数据查询,程序直接通过Uri匹配查询,返回数据集。
数据库涉及到写操作的行为,主要包括增加、删除、修改,针对多个数据表的操作ContactsProvider采用事务机制,多个数据表的数据的操作全部完成后,统一进行提交。单表操作,则不会使用。
事务机制具体定义如下:{
mDb.beginTransactionWithList
insertInTransaction()/updateInTransaction()/deleteInTransaction()
mDb.setTransactionSuccessful
mDb.endTransaction()
}
在beginTransactionWithList
而如何判断是否为多操作,ContactsProvider模块通过在SQLiteContentProvider文件的applyBatch()方法中设置标志变量来实现。
单表操作都是简单通过Uri定位匹配,从而完成数据库操作,实现上比较简单,就不多作分析。而多表操作,主要都是通过构建ContentProviderOperation
而raw_contacts表会使用contacts表的_id,contacts表会使用raw_contacts表的_id,data表会使用raw_contacts表和mimetypes表的_id,name_lookup表会使用data表和raw_contacts表的_id,phone_lookup表会使用data表和raw_contacts表的_id.
Contacts的数据存储(四)
下面将主要描述联系人的增加,删除,修改:
用户在联系人新增界面,填入需要的联系人信息数据,比如名字,电话号码,电子邮件等信息,用户点击保存时会通过EntitySet.buildDiff()方法进行构造ContentProviderOperation
调用applyBatch()函数过程中,会读取ContentProviderOperation
获取mimetype,并根据mimetype类型数据,获得不同的DataRowHandler,进行data数据的写入。(data数据操作具体见Data表数据增加、修改、删除章节)
用户在联系人编辑界面,更改需要修改的数据,比如名字,电话号码,电子邮件等信息,用户点击保存时会通过EntitySet.buildDiff()方法进行构造ContentProviderOperation
调用applyBatch()函数过程中,会读取ContentProviderOperation
获取mimetype,并根据mimetype类型数据,获得不同的DataRowHandler,进行data数据的更新。(data数据操作具体见Data表数据增加、修改、删除章节)
用户在联系人列表选择联系人的删除,本地联系人url匹配只是删除contacts表中的数据,标记raw_contacts表的字段deletde为1,而Data表的数据并没有发生变化。url匹配删除Sim卡联系人或者同步联系人时删除,会直接删除raw_contacts表的数据,并触发触发器raw_contacts_deleted,将data表,agg_exceptions表,contacts表的数据全部删除。
当用户进入到联系人编辑界面,删除某个数据。也就是只对联系人的data数据进行删除,而联系人数据未发生变化,这样会根据删除内容获得ContentProviderOperation
调用applyBatch()函数过程中,会读取ContentProviderOperation
最后根据mimetype类型数据,获得不同的DataRowHandler,进行data数据的删除。(data数据操作具体见Data表数据增加、修改、删除章节)
前面关于联系人数据的增删改时,最后对data表的操作,都是通过mimetype获得对应类型的DataRowHandler,从而对数据库进行操作。
在ContactsProvider2初始化时,会创建HashMap来装载DataRowHandler,具体常见ContactsProvider2.java中的initDataRowHandlers()函数。但涉及到data数据操作时,会根据其mimetype,获得HashMap中指定的DataRowHanlder,进而执行指定DataRowHanlder中定义的insert,update,delete方法。
目前ContactsProvider主要提供的DataHandlder继承关系图:
1)
主要处理mimetype为email的data数据。
插入操作:先插入data表,然后获取邮箱地址@前的字符串,并插入到name_lookup表。
修改操作:先更新data表,然后删除name_lookup表中的指定数据,重新获取邮箱地址@前的字符串,并插入到name_lookup表
删除操作:先删除data表,然后删除name_lookup表数据
2)
主要处理mimetype为phone的data数据。
插入操作:判断是否包含电话号码,包含的话先插入data表,然后更新phone_lookup表,不包含的话直接插入data表。
修改操作:判断是否包含电话号码,包含的话则更新data表,然后更新phone_lookup表,不包含的话直接更新data表。
删除操作:删除data表数据,更新phone_lookup表为空
3)
主要处理mimetype为organization的data数据。
插入操作:获取company和title字段值,先插入data表,然后将company和titile分别插入name_lookup表。
修改操作:更新data表,删除name_lookup表数据,重新获取company和title字段值,并将其插入到name_lookup表。
删除操作:删除data表数据,删除name_lookup表
4)
主要处理mimetype为nickname的data数据。
插入操作:获取nickname字段值,先插入data表,如果nickname不为空,插入到name_lookup表。
修改操作:更新data表,删除name_lookup表数据,重新获取nickname字段值,并将其插入到name_lookup表。
删除操作:删除data表数据,删除name_lookup表
5)
主要处理mimetype为group_membership的data数据。
插入操作:插入data表,调用更新contacts和raw_contacts表中的contact_in_visible_group字段。
修改操作:更新data表,调用更新contacts和raw_contacts表中的contact_in_visible_group字段。
删除操作:删除data表数据,调用更新contacts和raw_contacts表中的contact_in_visible_group字段。
6)
主要处理mimetype为photo的data数据。
插入操作:插入data表,调用更新contacts中的photo_id字段。
修改操作:更新data表,调用更新contacts中的photo_id字段。
删除操作:删除data表数据,调用更新contacts中的photo_id字段。
7)
主要处理mimetype为name的data数据。
插入操作:插入data表,通过函数insertNameLookupForStruc
修改操作:更新data表,删除name_lookup表数据,并通过调用函数insertNameLookupForStruc
删除操作:删除data表数据,删除name_lookup表数据。
8)
主要处理mimetype为postal-address的data数据。
插入操作:插入data表。
修改操作:更新data表。
删除操作:删除data表数据。
9)
EmailDataRowHandler、OrganizationDataRowHandl
CommonDataRowHandelr主要的数据操作,只是简单的对data表的增加、删除、修改。
10)
CustomDataRowHandler继承与DataRowHandler,主要功能:当用户通过mimetype获取HashMap中加载的handler时,获取的handler为空时,则创建CustomDataRowHandler做为数据处理的handler。
CustomDataRowHandler主要的数据操作,也只是简单的对data表的增加、删除、修改
Contacts的数据存储(五)
以上几篇都是转载,找不到原作者信息了,也不贴原链接了。
个人读后的收获有以下几点,这几点是我原来都比较模糊的:
(1)用户在联系人列表选择联系人的删除,本地联系人url匹配只是删除contacts表中的数据,标记raw_contacts表的字段deletde为1,而Data表的数据并没有发生变化。url匹配删除Sim卡联系人或者同步联系人时删除,会直接删除raw_contacts表的数据,并触发触发器raw_contacts_deleted,将data表,agg_exceptions表,contacts表的数据全部删除。
(2)在看搜索联系人的相关知识,发现Android原生系统是支持汉字全拼和汉字简拼查询的,查询的部分是在ContactsProvider2.java里面做的,但是对于拼音的获得以及存储是这样实现的:
HanziToPinyin.java是将汉字转换成对应的拼音的最原始的文件,ContactLocaleUtils.java对其进行了一层包装,负责提供对外的接口,这个类里面getNameLookupKeys(String name)获取了汉字的全拼拼音和简拼拼音(每个字拼音的首字母),存放在一个HashSet类型里。实际上,name_lookup表里的normalized_name并不存储这个拼音信息,这个信息存储在search_index_content表的c2name列里,搜索时c1content 或 c2name 或c3tokens就会将这个信息匹配出来。
- Contacts的数据存储原理
- Contacts Provider 联系人存储
- 存储XML格式数据的原理
- 存储XML格式数据的原理
- 微机原理:数据的多段存储
- 【iOS开发-76】Private Contacts案例:导航控制器使用、数据传递、第三方类库使用、tableViewCell的添加删除、数据存储等
- 数据存储原理历程
- memcache数据存储原理
- 【Cassandra】数据存储原理
- 误删文件恢复,系统启动原理,数据的存取原理(文件存储原理),文件恢复原理
- 误删文件恢复,系统启动原理,数据的存取原理(文件存储原理),文件恢复原理
- Android Contacts的使用
- ValueStack和OGNL实现Struts2表单数据的存储原理
- android多线程数据存储 - ThreadLocal的工作原理
- 实践题目——数值型数据的存储原理
- druid数据存储原理介绍
- 数据存储原理-查询优化
- SQL SERVER 存储原理 数据存储
- maven 加入json-lib.jar 报错 Missing artifact net.sf.json-lib:json-lib:jar:2.4:compile
- 通知的状况
- TextView支持的Html标签
- 66. Plus One
- JAVA WEB学习——tomcat服务器首页配置
- Contacts的数据存储原理
- MRC && ARC 混编
- 0.2 简单搭建C语言环境
- 浅析Java中的final关键字
- php函数,伪函数的使用:函数名长,会影响到性能?
- 企业版Oracle 11g服务器安装详细步骤——图文教程
- unity中的Transform类
- Linux中linuxrc的作用
- linux 常用命令