使用 ContentProviderOperation 来提升性能

来源:互联网 发布:windows视频剪辑 编辑:程序博客网 时间:2024/05/12 21:50

使用 ContentProviderOperation 来提升性能

ContentProviders  是android 系统核心组件之一,ContentProviders 封装了数据的访问接口,其底层数据一般都是保存在数据库中或者保存在云端。

因为Builder设计模式设计模式是将数据直接封装到ContentProviderOperation里面,然后添加到定义好的ArrayList<ContentProviderOperation>()集合中,可以实现批量操作,具体怎样批量操作示例,提升性能。而ContentResolver的对应函数只能调用多次,比较耗时

为了使批量更新、插入、删除数据更加方便,android系统引入了 ContentProviderOperation类。

在官方开发文档中推荐使用ContentProviderOperations,有一下原因:

  1. 所有的操作都在一个事务中执行,这样可以保证数据完整性
  2. 由于批量操作在一个事务中执行,只需要打开和关闭一个事务,比多次打开关闭多个事务性能要好些
  3. 使用批量操作和多次单个操作相比,减少了应用和content provider之间的上下文切换,这样也会提升应用的性能,并且减少占用CPU的时间,当然也会减少电量的消耗。


要创建ContentProviderOperation对象,则需要使用 ContentProviderOperation.Builder类,通过调用下面几个静态函数来获取一个Builder 对象:

获取Builder 对象的函数函数用途newInsert创建一个用于执行插入操作的BuildernewUpdate创建一个用于执行更新操作的BuildernewDelete创建一个用于执行删除操作的Builder

这个Buidler对象使用了著名的Builder设计模式。

由于Builder对象的函数都返回了自己,所以通过一系列的函数调用即可生成最终的ContentProviderOperation对象。

1
2
3
4
5
6
7
8
ArrayList<ContentProviderOperation> ops =
   newArrayList<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()函数来应用批量操作:

1
2
3
4
5
6
7
8
try {
   getContentResolver().
      applyBatch(ContactsContract.AUTHORITY, ops);
} catch(RemoteException e) {
   // do s.th.
} catch(OperationApplicationException e) {
   // do s.th.
}

批量操作很简单,提示性能很容易!

示例:

  1. package com.example.contactdemos.test;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. import android.content.ContentProviderOperation;  
  6. import android.content.ContentProviderResult;  
  7. import android.content.OperationApplicationException;  
  8. import android.os.RemoteException;  
  9. import android.provider.ContactsContract;  
  10. import android.test.AndroidTestCase;  
  11.   
  12. public class ContactsTest extends AndroidTestCase {  
  13.   
  14.     /** 
  15.      * 根据主键ID更新 
  16.      */  
  17.     public void updateByData_ID() {  
  18.   
  19.         ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();  
  20.         // 把与这个display_name关联的data2,data3,data5清空,主要是保证(raw_contacts表中的display_name的正确性)  
  21.         ContentProviderOperation operation = ContentProviderOperation  
  22.                 .newUpdate(ContactsContract.Data.CONTENT_URI)  
  23.                 .withSelection(ContactsContract.Data._ID + "=?",  
  24.                         new String[] { String.valueOf(1) })  
  25.                 .withValue(  
  26.                         ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,// 对应data表中的data2字段  
  27.                         null)  
  28.                 .withValue(  
  29.                         ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,// 对应data表中的data3字段  
  30.                         null)  
  31.                 .withValue(  
  32.                         ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME,// 对应data表中的data5字段  
  33.                         null)  
  34.                 .withValue(  
  35.                         ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,// 对应data表中的data1字段  
  36.                         "陈红军").build();  
  37.   
  38.         ops.add(operation);  
  39.         try {  
  40.   
  41.             ContentProviderResult rs[] = getContext().getContentResolver()  
  42.                     .applyBatch(ContactsContract.AUTHORITY, ops);  
  43.   
  44.             for (ContentProviderResult s : rs) {  
  45.                 System.out.println(s.toString());  
  46.             }  
  47.         } catch (RemoteException e) {  
  48.             // TODO Auto-generated catch block  
  49.             e.printStackTrace();  
  50.         } catch (OperationApplicationException e) {  
  51.             // TODO Auto-generated catch block  
  52.             e.printStackTrace();  
  53.         }  
  54.   
  55.     }  
  56.   
  57.     /** 
  58.      * 根据raw_contact_id和mimetype更新的操作 
  59.      */  
  60.     public void updateByRawContactIdAndMimeType() {  
  61.   
  62.         ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();  
  63.   
  64.         // 把与这个display_name关联的data2,data3,data5清空,主要是保证(raw_contacts表中的display_name的正确性)  
  65.         ContentProviderOperation operation = ContentProviderOperation  
  66.                 .newUpdate(ContactsContract.Data.CONTENT_URI)  
  67.                 .withSelection(  
  68.                         ContactsContract.Data.RAW_CONTACT_ID + "=?" + " AND "  
  69.                                 + ContactsContract.Data.MIMETYPE + "=?",  
  70.                         new String[] {  
  71.                                 String.valueOf(1),  
  72.                                 ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE })  
  73.                 .withValue(  
  74.                         ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, // 对应data表中的data2字段  
  75.                         null)  
  76.                 .withValue(  
  77.                         ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, // 对应data表中的data3字段  
  78.                         null)  
  79.                 .withValue(  
  80.                         ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME,// 对应data表中的data5字段  
  81.                         null)  
  82.                 .withValue(  
  83.                         ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,// 对应data表中的data1字段  
  84.                         "夏淑琼").build();  
  85.   
  86.         ops.add(operation);  
  87.         try {  
  88.   
  89.             ContentProviderResult rs[] = getContext().getContentResolver()  
  90.                     .applyBatch(ContactsContract.AUTHORITY, ops);  
  91.   
  92.             for (ContentProviderResult s : rs) {  
  93.                 System.out.println(s.toString());  
  94.             }  
  95.         } catch (RemoteException e) {  
  96.             // TODO Auto-generated catch block  
  97.             e.printStackTrace();  
  98.         } catch (OperationApplicationException e) {  
  99.             // TODO Auto-generated catch block  
  100.             e.printStackTrace();  
  101.         }  
  102.     }  



0 0