前言:依然没有前言……

相关博客:
1、《Uri详解之——Uri结构与代码提取》
2、《Uri详解之二——通过自定义Uri外部启动APP与Notification启动》

上几篇给大家讲了ContentProvider,里面有用到Uri,可能很多同学对Uri是什么,怎么来的,这些都不是很熟悉,今天就给大家具体讲讲Uri

一、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)、基本形式:
[html] view plain copy
[scheme:]scheme-specific-part[#fragment]
这里分为三部分:
scheme、scheme-specific-part、fragment
(2)、进一步划分:
如果进一步划分的话是这样子的

[html] view plain copy
[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的形式,即再次划分后是这样的:

[html] view plain copy
[scheme:][//host:port][path][?query][#fragment]
所以这是划分最细的形式,其中host:port用冒号分隔,冒号前的是host,冒号后的port;
三、示例
经过上面的讲解,想必大家的Uri的结构就有所了解了,下面我们就实例看看各部分的识别方式。

[html] view plain copy
[scheme:]scheme-specific-part[#fragment]
[scheme:][//authority][path][?query][#fragment]
[scheme:][//host:port][path][?query][#fragment]
先列出这三种Uri形式,好让大家对比;
针对下面一个Uri字符串来匹配一下各个部分:
[java] view plain copy
http://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4#harvic
scheme:匹对上面的两个Uri标准形式,很容易看出在:前的部分是scheme,所以这个Uri字符串的sheme是:http
scheme-specific-part:很容易看出scheme-specific-part是包含在scheme和fragment之间的部分,也就是包括第二部分的[//authority][path][?query]这几个小部分,所在这个Uri字符串的scheme-specific-part是://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4 ,注意要带上//,因为除了[scheme:]和[#fragment]部分全部都是scheme-specific-part,当然包括最前面的//;
fragment:这个是更容易看出的,因为在最后用#分隔的部分就是fragment,所以这个Uri的fragment是:harvic
下面就是对scheme-specific-part进行拆分了;
在scheme-specific-part中,最前端的部分就是authority,?后面的部分是query,中间的部分就是path
authority:很容易看出scheme-specific-part最新端的部分是:www.java2s.com:8080
query:在scheme-specific-part中,?后的部分为:stove=10&path=32&id=4
path:在**query:**在scheme-specific-part中,除了authority和query其余都是path的部分:/yourpath/fileName.htm
又由于authority又一步可以划分为host:port形式,其中host:port用冒号分隔,冒号前的是host,冒号后的是port,所以:
host:www.java2s.com
port:8080
四、代码提取
上面我们通过实例讲解了肉眼识别Uri更部分的方式,但在代码中又要怎样提取呢。下面就看看Uri中提取各部分的接口,依然以上面的Uri字符串为例:

[java] view plain copy
http://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4#harvic
getScheme() :获取Uri中的scheme字符串部分,在这里即,http
getSchemeSpecificPart():获取Uri中的scheme-specific-part:部分,这里是://www.java2s.com:8080/yourpath/fileName.htm?
getFragment():获取Uri中的Fragment部分,即harvic
getAuthority():获取Uri中Authority部分,即www.java2s.com:8080
getPath():获取Uri中path部分,即/yourpath/fileName.htm
getQuery():获取Uri中的query部分,即stove=10&path=32&id=4
getHost():获取Authority中的Host字符串,即www.java2s.com
getPost():获取Authority中的Port字符串,即8080
另外还有两个常用的:getPathSegments()、getQueryParameter(String key)
List< String> getPathSegments():上面我们的getPath()是把path部分整个获取下来:/yourpath/fileName.htm,getPathSegments()的作用就是依次提取出Path的各个部分的字符串,以字符串数组的形式输出。以上面的Uri为例:
[java] view plain copy
String mUriStr = "http://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4#harvic";
Uri mUri = Uri.parse(mUriStr);
List<String> pathSegList = mUri.getPathSegments();
for (String pathItem:pathSegList){
Log.d("qijian","pathSegItem:"+pathItem);
}
打出来的列表为:

getQueryParameter(String key):在上面我们通过getQuery()获取整个query字段:stove=10&path=32&id=4,getQueryParameter(String key)作用就是通过传进去path中某个Key的字符串,返回他对应的值。
[java] view plain copy
String mUriStr = "http://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id#harvic";
mUri = Uri.parse(mUriStr);
Log.d(tag,"getQueryParameter(\"stove\"):"+mUri.getQueryParameter("stove"));
Log.d(tag,"getQueryParameter(\"id\"):"+mUri.getQueryParameter("id"));
注意注意,我稍微更改了下字符串,把query中id的值去掉了!!!!!然后看看通过getQueryParameter("id")获取它的值会得到什么!
结果如下:

可以看到,在path中,即使针对某一个KEY不对它赋值是允许的,但在利用getQueryParameter()获取该KEY对应的值时,获取到的是null;

五、扩展
1、 绝对URI和相对URI
绝对URI:以scheme组件起始的完整格式,如http://fsjohnhuang.cnblogs.com。表示以对标识出现的环境无依赖的方式引用资源。
相对URI:不以scheme组件起始的非完整格式,如fsjohnhuang.cnblogs.com。表示以对依赖标识出现的环境有依赖的方式引用资源。

2、不透明URI和分层URI
不透明URI:scheme-specific-part组件不是以正斜杠(/)起始的,如mailto:fsjohnhuang@xxx.com。由于不透明URI无需进行分解操作,因此不会对scheme-specific-part组件进行有效性验证。
分层URI:scheme-specific-part组件是以正斜杠(/)起始的,如http://fsjohnhuang.com。

更多有关本扩展和标准化(Normalization)、解析化(Resolution)、相对化(Relativization)的知识参见:《Java魔法堂:URI、URL(含URL Protocol Handler)和URN》

下面源码中演示了各个提取函数的用法及结果;

如果本文有帮到你,记得关注哦

源码下载地址:http://download.csdn.net/detail/harvic880925/8539679

请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/44679239 谢谢

如果你喜欢我的文章,那么你将会更喜欢我的微信公众号,将定期推送博主最新文章与收集干货分享给大家(一周一次)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/harvic880925/article/details/44679239

(转)Uri详解之——Uri结构与代码提取的更多相关文章

  1. Uri详解之——Uri结构与代码提取

    目录(?)[+] 前言:依然没有前言…… 相关博客:1.<Uri详解之——Uri结构与代码提取>2.<Uri详解之二——通过自定义Uri外部启动APP与Notification启动& ...

  2. hadoop hdfs uri详解

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

  3. DDR3内存详解,存储器结构+时序+初始化过程

    DDR3内存详解,存储器结构+时序+初始化过程 标签: DDR3存储器博客 2017-06-17 16:10 1943人阅读 评论(1) 收藏 举报  分类: 硬件开发基础(2)  转自:http:/ ...

  4. 【转】IOS AutoLayout详解(三)用代码实现(附Demo下载)

    转载自:blog.csdn.net/hello_hwc IOS SDK详解 前言: 在开发的过程中,有时候创建View没办法通过Storyboard来进行,又需要AutoLayout,这时候用代码创建 ...

  5. Android ContentProvider和Uri详解 (绝对全面)

        ContentProvider的基本概念 : 1.ContentProvider为存储和读取数据提供了统一的接口 2.使用ContentProvider,应用程序可以实现数据共享 3.andr ...

  6. Android ContentProvider和Uri详解

    一.使用ContentProvider(内容提供者)共享数据 ContentProvider在android中的作用是对外共享数据, 也就是说你可以通过ContentProvider把应用中的数据共享 ...

  7. Java虚拟机详解02----JVM内存结构

    主要内容如下: JVM启动流程 JVM基本结构 内存模型 编译和解释运行的概念 一.JVM启动流程: JVM启动时,是由java命令/javaw命令来启动的. 二.JVM基本结构: JVM基本结构图: ...

  8. Java虚拟机详解----JVM内存结构

    http://www.cnblogs.com/smyhvae/p/4748392.htm 主要内容如下: JVM启动流程 JVM基本结构 内存模型 编译和解释运行的概念 一.JVM启动流程: JVM启 ...

  9. http协议报头详解HTTP协议结构

    http协议 请求报文和响应报文都是由以下4部分组成 1.请求行 2.请求头 3.空行 4.消息主体 下图为http请求的报文结构 下图为http响应报文结构 请求行 格式为: Method Requ ...

随机推荐

  1. 敏捷软件开发:原则、模式与实践——第13章 写给C#程序员的UML概述

    第13章 写给C#程序员的UML概述 UML包含3类主要的图示.静态图(static diagram)描述了类.对象.数据结构以及它们之间的关系,藉此表现出了软件元素间那些不变的逻辑结构.动态图(dy ...

  2. mybatis 输入、输出映射

    一.输入映射 mapper.xml的参数只有一个.可以传参数,基本简单类型,hashmap和javabean (一).Javabean的方法. 需求:通过小说名和作者模糊找书. 1.定义Javabea ...

  3. CLR via C# 读书笔记-27.计算限制的异步操作(上篇)

    前言 学习这件事情是一个习惯,不能停...另外这篇已经看过两个月过去,但觉得有些事情不总结跟没做没啥区别,遂记下此文 1.CLR线程池基础 2.ThreadPool的简单使用练习 3.执行上下文 4. ...

  4. ES6—— 变量的结构赋值

    变量的结构赋值.基本概念: 本质上就是一中匹配模式,只要等号两边的模式相同,那么左边的变量就可以被赋予对应的值: 1.数组的结构赋值. 2.对象的结构赋值. 3.基本类型的结构赋值. let [a,b ...

  5. Win7系统下搭建FTP

    一.创建FTP站点  1.打开:控制面板---系统和安全---管理工具---Internet 信息服务 2. 建站:右键点击网站---添加FTP站点 3. 输入FTP 站点名称---选择你的 FTP ...

  6. 《Beginning Java 7》 - 7 - abstract class 抽象类 和 interface 接口

    1. 抽象类: 为什么用抽象类: 一些 generic 的类本身并没有现实意义,所以不需要被实例化.比如动物,自然界没有动物这个物种,但却有无数的继承自动物的物种,那么动物本身可以是一个抽象类. 抽象 ...

  7. fatal: unable to auto-detect email address (got 'tim@newton.(none)')的解决方法

    问题描述: 使用git commit -m "wrote a readme file",就遇到了这个问题** Please tell me who you are. Run git ...

  8. linux命令之网络管理命令(下)

    1.wget:命令行下载工具 该命令用于从网络上下载资料,可以直接从网络上下载自己所需要的资料. 参数 说明 -O(常用) 指定保存的文件名后下载文件 --limit-rate(常用) 限速下载 -c ...

  9. Servlet实现禁用cookie重写URL获取session

    前言 一个女人让他的程序员丈夫去商店买东西:你去附近的商店买些鸡蛋,如果有香蕉的话,买8个回来,这个丈夫买了8个鸡蛋回来,他的妻子大吃一惊:你为什么买了8个鸡蛋?! 程序员丈夫回答:因为他们有香蕉. ...

  10. ArchLinux中证书错误解决方案

    ca-certificates 更新 x509: failed to load system roots and no roots provided. curl error: Problem with ...