Uri詳解之——Uri結構與代碼提取

目錄(?)[+]html

前言:依然沒有前言……前端


相關博客:
一、《Uri詳解之——Uri結構與代碼提取》
二、《Uri詳解之二——經過自定義Uri外部啓動APP與Notification啓動》
java

 

上幾篇給你們講了ContentProvider,裏面有用到Uri,可能不少同窗對Uri是什麼,怎麼來的,這些都不是很熟悉,今天就給你們具體講講Uriandroid

1、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便可;
微信開發

2、Uri結構

(1)、基本形式:

[html] view plain copy
  1. [scheme:]scheme-specific-part[#fragment]  

這裏分爲三部分:
scheme、scheme-specific-part、fragmentide

(2)、進一步劃分:

若是進一步劃分的話是這樣子的函數

[html] view plain copy
  1. [scheme:][//authority][path][?query][#fragment]  

其中有下面幾個規則:spa

  • 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
  1. [scheme:][//host:port][path][?query][#fragment]  

因此這是劃分最細的形式,其中host:port用冒號分隔,冒號前的是host,冒號後的port;

3、示例

通過上面的講解,想必你們的Uri的結構就有所瞭解了,下面咱們就實例看看各部分的識別方式。

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

先列出這三種Uri形式,好讓你們對比;
針對下面一個Uri字符串來匹配一下各個部分:

[java] view plain copy
  1. 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

4、代碼提取

上面咱們經過實例講解了肉眼識別Uri更部分的方式,但在代碼中又要怎樣提取呢。下面就看看Uri中提取各部分的接口,依然以上面的Uri字符串爲例:

[java] view plain copy
  1. 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
  1. String mUriStr = "http://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4#harvic";  
  2. Uri mUri = Uri.parse(mUriStr);  
  3. List<String> pathSegList = mUri.getPathSegments();  
  4. for (String pathItem:pathSegList){  
  5.     Log.d("qijian","pathSegItem:"+pathItem);  
  6. }  

打出來的列表爲:

  • getQueryParameter(String key):在上面咱們經過getQuery()獲取整個query字段:stove=10&path=32&id=4,getQueryParameter(String key)做用就是經過傳進去path中某個Key的字符串,返回他對應的值。
[java] view plain copy
  1. String mUriStr = "http://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id#harvic";  
  2. mUri = Uri.parse(mUriStr);  
  3. Log.d(tag,"getQueryParameter(\"stove\"):"+mUri.getQueryParameter("stove"));  
  4. Log.d(tag,"getQueryParameter(\"id\"):"+mUri.getQueryParameter("id"));  

注意注意,我稍微更改了下字符串,把query中id的值去掉了!!!!!而後看看經過getQueryParameter("id")獲取它的值會獲得什麼!
結果以下:

能夠看到,在path中,即便針對某一個KEY不對它賦值是容許的,但在利用getQueryParameter()獲取該KEY對應的值時,獲取到的是null;

5、擴展

一、 絕對URI和相對URI

絕對URI:以scheme組件起始的完整格式,如http://fsjohnhuang.cnblogs.com。表示以對標識出現的環境無依賴的方式引用資源。
相對URI:不以scheme組件起始的非完整格式,如fsjohnhuang.cnblogs.com。表示以對依賴標識出現的環境有依賴的方式引用資源。

二、不透明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 謝謝

若是你喜歡個人文章,那麼你將會更喜歡個人微信公衆號,將按期推送博主最新文章與收集乾貨分享給你們(一週一次)

相關文章
相關標籤/搜索