热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

深入解析Android联系人数据库设计:AbstractContactsProvider

本文探讨了Android系统中联系人数据库的设计,特别是AbstractContactsProvider类的作用与实现。文章提供了对源代码的详细分析,并解释了该类如何支持跨数据库操作及事务处理。源代码可从官方Android网站下载。

本文旨在深入探讨Android系统中联系人数据库的设计,尤其是AbstractContactsProvider类的关键作用及其内部实现机制。通过本文,读者可以了解该类如何有效地管理跨数据库操作及事务处理,从而提高应用性能和数据安全性。


AbstractContactsProvider是联系人和用户资料提供者的公共基类,它不仅处理了SQLiteContentProvider中类似的数据库逻辑,还向子类暴露了批处理操作的支持,以便能够处理跨数据库的操作。


package com.android.providers.contacts;

import android.content.ContentProvider;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteTransactionListener;
import android.net.Uri;

import java.util.ArrayList;

/**
* AbstractContactsProvider是联系人和用户资料提供者的公共基类。它处理了SQLiteContentProvider中的大部分相同逻辑,
* 同时向子类暴露了批处理操作的支持,以实现跨数据库操作。
*/
public abstract class AbstractContactsProvider extends ContentProvider implements SQLiteTransactionListener {

/**
* 在批处理操作成功释放锁后休眠的时间(毫秒)。
*/
protected static final int SLEEP_AFTER_YIELD_DELAY = 4000;

/**
* 单个批处理操作中允许的最大操作数。
*/
private static final int MAX_OPERATIONS_PER_YIELD_POINT = 500;

/**
* 在批处理操作中,每执行一定数量的插入操作后释放锁的数量。
*/
private static final int BULK_INSERTS_PER_YIELD_POINT = 50;

/**
* 当前线程活跃的联系人事务。
*/
private ThreadLocal mTransactionHolder;

/**
* 为此内容提供者使用的数据库帮助器。
*/
private SQLiteOpenHelper mDbHelper;

/**
* 用于序列化所有事务的数据库帮助器。如果非空,则此提供者创建的所有新事务都将自动从该帮助器获取一个可写的数据库实例并启动事务。
*/
private SQLiteOpenHelper mSerializeOnDbHelper;

/**
* 序列化事务的标签,与数据库对应。
*/
private String mSerializeDbTag;

@Override
public boolean onCreate() {
Context cOntext= getContext();
mDbHelper = getDatabaseHelper(context);
mTransactiOnHolder= getTransactionHolder();
return true;
}

public SQLiteOpenHelper getDatabaseHelper() {
return mDbHelper;
}

/**
* 设置用于序列化事务的数据库帮助器及其对应的标签。
* @param serializeOnDbHelper 用于序列化事务的数据库帮助器。
* @param tag 对应数据库的标签。
*/
public void setDbHelperToSerializeOn(SQLiteOpenHelper serializeOnDbHelper, String tag) {
mSerializeOnDbHelper= serializeOnDbHelper;
mSerializeDbTag = tag;
}

public ContactsTransaction getCurrentTransaction() {
return mTransactionHolder.get();
}

@Override
public Uri insert(Uri uri, ContentValues values) {
ContactsTransaction transaction = startTransaction(false);
try {
Uri result = insertInTransaction(uri, values);
if (result != null) {
transaction.markDirty();
}
transaction.markSuccessful(false);
return result;
} finally {
endTransaction(false);
}
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
ContactsTransaction transaction = startTransaction(false);
try {
int deleted = deleteInTransaction(uri, selection, selectionArgs);
if (deleted > 0) {
transaction.markDirty();
}
transaction.markSuccessful(false);
return deleted;
} finally {
endTransaction(false);
}
}

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
ContactsTransaction transaction = startTransaction(false);
try {
int updated = updateInTransaction(uri, values, selection, selectionArgs);
if (updated > 0) {
transaction.markDirty();
}
transaction.markSuccessful(false);
return updated;
} finally {
endTransaction(false);
}
}

@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
ContactsTransaction transaction = startTransaction(true);
int numValues = values.length;
int opCount = 0;
try {
for (int i = 0; i insert(uri, values[i]);
if (++opCount >= BULK_INSERTS_PER_YIELD_POINT) {
opCount = 0;
try {
yield(transaction);
} catch (RuntimeException re) {
transaction.markYieldFailed();
throw re;
}
}
}
transaction.markSuccessful(true);
} finally {
endTransaction(true);
}
return numValues;
}

@Override
public ContentProviderResult[] applyBatch(ArrayList operations)
throws OperationApplicationException {
int ypCount = 0;
int opCount = 0;
ContactsTransaction transaction = startTransaction(true);
try {
final int numOperatiOns= operations.size();
final ContentProviderResult[] results = new ContentProviderResult[numOperations];
for (int i = 0; i if (++opCount >= MAX_OPERATIONS_PER_YIELD_POINT) {
throw new OperationApplicationException(
"Too many content provider operations between yield points. "
+ "The maximum number of operations per yield point is "
+ MAX_OPERATIONS_PER_YIELD_POINT, ypCount);
}
final ContentProviderOperation operation = operations.get(i);
if (i > 0 && operation.isYieldAllowed()) {
opCount = 0;
try {
if (yield(transaction)) {
ypCount++;
}
} catch (RuntimeException re) {
transaction.markYieldFailed();
throw re;
}
}
results[i] = operation.apply(this, results, i);
}
transaction.markSuccessful(true);
return results;
} finally {
endTransaction(true);
}
}

/**
* 如果当前没有事务,则启动一个新的事务,并设置线程局部事务变量进行跟踪。如果已经有一个事务,则返回该事务。
* @param callerIsBatch 调用者是否处于批处理模式。
*/
private ContactsTransaction startTransaction(boolean callerIsBatch) {
ContactsTransaction transaction = mTransactionHolder.get();
if (transaction == null) {
transaction = new ContactsTransaction(callerIsBatch);
if (mSerializeOnDbHelper != null) {
transaction.startTransactionForDb(mSerializeOnDbHelper.getWritableDatabase(),
mSerializeDbTag, this);
}
mTransactionHolder.set(transaction);
}
return transaction;
}

/**
* 结束当前事务并清除成员变量。这不会将事务标记为成功。
* @param callerIsBatch 调用者是否处于批处理模式。
*/
private void endTransaction(boolean callerIsBatch) {
ContactsTransaction transaction = mTransactionHolder.get();
if (transaction != null && (!transaction.isBatch() || callerIsBatch)) {
try {
if (transaction.isDirty()) {
notifyChange();
}
transaction.finish(callerIsBatch);
} finally {
mTransactionHolder.set(null);
}
}
}

/**
* 获取此联系人提供者使用的数据库帮助器。在onCreate()期间调用一次。
*/
protected abstract SQLiteOpenHelper getDatabaseHelper(Context context);

/**
* 获取用于跟踪事务的线程局部事务持有者。在onCreate()期间调用一次。如果多个类继承自此类并且需要在同一事务中保持同步,
* 它们必须返回相同的线程局部实例。
*/
protected abstract ThreadLocal getTransactionHolder();

protected abstract Uri insertInTransaction(Uri uri, ContentValues values);

protected abstract int deleteInTransaction(Uri uri, String selection, String[] selectionArgs);

protected abstract int updateInTransaction(Uri uri, ContentValues values, String selection,
String[] selectionArgs);

protected abstract boolean yield(ContactsTransaction transaction);

protected abstract void notifyChange();
}

以上代码展示了AbstractContactsProvider类的核心功能,包括事务管理和批处理操作的支持。通过这种方式,可以有效地管理复杂的数据库操作,确保数据的一致性和完整性。


推荐阅读
  • 本文详细介绍了PHP中的几种超全局变量,包括$GLOBAL、$_SERVER、$_POST、$_GET等,并探讨了AJAX的工作原理及其优缺点。通过具体示例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 2023年1月28日网络安全热点
    涵盖最新的网络安全动态,包括OpenSSH和WordPress的安全更新、VirtualBox提权漏洞、以及谷歌推出的新证书验证机制等内容。 ... [详细]
  • Android 中的布局方式之线性布局
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 使用TabActivity实现Android顶部选项卡功能
    本文介绍如何通过继承TabActivity来创建Android应用中的顶部选项卡。通过简单的步骤,您可以轻松地添加多个选项卡,并实现基本的界面切换功能。 ... [详细]
  • 本文详细介绍了在PHP中如何获取和处理HTTP头部信息,包括通过cURL获取请求头信息、使用header函数发送响应头以及获取客户端HTTP头部的方法。同时,还探讨了PHP中$_SERVER变量的使用,以获取客户端和服务器的相关信息。 ... [详细]
  • 在AngularJS中,有时需要在表单内包含某些控件,但又不希望这些控件导致表单变为脏状态。例如,当用户对表单进行修改后,表单的$dirty属性将变为true,触发保存对话框。然而,对于一些导航或辅助功能控件,我们可能并不希望它们触发这种行为。 ... [详细]
  • 使用 ModelAttribute 实现页面数据自动填充
    本文介绍了如何利用 Spring MVC 中的 ModelAttribute 注解,在页面跳转后自动填充表单数据。主要探讨了两种实现方法及其背后的原理。 ... [详细]
  • Hadoop MapReduce 实战案例:手机流量使用统计分析
    本文通过一个具体的Hadoop MapReduce案例,详细介绍了如何利用MapReduce框架来统计和分析手机用户的流量使用情况,包括上行和下行流量的计算以及总流量的汇总。 ... [详细]
  • 本文由chszs撰写,详细介绍了Apache Mina框架的核心开发流程及自定义协议处理方法。文章涵盖从创建IoService实例到协议编解码的具体步骤,适合希望深入了解Mina框架应用的开发者。 ... [详细]
  • 本文分享了作者在使用LaTeX过程中的几点心得,涵盖了从文档编辑、代码高亮、图形绘制到3D模型展示等多个方面的内容。适合希望深入了解LaTeX高级功能的用户。 ... [详细]
  • 本文详细探讨了编程中的命名空间与作用域概念,包括其定义、类型以及在不同上下文中的应用。 ... [详细]
  • 轮播图(Carousel)是网页设计中常见的元素,用于展示图片或内容滚动。本文精选了超过40个高质量的jQuery轮播图插件及教程,帮助开发者实现各种动态展示效果。 ... [详细]
  • 1,滤波流程2,图像的金字塔分解(拉普拉斯金字塔)3,金字塔傅里叶频率组合滤波(本文完ÿ ... [详细]
  • 本文探讨了在AspNetForums平台中实施基于角色的权限控制系统的方法,旨在为不同级别的用户提供合适的访问权限,确保系统的安全性和可用性。 ... [详细]
author-avatar
王乐668_802
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有