Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6039214
  • 博文数量: 2759
  • 博客积分: 1021
  • 博客等级: 中士
  • 技术积分: 4091
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-11 14:14
文章分类

全部博文(2759)

文章存档

2019年(1)

2017年(84)

2016年(196)

2015年(204)

2014年(636)

2013年(1176)

2012年(463)

分类: Android平台

2017-03-08 06:25:53

一般情况我们使用ContentProvider主要访问数据库数据,但有时也可能需要访问非数据库数据,如XML或者本地数据,那就需要做一下特殊处理
最主要的是需要自定义Cursor,因为ContentProvider的query方法,只能返回Cursor引用。直接上代码,咱们边看边说

点击(此处)折叠或打开

  1. public class MyContentProvider extends ContentProvider {
  2.     
  3.     //操作URI的类
  4.     public static final UriMatcher uriMatcher;
  5.     //为UriMatcher添加自定义的URI
  6.     static{
  7.         uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  8.         uriMatcher.addURI(ProviderConstant.AUTHORITIES,"/user",
  9.                 ProviderConstant.INCOMING_USER_COLLECTION);
  10.         uriMatcher.addURI(ProviderConstant.AUTHORITIES,"/user/#",
  11.                 ProviderConstant.INCOMING_USER_SINGLE);
  12.     }

  13.     private HashMap<String,ArrayList<String>> allDatas= new HashMap<String,ArrayList<String>>();
  14.        
  15.     
  16.     private MyCursor cursor;
  17.     
  18.     public MyContentProvider(){
  19.         cursor = new MyCursor();
  20.         loadAllData();
  21.     }
  22.     
  23.     
  24.     /**
  25.      * 加载我们的数据信息
  26.      */
  27.     public void loadAllData(){
  28.         allDatas.clear();
  29.         for(int pos=0; pos < 5;pos++){//填充5个学生数据
  30.             ArrayList<String> dataList = new ArrayList<>();
  31.             dataList.add(pos+"");//id
  32.             dataList.add("name"+pos);//name
  33.             allDatas.put(pos+"",dataList);
  34.         }
  35.     }
  36.     
  37.     /**
  38.      * 删除数据
  39.      */
  40.     @Override
  41.     public int delete(Uri uri, String selection, String[] selectionArgs) {
  42.         System.out.println("delete");
  43.         int count = 0;
  44.         String id = getUserId(selection, selectionArgs);
  45.         if(allDatas.containsKey(id)){
  46.             allDatas.remove(id);
  47.             count = 1;
  48.         }
  49.         return count;
  50.     }

  51.     /**
  52.      * 数据库访问类型
  53.      */
  54.     @Override
  55.     public String getType(Uri uri) {
  56.         System.out.println("getType");
  57.         //根据用户请求,得到数据类型
  58.         switch (uriMatcher.match(uri)) {
  59.             case ProviderConstant.INCOMING_USER_COLLECTION:
  60.                 return ProviderConstant.CONTENT_TYPE;
  61.             case ProviderConstant.INCOMING_USER_SINGLE:
  62.                 return ProviderConstant.CONTENT_TYPE_ITEM;
  63.             default:
  64.                 throw new IllegalArgumentException("UnKnown URI"+uri);
  65.         }
  66.     }

  67.     /**
  68.      * 插入数据
  69.      */
  70.     @Override
  71.     public Uri insert(Uri uri, ContentValues values) {
  72.         ArrayList<String> data = new ArrayList<>();
  73.         int id =values.getAsInteger(ProviderConstant.ID);
  74.         String name = values.getAsString(ProviderConstant.NAME);
  75.         data.add(id+"");
  76.         data.add(name);
  77.         allDatas.put(id+"", data);
  78.         return uri;
  79.     }

  80.     /**
  81.      * 创建ContentProvider时调用的回调函数
  82.      */
  83.     @Override
  84.     public boolean onCreate() {
  85.         System.out.println("onCreate");
  86.         return true;
  87.     }

  88.     /**
  89.      * 查询数据库
  90.      */
  91.     @Override
  92.     public Cursor query(Uri uri, String[] projection, String selection,
  93.             String[] selectionArgs, String sortOrder) {
  94.         //判断用户请求,查询所有还是单个
  95.         switch(uriMatcher.match(uri)){
  96.             case ProviderConstant.INCOMING_USER_COLLECTION:
  97.                cursor.updateAllData(allDatas.values());
  98.                 break;
  99.             case ProviderConstant.INCOMING_USER_SINGLE:
  100.                 String id = uri.getLastPathSegment();
  101.                 cursor.updateUserData(allDatas.get(id));
  102.                 break;
  103.         }
  104.         return cursor;
  105.     }

  106.     /**
  107.      * 更新数据库
  108.      */
  109.     @Override
  110.     public int update(Uri uri, ContentValues values, String selection,
  111.             String[] selectionArgs) {
  112.         System.out.println("update");
  113.         String id = getUserId(selection, selectionArgs);
  114.         int count=0;
  115.         if(allDatas.containsKey(id)){
  116.             String name = values.getAsString(ProviderConstant.NAME);
  117.             //index取决于name所在的列
  118.             allDatas.get(id).set(cursor.getColumnIndex(ProviderConstant.NAME), name);
  119.             count = 1;
  120.         }
  121.         return count;
  122.     }
  123.     
  124.     /**
  125.      * 获取关键信息,用户ID
  126.      * @param selection
  127.      * @param selectionArgs
  128.      * @return
  129.      */
  130.     private String getUserId(String selection, String[] selectionArgs){
  131.         if(selectionArgs == null || selectionArgs.length == 0){
  132.             //id 包含在selection里
  133.             return selection.substring(selection.indexOf("=")+1).trim();
  134.         }else{
  135.             return selectionArgs[0];
  136.         }
  137.     }

  138. }
以上是自定义contentProvider,网上有很多例子和说明,不在详述,我们主要看一下query,我返回自定义Cursor。
其中用到了一些常量如下:

点击(此处)折叠或打开

  1. public class ProviderConstant {
  2.   //URI的指定,此处的字符串必须和声明的authorities一致
  3.    public static final String AUTHORITIES = "com.zy.sports.app.MyContentProvider";

  4.    //访问该ContentProvider的URI
  5.    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITIES + "/user");
  6.    
  7.    //该ContentProvider所返回的数据类型的定义
  8.    public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.myprovider.user";
  9.    public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.myprovider.user";
  10.    
  11.    
  12.    //访问表的所有列
  13.    public static final int INCOMING_USER_COLLECTION = 1;
  14.    //访问单独的列
  15.    public static final int INCOMING_USER_SINGLE = 2;
  16.    
  17.    
  18.    public static final String ID = "id";
  19.    public static final String NAME = "name";

  20. }



自定义Cursor的代码如下:

点击(此处)折叠或打开

  1. public class MyCursor extends AbstractCursor{
  2.     private static final String TAG = "MyCursor";
  3.     
  4.     private String[] columnNames= null;//构建cursor时必须先传入列明数组以规定列数

  5.     /**
  6.      * 数据区域
  7.      */
  8.     //所有的数据
  9.     private ArrayList<ArrayList<String>> allDatas= new ArrayList<ArrayList<String>>();//在构造的时候填充数据,里层数据的size=columnNames.leng
  10.     //当前一项的数据
  11.     private ArrayList<String> oneLineData= null;//onMove时填充

  12.     public MyCursor(){
  13.         //必须构建完整列信息
  14.         columnNames = new String[]{"id","name"};
  15.     }
  16.     
  17.     /**
  18.      * 加载我们的数据信息
  19.      */
  20.     public void updateAllData(Collection<ArrayList<String>> data){
  21.         mPos = -1;
  22.         allDatas.clear();
  23.         allDatas.addAll(data);
  24.     }
  25.     
  26.     /**
  27.      * 加载我们的数据信息
  28.      */
  29.     public void updateUserData(ArrayList<String> data){
  30.         mPos = -1;
  31.         allDatas.clear();
  32.         allDatas.add(data);
  33.     }

  34.     /**
  35.      * 获取当前行对象,为一个oneLineDatastring[]
  36.      */

  37.     @Override
  38.     public boolean onMove(int oldPosition, int newPosition) {
  39.         if(newPosition< 0 || newPosition >= getCount()){
  40.             oneLineData= null;
  41.             return false;
  42.         }

  43.         int index = newPosition ;
  44.         if(index< 0 || index >= allDatas.size()){
  45.             return false;
  46.         }
  47.         oneLineData= allDatas.get(index);
  48.         return super.onMove(oldPosition,newPosition);
  49.     }

  50.     /**
  51.      *获取游标行数
  52.      */
  53.     @Override
  54.     public int getCount() {
  55.         return allDatas.size();
  56.     }

  57.     /**
  58.      * 获取列名称
  59.      */
  60.     @Override
  61.     public String[] getColumnNames() {
  62.         return columnNames;
  63.     }


  64.     @Override
  65.     public String getString(int column) {
  66.         if(oneLineData== null){
  67.             return null;
  68.         }
  69.         return oneLineData.get(column);
  70.     }
  71.     
  72.     @Override
  73.     public int getInt(int column) {
  74.         Object value = getString(column);
  75.         try{
  76.             return value != null? ((Number) value).intValue() : null;
  77.         } catch(ClassCastException e) {
  78.             if(value instanceof CharSequence) {
  79.                 try{
  80.                     return Integer.valueOf(value.toString());
  81.                 } catch(NumberFormatException e2) {
  82.                     Log.e(TAG,"Cannotparse int value for "+ value + "at key "+ column);
  83.                     return 0;
  84.                 }
  85.             } else{
  86.                 Log.e(TAG,"Cannotcast value for "+ column + "to a int: "+ value, e);
  87.                 return 0;
  88.             }
  89.         }
  90.     }

  91.     /**
  92.      * 以下参考getInt(int column)
  93.      */
  94.     
  95.     @Override
  96.     public short getShort(int column) {
  97.         return 0;
  98.     }

  99.     @Override
  100.     public long getLong(int column) {
  101.         return 0;
  102.     }

  103.     @Override
  104.     public float getFloat(int column) {
  105.         return 0;
  106.     }

  107.     @Override
  108.     public double getDouble(int column) {
  109.         return 0;
  110.     }

  111.     @Override
  112.     public boolean isNull(int column) {
  113.         return false;
  114.     }
  115. }
 我们看到Cursor是一个接口,我们只需要继承AbstractCursor或者他的子类来重定义Cursor的方法。大家可以参考,欢迎多提意见





阅读(2302) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~