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、结构形式

结构由简至繁以此可划分以下三种格式:

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

2、主要规则

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
等等……


三、示例

方便对照查看再写一遍结构

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

示例:

http://www.baidu.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4#harvic 

scheme:http
scheme-specific-part://www.baidu.com:8080/yourpath/fileName.htm?tove=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.baidu.com:8080
query:在scheme-specific-part中,?后的部分为:stove=10&path=32&id=4
path:在scheme-specific-part中,除了authority和query其余都是path的部分:/yourpath/fileName.htm

authority又一步可以划分为host:port形式,其中host:port用冒号分隔,冒号前的是host,冒号后的是port,所以:
host:www.baidu.com
port:8080


**

四、代码提取

方便对照查看再写一遍结构

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

**
示例:

http://www.baidu.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4#harvic 

getScheme():获取Uri中的scheme字符串部分,在这里即,http

getSchemeSpecificPart():
获取Uri中的scheme-specific-part部分,这里是://www.baidu.com:8080/yourpath/fileName.htm?

getFragment():获取Uri中的Fragment部分,即harvic

getAuthority():获取Uri中Authority部分,即www.baidu.com:8080

getPath():获取Uri中path部分,即/yourpath/fileName.htm

getQuery():获取Uri中的query部分,即stove=10&path=32&id=4

getHost():获取Authority中的Host字符串,即www.baidu.com

getPost():获取Authority中的Port字符串,即8080

List< String> getPathSegments():上面我们的getPath()是把path部分整个获取下来:/yourpath/fileName.htm,getPathSegments()的作用就是依次提取出Path的各个部分的字符串,以字符串数组的形式输出。以上面的Uri为例:

String mUriStr = "http://www.baidu.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("TAG","pathSegItem:"+pathItem);  
}  

getQueryParameter(String key):在上面我们通过getQuery()获取整个query字段:stove=10&path=32&id=4,getQueryParameter(String key)作用就是通过传进去path中某个Key的字符串,返回他对应的值。

String mUriStr = "http://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id#harvic";  
mUri = Uri.parse(mUriStr);  
Log.d("TAG","(stove):"+mUri.getQueryParameter("stove"));  
Log.d("TAG","(id):"+mUri.getQueryParameter("id"));  

注意:在path中,即使针对某一个KEY不对它赋值是允许的,但在利用getQueryParameter()获取该KEY对应的值时,获取到的是null,所以id的值为null(未赋值)


**

五、扩展

**
1、 绝对URI和相对URI

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

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

URI、URL、URN的区别
互联网之父Tim Berners-Lee引入用于识别、定位和命名互联网资源的途径——URI、URL和URN。三者彼此关联,URI的范畴位于体系的顶层,URL和URN的范畴位于体系的底层。

         ![这里写图片描述](https://img-blog.csdn.net/20160811143413601)

URI:Uniform Resource Identifier,统一资源标识符;
URL:Uniform Resource Locator,统一资源定位符;
URN:Uniform Resource Name,统一资源名称。

上图可知URL和URN必须是URI,但URI却不一定是URL或URN。
URI仅仅是资源名称而已,知道了URI最多就是知道有这么一个名称的资源罢了,至于如何获取(与资源作交互)则是毫无头绪(不能定位或读取/写入资源),而这个资源名称是永久持有还是暂时持有也没有相应的规定,于是就有了URL和URN两个子集。


更多有关本扩展和标准化(Normalization)、解析化(Resolution)、相对化(Relativization)的知识参见此链接博客:

文章部分摘取总结自http://blog.csdn.net/harvic880925/article/details/44679239,万分感谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值