`
Lagunarock
  • 浏览: 20175 次
  • 性别: Icon_minigender_1
  • 来自: 成都
文章分类
社区版块
存档分类
最新评论

ContentProvider学习笔记

阅读更多
一、首先要明白,ContentProvider(以下简称为CP)是什么。
1,是一套数据存储和获取的统一接口。
2,最大的特点是,可以在不同的应用程序间共享数据。
3,Android系统自身已经提供数个CP,包括音频、视频、通讯录的数据。
4,如第一条所说,CP是一套数据存储和获取的接口。所以有不同的实现,其中最常见的是使用SQLite的实现,数据被保存在一张表中。
5,CP需要向外部提供一个唯一的Uri(统一资源标识符),来标明资源的位置。该Uri的格式为:
content://xxx.yyy.zzz/aaa其中红色部分为统一的,表示协议、
xxx.yyy.zzz被称为authority,是一个唯一的字符串,按doc推荐,通常采用项目的包名、
蓝色部分/aaa被称为PathSegments,表示该资源更确切的位置,是一个目录结构。某些时候,可以将其理解为一张表。

二、自定义CP不是很有必要,除非应用需要向外部共享数据。一般都是使用Android系统提供的CP。

三、自定义CP的实现方法。
此处采用常见的SQLite方式实现。

1,书写一个类,继承android.content.ContentProvider,该类是抽象类,需要实现以下的方法:
  • boolean onCreate():很明显,该方法作为CP创建时由系统调用的方法,通常执行初始化操作。
  • Uri insert(Uri uri, ContentValues values):插入数据的方法,返回最新插入数据的Uri。
  • int delete(Uri uri, String selection, String[] selectionArgs):删除数据的方法,返回操作影响行数。
  • int update(Uri uri, ContentValues values, String selection,String[] selectionArgs):更新数据的方法,返回操作影响行数。
  • Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder):查询数据的方法,返回包含数据的游标对象。
  • String getType(Uri uri):取得该uri的MIME类型,返回表示MIME类型的字符串。

  • 从以上方法的参数可见,确实用SQLite的相关API来实现CP是很合适的。

    2,自定义CP必要的内容。
  • authority:确定了该CP的唯一性,Uri的必要组成部分,以常量的形式定义。同时需要在AndroidManifest.xml中进行配置。
  • eg:
    public static final String AUTHORITY = "org.ashtray.todolist";
  • uri:该CP的资源定位,以常量的形式定义。一个CP允许有多个Uri,以PathSegment进行区分和定位。
  • eg:
    public static finalUri URI_1 = Uri.parse("content://" + AUTORITY + "/location_1");

    最后的字符串location_1即为PathSegment。
  • 需要一个定义一个android.content.UriMatcher常量。在静态块中进行初始化。
  • eg:
    public static final UriMatcher matcher = null;
    public static final int TODOS = 0;
    public static final int TODO = 1;
    
    static{
         matcher = new UriMatcher(UriMatcher.NO_MATCH);
         //为matcher添加映射,用于过滤uri,
          //todolist,todolist/#为uri的形式,
          //TODOS,TODO未定义的两个整型常量,用于标识该类型的uri
         matcher.addURI(AUTHORTY, "todolist", TODOS);
         matcher.addURI(AUTHORTY, "todolist/#",  TODO);
    }
    
  • 以字符串常量的形式定义该CP拥有的MIME类型,通常需要定义两个,表示单条数据的MIME类型和复数条数据的MIME类型。
  • eg:
    public static final String CONTENT_ITEMS_TYPE= "vnd.android.cursor.dir/vnd.ashtray.todolist";
    public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.ashtray.todolist";
    

    vnd.android.cursor.item:固定的,表示单条数据。
    vnd.android.cursor.dir:固定的,表示复数数据。
    “/”之后为自定义,可随意。
  • 一个静态常量Map<String,String>,用于描述数据存储的结构,可以理解为描述表结构。即有哪些列和列的别名。
  • 此段内容在下在学习中也不甚懂,不知有什么必要,此处只姑且写出通常推荐的作法。
    public static final Map<String,String> projectionMap = null;
    static {
          projectionMap = new HashMap<String,String>();
          projectionMap.put("col_1","col_1"); 
          projectionMap.put("col_2","col_2"); 
          projectionMap.put("col_3","col_3"); 
    }
    


    3,几个重点方法的实现。
  • String getType(Uri uri)
  • 此方法主要的作用在于根据uri返回该uri所对应的数据MIME类型。
             @Override
    	public String getType(Uri uri) {
                      //UriMatcher对象的match方法,获取uri对应的int型标识
                         //该映射关系需要用首先用matcher.addURI进行添加
    		switch (matcher.match(uri)) {
                               
    			case Const.TODO:
                                        //返回uri对应的MIME类型
    				return Const.CONTENT_ITEM_TYPE;
    			case Const.TODOS:
    				return Const.CONTENT_ITEMS_TYPE;
    			default:
    				return null;
    		}
    	}
    

    个人认为,该方法的作用在于,在查询方法中判断是查询单条数据还是多条数据以作不同处理。如果是查询单条数据,即可从uri中取出所要查询数据的id
    //以List<String>的形式返回authority之后的内容,以“/”隔开
    String id = uri.getPathSegments().get(1)
    

  • Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder),查询方法
  • @Override
    	public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) 
    {
                      //通过SQLiteOpenHelper的实现类,获取数据库对象
    		SQLiteDatabase db = helper.getReadableDatabase();
    
    		//根据uri取得查询内容的MIME类型
    		String mime = this.getType(uri);
    
                      //创建查询
    		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
    		//设置描述数据结构的Map
                      qb.setProjectionMap(getProjection(projection));
    		
                      //如果MIME类型为查询单条数据,则从uri中取出数据的id,并添  加为查询的条件
    		if(Const.CONTENT_ITEM_TYPE.equalsIgnoreCase(mime)){
    			qb.appendWhere(Const.COL_ID + "=" + uri.getPathSegments().get(1));
    		}
                      //设置查询的表
    		qb.setTables(Const.TABLE_NAME);
                      //执行查询,并返回Cursor对象
    		Cursor cursor = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);
                      //设置更新通知,以获取最新的数据
             cursor.setNotificationUri(this.getContext().getContentResolver(), uri);
    		return cursor;
    	}
    

  • Uri insert(Uri uri, ContentValues values),插入数据方法。
  • SQLiteDatabase db = this.helper.getWritableDatabase();
    		long id = db.insert(Const.TABLE_NAME, null, values);
    		
    		if(id < 0){
    			throw new SQLException("insert field");
    		}
    		
    		//将插入数据的id添加到Uri并返回
    		Uri curr = ContentUris.withAppendedId(Const.TODO_LIST_URI, id);
                      //将新插入的数据uri进行通知,以便获取最新的数据
    		this.getContext().getContentResolver().notifyChange(curr, null);
    		return curr;
    


    4,Activity中使用CP。
    首先需要在AndroidManifest.xml中对自定义CP进行注册,
    eg:
      <provider
                      <!--自定义CP的类全名-->
       	android:name="org.ashtray.cp.TodoListContentProvider" 
             <!--authority,自定义CP的唯一标识,与代码中定义的字符串相同-->
        		android:authorities="org.ashtray.todolist"/>
    

    自定义CP在应用启动时,由系统实例化(调用CP的onCreate方法,并且会实例化所有注册了的CP),在Activity中通过ContentResolver来操作自定义CP。
    而对于查询,则调用Activty的mangedQuery方法。
    或者ContentResolver的query方法。
    分享到:
    评论

    相关推荐

      xamarin学习笔记A11(安卓ContentProvider)

      在Android平台上,ContentProvider是一种核心组件,它负责...以上就是关于Xamarin学习笔记A11中Android ContentProvider的相关知识点,深入理解和实践这些内容,将有助于你开发出更加健壮和功能丰富的跨平台应用程序。

      安卓学习之ContentProvider初步

      ContentProvider是Android系统中用于数据共享的重要组件,它是不同应用程序之间安全地交换数据的桥梁。当你想要在自己的应用中公开数据,允许其他应用进行访问时,就需要使用ContentProvider。虽然在许多情况下,...

      JAVA学习笔记

      【JAVA学习笔记】是一份专为Java初学者设计的学习资源,包含了从基础知识到进阶概念的全面讲解。PDF版的格式使得学习者可以方便地在各种设备上阅读和打印,随时随地提升自己的Java技能。 这份笔记可能涵盖了以下几...

      Android学习笔记之ContentProvider和Uri详解

      ContentProvider和Uri是Android系统中两个非常重要的概念,它们主要用于数据的共享和访问。在Android平台上,ContentProvider是一种机制,允许应用程序之间安全地共享数据,而Uri(Uniform Resource Identifier)则...

      Android基础学习笔记

      Android基础学习笔记主要涵盖了一系列关于Android开发的基本概念和关键组件,以下是这些知识点的详细解析: 1. **Activity**: 是Android应用程序的基本单元,它代表用户在屏幕上看到的一个界面。每个Activity都必须...

      安卓学习笔记大全

      【安卓学习笔记详解】 在安卓开发的学习过程中,了解并掌握基本概念和技术是非常关键的。以下是一些核心知识点的详述: 1. **字符集与编码**:Android系统默认使用UTF-8编码,而不是iso-8859-1。当你使用`getBytes...

      关于安卓开发的一些学习笔记

      这份"关于安卓开发的一些学习笔记"涵盖了初学者需要知道的基础概念、核心技术以及实践经验,旨在为刚接触安卓开发的人员提供指导。 首先,安卓开发的基础知识包括Java语言的学习。由于安卓应用主要基于Java语言编写...

      ContentProvider使用案例

      可能的场景是,开发者创建了一个ContentProvider来管理用户笔记,其他应用可以读取或添加新的笔记。在这个例子中,你可以学习到如何自定义Uri匹配规则,编写数据操作的逻辑,以及如何在其他应用中通过...

      Android四大组件ContentProvider

      学习和理解ContentProvider及ContentResolver的使用,对于开发Android应用尤其是涉及到数据共享和跨应用交互的场景至关重要。通过实践这些示例代码,开发者可以更好地掌握这两者的工作原理,并能灵活地应用于实际...

      安卓学习笔记

      【安卓学习笔记】是作者GcsSloop在学习Android开发过程中的个人心得和问题解决方案的集合,旨在帮助读者深入理解Android系统以及应用开发。这份笔记不仅涵盖了基础概念,还可能包含高级特性和最佳实践,是Android...

      ContentProvider 内容提供者完整代码

      通过深入学习和实践这个“ContentProvider 内容提供者完整代码”,我们可以掌握ContentProvider的实现细节,理解其在Android数据共享中的核心地位,这对于构建功能丰富的Android应用至关重要。同时,这也有助于提升...

      java、linux、Android 学习笔记

      【Java学习笔记】 Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems开发,现在由甲骨文公司维护。它的设计目标是提供平台无关性,这意味着Java编写的代码可以在任何支持Java虚拟机(JVM)的设备上运行...

      黑马程序员Android学习笔记

      《黑马程序员Android学习笔记》是一份专为初学者设计的详尽教程,旨在帮助那些希望踏入安卓开发领域的人员快速掌握核心知识。这份笔记涵盖了从基础到进阶的多个主题,帮助学习者系统地理解Android应用开发的过程。 ...

      android学习笔记2

      本笔记主要围绕"android学习笔记2"展开,特别关注了如何在Android应用中集成并使用百度地图API。这是一份适合自学Android开发者的资源,旨在提升你在Android平台上的实践能力。 首先,让我们深入了解一下Android...

      android学习笔记3(联系人应用)

      总结,这篇“android学习笔记3(联系人应用)”涵盖了Android中与联系人应用相关的多个方面,包括ContentProvider的工作原理、ContactsContract的使用、数据操作的方法、权限管理、以及源码分析等。对于想要深入理解...

      android 学习笔记doc

      这篇学习笔记涵盖了Android开发的基本知识点,旨在帮助初学者系统地理解和深入探索这个平台。 1. **Android系统架构**:Android由Linux内核、硬件抽象层(HAL)、运行库层、应用程序框架层和应用程序层组成。了解...

      android学习笔记最新版(1-4)

      《Android学习笔记最新版(1-4)》是一份针对初学者精心编撰的教程,旨在帮助新手快速掌握Android开发的基础知识。这份笔记涵盖了从环境搭建到应用开发的全过程,内容丰富,深入浅出,是Android学习者的理想参考资料...

      Android学习笔记.rar

      这份“Android学习笔记”涵盖了从基础到进阶的Android开发知识,旨在帮助开发者深入理解Android系统,并具备开发高质量Android应用的能力。 一、Android系统架构 Android系统分为四个主要层次:Linux内核、系统库和...

    Global site tag (gtag.js) - Google Analytics