一、URI与Uri

大家可能经常会看到在开发时,怎么有的时候是URI,有的时候是Uri,这是怎么回事?

名称如此相像的两个类是有什么区别和联系?

  • 1.所属的包不同。URI位置在java.net.URI,显然是Java提供的一个类。而Uri位置在android.net.Uri,是由Android提供的一个类。所以初步可以判断,Uri是URI的“扩展”以适应Android系统的需要。
  • 2.作用的不同。URI类代表了一个URI(这个URI不是类,而是其本来的意义:通用资源标志符——Uniform Resource Identifier)实例。Uri类是一个不可改变的URI引用,包括一个URI和一些碎片,URI跟在“#”后面。建立并且转换URI引用。而且Uri类对无效的行为不敏感,对于无效的输入没有定义相应的行为,如果没有另外制定,它将返回垃圾而不是抛出一个异常。

看不懂?没关系,知道这个就可以了:Uri是Android开发的,扩展了JAVA中URI的一些功能来特定的适用于Android开发,所以大家在开发时,只使用Android 提供的Uri即可;

二、Uri结构

(1)、基本形式:

  1. [scheme:]scheme-specific-part[#fragment]  

      这里分为三部分:

      scheme、scheme-specific-part、fragment

(2)、进一步划分:

如果进一步划分的话是这样子的

  1. [scheme:][//authority][path][?query][#fragment]  

其中有下面几个规则:

  • path可以有多个,每个用/连接,比如 scheme://authority/path1/path2/path3?query#fragment
  • query参数可以带有对应的值,也可以不带,如果带对应的值用=表示,如:scheme://authority/path1/path2/path3?id = 1#fragment,这里有一个参数id,它的值是1
  • query参数可以有多个,每个用&连接 scheme://authority/path1/path2/path3?id = 1&name = mingming&old#fragment 这里有三个参数: 参数1:id,其值是:1 参数2:name,其值是:mingming 参数3:old,没有对它赋值,所以它的值是null
  • 在android中,除了scheme、authority是必须要有的,其它的几个path、query、fragment,它们每一个可以选择性的要或不要,但顺序不能变,比如: 其中"path"可不要:scheme://authority?query#fragment 其中"path"和"query"可都不要:scheme://authority#fragment 其中"query"和"fragment"可都不要:scheme://authority/path "path","query","fragment"都不要:scheme://authority 等等……

(3)、终极划分

其中authority,又可以分为host:port的形式,即再次划分后是这样的:

  1. [scheme:][//host:port][path][?query][#fragment]  

所以这是划分最细的形式,其中host:port用冒号分隔,冒号前的是host,冒号后的port;

 三、示例

经过上面的讲解,想必大家的Uri的结构就有所了解了,下面我们就实例看看各部分的识别方式。

1. [scheme:]scheme-specific-part[#fragment]  
2. [scheme:][//authority][path][?query][#fragment]  
3. [scheme:][//host:port][path][?query][#fragment]

先列出这三种Uri形式,好让大家对比;

针对下面一个Uri字符串来匹配一下各个部分:

  1. http://www.baidu.com:8080/yourpath/imageview?value=10&path=55&id=8#break

  • scheme:匹对上面的两个Uri标准形式,很容易看出在:前的部分是scheme,所以这个Uri字符串的sheme是:http
  • scheme-specific-part:很容易看出scheme-specific-part是包含在scheme和fragment之间的部分,也就是包括第二部分的[//authority][path][?query]这几个小部分,所在这个Uri字符串的scheme-specific-part是://www.baidu.com:8080/yourpath/imageview?value=10&path=55&id=8 ,注意要带上//,因为除了[scheme:]和[#fragment]部分全部都是scheme-specific-part,当然包括最前面的//;
  • fragment:这个是更容易看出的,因为在最后用#分隔的部分就是fragment,所以这个Uri的fragment是:break 下面就是对scheme-specific-part进行拆分了; 在scheme-specific-part中,最前端的部分就是authority,?后面的部分是query,中间的部分就是path
  • authority:很容易看出scheme-specific-part最新端的部分是:www.baidu.com:8080
  • query:在scheme-specific-part中,?后的部分为:value=10&path=55&id=8
  • path:在**query:**在scheme-specific-part中,除了authority和query其余都是path的部分:/yourpath/imageview 又由于authority又一步可以划分为host:port形式,其中host:port用冒号分隔,冒号前的是host,冒号后的是port,所以:
  • host:www.baidu.com
  • port:8080

 四、代码提取

上面我们通过实例讲解了肉眼识别Uri更部分的方式,但在代码中又要怎样提取呢。下面就看看Uri中提取各部分的接口,依然以上面的Uri字符串为例:

  1. http://www.baidu.com:8080/yourpath/imageview?value=10&path=55&id=8#break

  • getScheme() :获取Uri中的scheme字符串部分,在这里即,http
  • getSchemeSpecificPart():获取Uri中的scheme-specific-part:部分,这里是://www.baidu.com:8080/yourpath/imageview?
  • getFragment():获取Uri中的Fragment部分,即break
  • getAuthority():获取Uri中Authority部分,即www.baidu.com:8080
  • getPath():获取Uri中path部分,即/yourpath/imageview
  • getQuery():获取Uri中的query部分,即value=10&path=55&id=8
  • getHost():获取Authority中的Host字符串,即www.baidu.com
  • getPost():获取Authority中的Port字符串,即8080

另外还有两个常用的:getPathSegments()、getQueryParameter(String key)

    • List< String> getPathSegments():上面我们的getPath()是把path部分整个获取下来:/yourpath/imageview,getPathSegments()的作用就是依次提取出Path的各个部分的字符串,以字符串数组的形式输出。以上面的Uri为例:
    1. String uri= "http://www.baidu.com:8080/yourpath/imageview?value=10&path=55&id=8#break";  
    2. Uri mUri = Uri.parse(uri);  
    3. List<String> path = mUri.getPathSegments();  
    4. for (String pathItem:path ){  
    5. "item===","pathItem:"+pathItem);  
    6. }  
     
    打出来的数据为:
    item===pathItem:yourpath
    item===pathItem:imageview
     
     
    • getQueryParameter(String key):在上面我们通过getQuery()获取整个query字段:value=10&path=55&id=8,getQueryParameter(String key)作用就是通过传进去path中某个Key的字符串,返回他对应的值。
    1. String mUriStr = "http://www.baidu.com:8080/yourpath/imageview?value=10&path=55&id=8#break";  
    2. mUri = Uri.parse(mUriStr);  
    3. "value")  的值为 10;
    4. mUri.getQueryParameter("id") 的值为 8;

    我相信了解了以上,就能应对开发了。