使用ContentProviderOperation 来提升应用性能
来源:互联网 发布:七天网络网页版 编辑:程序博客网 时间:2024/05/23 22:01
ContentProviders 是android 系统核心组件之一,ContentProviders 封装了数据的访问接口,其底层数据一般都是保存在数据库中或者保存在云端。
有时候你需要更新多行数据,可以选择调用多次ContentResolver的对应函数,或者 使用批量操作。当然 后者性能会比较好些。
为了使批量更新、插入、删除数据更加方便,android系统引入了 ContentProviderOperation类。
在官方开发文档中推荐使用ContentProviderOperations,有一下原因:
所有的操作都在一个事务中执行,这样可以保证数据完整性
由于批量操作在一个事务中执行,只需要打开和关闭一个事务,比多次打开关闭多个事务性能要好些
使用批量操作和多次单个操作相比,减少了应用和content
provider之间的上下文切换,这样也会提升应用的性能,并且减少占用CPU的时间,当然也会减少电量的消耗。
要创建ContentProviderOperation对象,则需要使用 ContentProviderOperation.Builder类,通过调用下面几个静态函数来获取一个Builder 对象:
获取Builder 对象的函数
函数 用途
- newInsert 创建一个用于执行插入操作的Builder
- newUpdate 创建一个用于执行更新操作的Builder
- newDelete 创建一个用于执行删除操作的Builder
这个Buidler对象使用了著名的Builder设计模式。
由于Builder对象的函数都返回了自己,所以通过一系列的函数调用即可生成最终的ContentProviderOperation对象。
Java
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();ops.add( ContentProviderOperation.newInsert(RawContacts.CONTENT_URI) .withValue(RawContacts.ACCOUNT_TYPE, "someAccountType") .withValue(RawContacts.ACCOUNT_NAME, "someAccountName") .withYieldAllowed(true) .build());
当然 你还可以使用熟悉的ContentValues对象,对应的函数为withValues(values)。
下表是Builder对象核心函数的介绍:
Builder主要函数介绍
withSelection (String selection, String[] selectionArgs)
指定需要操作的数据条件。只有在更新、删除操作中有用。withValue (String key, Object value)
定义一列的数据值。只在更新、插入数据中有用。withValues (ContentValues values)
定义多列的数据值。 只在更新、插入数据中有用。
另外注意上面示例代码中是使用ArrayList来保存 ContentProviderOperation操作的。后面在介绍withValueBackReference()函数作用的时候就知道为啥用 有序的ArrayList而不是其他List。
最后通过ContentResolver 的applyBatch()函数来应用批量操作:
Java
try { getContentResolver(). applyBatch(ContactsContract.AUTHORITY, ops);} catch (RemoteException e) { // do s.th.} catch (OperationApplicationException e) { // do s.th.}
批量操作很简单,提升性能很容易!
以批量添加联系人为例:
public static void batchAddContact(Context context, List<FriendBean> list) throws RemoteException, OperationApplicationException { ArrayList<ContentProviderOperation> ops = new ArrayList<>(); int rawContactInsertIndex = 0; for (FriendBean contact : list) { rawContactInsertIndex = ops.size(); // 有了它才能给真正的实现批量添加 ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null) .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null) .withYieldAllowed(true).build()); // 添加姓名 ops.add(ContentProviderOperation .newInsert( android.provider.ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Contacts.Data.RAW_CONTACT_ID, rawContactInsertIndex) .withValue(ContactsContract.Contacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, contact.getName()) .withYieldAllowed(true).build()); // 添加号码 ops.add(ContentProviderOperation .newInsert( android.provider.ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Contacts.Data.RAW_CONTACT_ID, rawContactInsertIndex) .withValue(ContactsContract.Contacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getPhone()) .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE) .withValue(ContactsContract.CommonDataKinds.Phone.LABEL, "").withYieldAllowed(true).build()); } // 真正添加 context.getContentResolver() .applyBatch(ContactsContract.AUTHORITY, ops);}
批量删除联系人
public static void batchDeleteContact(Context context, List<FriendBean> list) throws RemoteException, OperationApplicationException { ArrayList<ContentProviderOperation> ops = new ArrayList<>(); for (FriendBean contact : list) { String name = contact.getName(); //根据姓名求id Uri uri = Uri.parse("content://com.android.contacts/raw_contacts"); ContentResolver resolver = context.getContentResolver(); Cursor cursor = resolver.query(uri, new String[]{ContactsContract.Data._ID}, "display_name=?", new String[]{name}, null); if(cursor.moveToFirst()){ int id = cursor.getInt(0); //根据id删除data中的相应数据 ops.add(ContentProviderOperation.newDelete(uri).withSelection("display_name=?",new String[]{name}).build()); uri = Uri.parse("content://com.android.contacts/data"); ops.add(ContentProviderOperation.newDelete(uri).withSelection("raw_contact_id=?",new String[]{id + ""}).build()); } } context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);}
如果您还没有使用ContentProviderOperation,赶紧修改吧!
- 使用ContentProviderOperation 来提升应用性能
- 使用 ContentProviderOperation 来提升性能
- 使用 ContentProviderOperation 来提升性能
- 使用 ContentProviderOperation 来提升性能
- 使用 ContentProviderOperation 来提升性能
- ContentProviderOperation批量操作提升性能
- 使用NLB提升企业高层应用性能
- 使用RSS提升DPDK应用的性能
- 使用RSS提升DPDK应用的性能
- ContentProviderOperation
- Android Training - 提升布局文件的性能(Lesson 4 - 使用ViewHolder来提升ListView的性能)
- 使用Redis+TCMalloc组合来提升服务器性能
- 使用局部索引来提升 PostgreSQL 的性能
- android 应用性能提升
- android 应用性能提升
- Web 应用性能提升
- 使用Cache-Control和gzip提升tomcat应用性能(整理)
- 使用 WebSphere Application Server 动态缓存技术提升应用性能
- Android studio 多环境打包和多渠道打包
- 【贪心】Codeforces698A-Vacations
- 杭电acm-------2502月之数
- GUI系列文章——GUI发展史
- spring中的Ioc技术是怎样实现解耦的
- 使用ContentProviderOperation 来提升应用性能
- HDU 5744 Keep On Movin
- 论文中的长句子
- Tree Preorder, Inorder, and Postorder Iteratively Summarization
- 记PHPStudy-win10系统80端口被占用的经历
- hdu5724 博弈+SG函数+状压 多校1
- scala parse使用记录
- hdoj 1014 Divding(03背包问题)
- 计算几何:极角排序(poj 2007 Scrambled Polygon)与简单凸包(poj 1113 Wall)