zoukankan      html  css  js  c++  java
  • 第四章 ContentProvider(精通Android3 )

    REST和SOAP


    表征状态转移(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。

            目前在三种主流的Web服务实现方案中,因为REST模式的Web服务与复杂的SOAPXML-RPC对比来讲明显的更加简洁,越来越多的web服务开始采用REST风格设计和实现。

            需要注意的是,REST是设计风格而不是标准。REST通常基于使用HTTPURI,和XML以及HTML这些现有的广泛流行的协议和标准。

      • 资源是由URI来指定。
      • 对资源的操作包括获取、修改、创建和删除资源,这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。
      • 通过操作资源的表现形式来操作资源。
      • 资源的表现形式则是XML或者HTML,取决于读者是机器还是人,是消费web服务的客户软件还是web浏览器。当然也可以是任何其他的格式。
     
    简单对象访问协议SOAP,全写为Simple Object Access Protocol
            是交换数据的一种协议规范,使用在计算机网络Web服务(web service)中,交换带结构信息。SOAP为了简化网页服务器(Web Server)从XML数据库中提取数据时,节省去格式化页面时间,以及不同应用程序之间按照HTTP通信协议,遵从XML格式执行资料互换,使其抽象于语言实现、平台和硬件。
            简单对象访问协议(SOAP)是一种轻量的、简单的、基于 XML 的协议,它被设计成在 WEB 上交换结构化的和固化的信息。 SOAP 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议( HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)。它还支持从消息系统到远程过程调用(RPC)等大量的应用程序
     
     
    sqlite3 命令行

    Note:adb的提示符为#,sqlite3的提示符为sqlite>

    adb shell                 进入到shell
    ls -R /data/data/*/databases                   列出所有*.db文件:
    sqlite3              进入到sqlite3
    .exit                退出sqlite3
    .tables              列出数据库中的所有表
    .schema people       contacts.db的people表的create语句
    .help                帮助
     
     
     
    ContentProvider的架构

            设备上的每个ContentProvider都会使用字符串注册自身,这个字符串类似于域名,但称为授权(authority)。这个可唯一标识的字符串是此ContentProvider可提供的一组URI的基础,授权的注册在AndroidManifest.xml中时进行。
         标识NotePadProvider数据库中的笔记目录或集合的URI为:
             content://com.android.provider.NotePad/Notes
         标识具体笔记的URI为:
             content://com.android.provider.NotePad/Notes(其中#是特定的笔记的id)
     
    1.Android内容URI的结构
        从ContentProvider中获取的数据是由Android Cursor 对象表示的一些行和列的集合,Android中的内容URI具有以下通用形式:
        content://authority-name/path-segmetl/path-segmet2/etc...
        
        以content://com.android.provider.NotePad/Notes/23为例
    • content:之后,该URI包含授权的唯一标识符,该标识符用于在提供程序注册表中定位ContentProvider,在示例中com.android.provider.NotePad是URI的授权部分
    • /Notes/23是URI中特定于每个ContentProvider的路径部分,路径中的Notes和23称为路径片段。对URI的路径部分和路径片段部分的记录和解释由ContentProvider负责。通常路径的第一部分可以指向一个对象集合,/Notes标识一个笔记集合或目录,而/23指向特定的笔记
        
    2.Android MIME类型的结构
        就像网站返回给定URL的MIME类型一样(这使浏览器能够调用正确的程序来查看内容),ContentProvider还负责返回给定URI的MIME类型。这使用户能够灵活地查看数据。知道数据的类型之后,可能有多个程序知道如何处理该数据。例如,如果在硬盘上有一个文本文件,那么许多编辑器都可以显示该文本文件。取决于使用的操作系统,可能还可以选择使用哪个编辑器。
        Android MIME类型中的vnd表示这些类型和子类型具有非标准的、供应商特定的的形式。为了实现唯一性,Android使用了多个类似域规范的部分来进一步区分类型和子类型,而且,每个内容类型的Android MIME类型都具有两种形式:一个用于某条具体的记录,另一个用于多条记录。
    • 对于单条记录,MIME类型类似于:      vnd.android.cursor.item/vnd.yourcompanyname.contenttype
    • 对于记录或行的集合,MIME类型类似于:   vnd.android.cursor.dir/vnd.yourcompanyname.contenttype
        MIME类型广泛用于Android中,尤其是在Intent中,系统在Intent中根据数据的MIME类型来判断调用哪些活动。MIME类型总是通过ContentProvider从它们的URI得出的,在使用MIME类型时,需要注意以下3点:
    • 类型和子类型对于它们表表示的内容必须是唯一的
    • 如果类型和子类型不是标准的(在谈到具体的记录通常属于这种情况),则需要在它们前面添加vnd
    • 它们通常是针对具体需求添加了命名空间
        通过Android cursor返回的项集合的主要MIME类型应该始终为 vnd.android.cursor.dir ,通过Android cursor获取的单一项的主要MIME类型应该是vnd.android.cursor.item 
     
    3.使用URI读取数据
        要从ContentProvider获取数据,需要使用该ContentProvider提供的URI,因为ContentProvider定义的URI对该ContentProvider是唯一的,所以记录这些URI并使其能被程序员看到和调用非常重要。Android中包含的ContentProvider通过定义表示这些URI字符串常量来实现此目的。
        
        给定这些URI,从联系人提供程序获取单行联系人信息的代码类似于:
            Uri peopleUri = Contacts.People.CONTENT_URI;
            Uri myPersonUri = Uri.withAppendedPath(Contacts.People.CONTENT_URI,"23");
            Cursor cur = managedQuery( myPersonUri  ,null,null,null,null);
        Note:ContentProvider应该实现一组接口或是将列名称作为常量列出,以列出它支持的列。但是,定义列常量的类或接口也应该通过列命名约定、注释或文档清晰地表明列的类型,因为没有正式的方式通过常量指定列的类型
        
    4.使用游标(curosr)   
        游标的一些知识:
    • 游标是一个行集合
    • 读取数据之前,需要使用moveToFirst(),因为游标放在第一行之前
    • 需要知道列名称
    • 需要知道列类型
    • 所有字段访问方法都是基于列编号,所以必需首先将列名称转换为列编号
    • 游标可以随意移动(可以向前向后移动,也可以跳过一段距离)
    • 由于游标可以随意移动,所以可以向它获取行计数
       建议首先从游标显式的获取所引,以避免意外。为了找到游标中的行数,Android为游标对象提供了一个getConut()方法。
     
    5.使用where子句
        ContentProvider提供了两种方式来传递where子句
        a.通过URI
            String noteUri = "content://com.google.provider.NotePad/notes/23";
            Cursor cur = someActivity.managedQuery(noteUri
                         projection,//which columns to return 
                         null,      //where clause
                         null);     //orderby clause
        b.通过String子句与一组可替换的字符串数组参数的组合       
            Cursor cur = someActivity.managedQuery("content://com.google.provider.NotePad/notes/23";  //Uri
                         null,                   //String[] projection
                         "_id = ?"               //String selection
                         new String[] {23},      //String [] selectionArgs
                          null);                 //sortOrder
     
    6.插入记录
        Android使用类Android.content.ContentValues来保存将插入的单一录音的值,ContentValues是一个键/值对字典,非常类似于列名称和它们的值。要插入记录,首先将记录填充到ContentValues,然后告诉Android.content.ContentValues使用URI插入该记录。
        ContentValues values = new ContentValues();
        values.put("tile","New note");
        values.put("note","This is a new note");
        ContentResolver contentR = activity.getContentResolver();
        在NoteP示例中,
        Uri uri = contentResolver.insert(NotePad.Notes.CONTENT_URI,values);
        此调用返回一个指向新插入记录的URI,回返的URI将具有以下结构:                      
        NotePad.Notes.CONTENT_URI/new_id
     
    7.更新和删除
        更新使用的主要是:
        int numberOfRowUpdated = 
        activity.getContentReslover().update(
            Uri uri,       //数据URI类型
            ContentValues values,  //要更新的值
            String whereClause,    
            String [] selectionArgs);
       删除主要使用的是:
         int numberOfRowDeleted = 
        activity.getContentReslover().update(
            Uri uri,
            String whereClause,
            String [] selectionArgs);
     
    8.使用UriMatcher来解析URI
        Android的UriMatcher实用程序类有助于识别URI类型。它的工作原理:你告诉UriMatcher实例需要什么样的URI模式,还将一个唯一编号与每个模式关联,注册这些模式之后,可以询问UriMatcher,传入的URI是否与某个模式匹配。
     
    9.使用投影映射
        ContentProvider充当着抽象列集和数据库中真实的列集之间的媒介,这些列集可能是不同的。在构造查询时,必须在客户端指定的where子句列与真实的数据库列之间建立映射。可以借助SQLiteQueryBuilder类建立此投影映射。
     
     
    实现ContentProvider

        要编写ContentProvider,必须扩展android.content.ContentProvider并实现以下重要方法:        
    • query()    
    • insert()
    • update()
    • delete()
    • getType() 
     
     
     
     
        采取的各种步骤:
    • 计划数据库、URI列名称等,创建无数据类来定义所有这些元数据元素的常量
    • 扩展抽象类ContentProvider
    • 实现方法:query、insert、update、delete和getType
    • 在AndroidManifest.xml文件中注册提供程序
     
    getType(uri uri)这个方法何时被调用

        当我们在程序中需要启动例外的activity时,很多时候我们是使用的隱式調用,即我们不直接指定要跳转的Activity,而是为Intent提供一些相关的参数,让其自动去和AndroidManifest.xml中已有的Activity去匹配,而IntentFilter(Intent 过滤器)在xml中有三個主要的参数:action,categary,data。
        我们通过Intent的构造函数或者Intent提供的方法可以指定这个三个参数,如方法有:
                intent.setAction(action);
                intent.setData(data);
                intent.addCategory(category);
        等,比如在记事本程序中有:
             <intent-filter android:label="@string/resolve_edit">
                    <action android:name="android.intent.action.VIEW" />
                    <action android:name="android.intent.action.EDIT" />
                    <action android:name="com.android.notepad.action.EDIT_NOTE" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
             </intent-filter>
        我们很容易看出action和category是很容易匹配的,而我们传的Uri的数据怎么匹配呢,这时系统会去调用你定义的ContentProvider中的getType,取得相关的返回值來和上面的data串进行匹配,当然getType的返回结果你是需要自己去定义的。
        但在程序中你也可以自己知道data的类型,就直接匹配了:intent.setType(type);
     
        
  • 相关阅读:
    C++ 类 析构函数
    Oracle 11g rac 添加新节点测试
    rac添加新节点的步骤与方法
    X 传输表空间方法留待整理
    1913: 成绩评估
    1066: 输入n个数和输出调整后的n个数
    1005: 渊子赛马
    Problem Y: 哪一天,哪一秒?
    Problem T: 结构体学生信息排序
    Problem O: 国家排序
  • 原文地址:https://www.cnblogs.com/adm1989/p/2781351.html
Copyright © 2011-2022 走看看