轉(zhuǎn)載 :http://blog.csdn.net/harvic880925/article/details/44679239
上幾篇給大家講了ContentProvider给赞,里面有用到Uri,可能很多同學(xué)對(duì)Uri是什么历筝,怎么來(lái)的,這些都不是很熟悉创泄,今天就給大家具體講講Uri
大家可能經(jīng)常會(huì)看到在開(kāi)發(fā)時(shí),怎么有的時(shí)候是URI眨唬,有的時(shí)候是Uri,這是怎么回事好乐?
名稱(chēng)如此相像的兩個(gè)類(lèi)是有什么區(qū)別和聯(lián)系匾竿?
1.所屬的包不同。URI位置在java.net.URI,顯然是Java提供的一個(gè)類(lèi)蔚万。而Uri位置在android.net.Uri,是由Android提供的一個(gè)類(lèi)岭妖。所以初步可以判斷,Uri是URI的“擴(kuò)展”以適應(yīng)Android系統(tǒng)的需要笛坦。
2.作用的不同区转。URI類(lèi)代表了一個(gè)URI(這個(gè)URI不是類(lèi)苔巨,而是其本來(lái)的意義:通用資源標(biāo)志符——Uniform Resource Identifier)實(shí)例版扩。Uri類(lèi)是一個(gè)不可改變的URI引用,包括一個(gè)URI和一些碎片侄泽,URI跟在“#”后面礁芦。建立并且轉(zhuǎn)換URI引用。而且Uri類(lèi)對(duì)無(wú)效的行為不敏感悼尾,對(duì)于無(wú)效的輸入沒(méi)有定義相應(yīng)的行為柿扣,如果沒(méi)有另外制定,它將返回垃圾而不是拋出一個(gè)異常闺魏。
看不懂未状?沒(méi)關(guān)系,知道這個(gè)就可以了:Uri是Android開(kāi)發(fā)的析桥,擴(kuò)展了Java中URI的一些功能來(lái)特定的適用于android開(kāi)發(fā)司草,所以大家在開(kāi)發(fā)時(shí)艰垂,只使用Android 提供的Uri即可;
[html]view plaincopy
[scheme:]scheme-specific-part[#fragment]
這里分為三部分:
scheme、scheme-specific-part搔课、fragment
如果進(jìn)一步劃分的話是這樣子的
[html]view plaincopy
[scheme:][//authority][path][?query][#fragment]
其中有下面幾個(gè)規(guī)則:
path可以有多個(gè),每個(gè)用/連接爬泥,比如
scheme://authority/path1/path2/path3?query#fragment
query參數(shù)可以帶有對(duì)應(yīng)的值柬讨,也可以不帶,如果帶對(duì)應(yīng)的值用=表示急灭,如:
scheme://authority/path1/path2/path3?id = 1#fragment姐浮,這里有一個(gè)參數(shù)id,它的值是1
query參數(shù)可以有多個(gè)葬馋,每個(gè)用&連接
scheme://authority/path1/path2/path3?id = 1&name = mingming&old#fragment
這里有三個(gè)參數(shù):
參數(shù)1:id卖鲤,其值是:1
參數(shù)2:name,其值是:mingming
參數(shù)3:old畴嘶,沒(méi)有對(duì)它賦值蛋逾,所以它的值是null
在android中,除了scheme窗悯、authority是必須要有的区匣,其它的幾個(gè)path、query蒋院、fragment亏钩,它們每一個(gè)可以選擇性的要或不要,但順序不能變欺旧,比如:
其中"path"可不要:scheme://authority?query#fragment
其中"path"和"query"可都不要:scheme://authority#fragment
其中"query"和"fragment"可都不要:scheme://authority/path
"path","query","fragment"都不要:scheme://authority
等等……
其中authority,又可以分為host:port的形式,即再次劃分后是這樣的:
[html]view plaincopy
[scheme:][//host:port][path][?query][#fragment]
所以這是劃分最細(xì)的形式辞友,其中host:port用冒號(hào)分隔栅哀,冒號(hào)前的是host,冒號(hào)后的port;
經(jīng)過(guò)上面的講解留拾,想必大家的Uri的結(jié)構(gòu)就有所了解了,下面我們就實(shí)例看看各部分的識(shí)別方式鲫尊。
[html]view plaincopy
[scheme:]scheme-specific-part[#fragment]
[scheme:][//authority][path][?query][#fragment]
[scheme:][//host:port][path][?query][#fragment]
先列出這三種Uri形式痴柔,好讓大家對(duì)比;
針對(duì)下面一個(gè)Uri字符串來(lái)匹配一下各個(gè)部分:
[java]view plaincopy
http://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4#harvic
scheme:匹對(duì)上面的兩個(gè)Uri標(biāo)準(zhǔn)形式疫向,很容易看出在:前的部分是scheme咳蔚,所以這個(gè)Uri字符串的sheme是:http
scheme-specific-part:很容易看出scheme-specific-part是包含在scheme和fragment之間的部分扛施,也就是包括第二部分的[//authority][path][?query]這幾個(gè)小部分,所在這個(gè)Uri字符串的scheme-specific-part是://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4 屹篓,注意要帶上//疙渣,因?yàn)槌薣scheme:]和[#fragment]部分全部都是scheme-specific-part,當(dāng)然包括最前面的//堆巧;
fragment:這個(gè)是更容易看出的妄荔,因?yàn)樵谧詈笥?分隔的部分就是fragment,所以這個(gè)Uri的fragment是:harvic
下面就是對(duì)scheme-specific-part進(jìn)行拆分了谍肤;
在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用冒號(hào)分隔俩滥,冒號(hào)前的是host嘉蕾,冒號(hào)后的是port,所以:
host:www.java2s.com
port:8080
上面我們通過(guò)實(shí)例講解了肉眼識(shí)別Uri更部分的方式错忱,但在代碼中又要怎樣提取呢。下面就看看Uri中提取各部分的接口挂据,依然以上面的Uri字符串為例:
[java]view plaincopy
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
另外還有兩個(gè)常用的:getPathSegments()、getQueryParameter(String key)
List< String> getPathSegments():上面我們的getPath()是把path部分整個(gè)獲取下來(lái):/yourpath/fileName.htm吟宦,getPathSegments()的作用就是依次提取出Path的各個(gè)部分的字符串篮洁,以字符串?dāng)?shù)組的形式輸出。以上面的Uri為例:
[java]view plaincopy
String?mUriStr?="http://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4#harvic";
Uri?mUri?=?Uri.parse(mUriStr);
List?pathSegList?=?mUri.getPathSegments();
for(String?pathItem:pathSegList){
Log.d("qijian","pathSegItem:"+pathItem);
}
打出來(lái)的列表為:
getQueryParameter(String key):在上面我們通過(guò)getQuery()獲取整個(gè)query字段:stove=10&path=32&id=4殃姓,getQueryParameter(String key)作用就是通過(guò)傳進(jìn)去path中某個(gè)Key的字符串袁波,返回他對(duì)應(yīng)的值瓦阐。
[java]view plaincopy
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的值去掉了K!<霞铡4辽薄!然后看看通過(guò)getQueryParameter("id")獲取它的值會(huì)得到什么夭苗!
結(jié)果如下:
可以看到信卡,在path中,即使針對(duì)某一個(gè)KEY不對(duì)它賦值是允許的题造,但在利用getQueryParameter()獲取該KEY對(duì)應(yīng)的值時(shí)傍菇,獲取到的是null;
絕對(duì)URI:以scheme組件起始的完整格式丢习,如http://fsjohnhuang.cnblogs.com。表示以對(duì)標(biāo)識(shí)出現(xiàn)的環(huán)境無(wú)依賴(lài)的方式引用資源淮悼。
相對(duì)URI:不以scheme組件起始的非完整格式泛领,如fsjohnhuang.cnblogs.com。表示以對(duì)依賴(lài)標(biāo)識(shí)出現(xiàn)的環(huán)境有依賴(lài)的方式引用資源敛惊。
不透明URI:scheme-specific-part組件不是以正斜杠(/)起始的,如mailto:fsjohnhuang@xxx.com瞧挤。由于不透明URI無(wú)需進(jìn)行分解操作锡宋,因此不會(huì)對(duì)scheme-specific-part組件進(jìn)行有效性驗(yàn)證。
分層URI:scheme-specific-part組件是以正斜杠(/)起始的特恬,如http://fsjohnhuang.com执俩。