1. 程式人生 > >Uri詳解之——Uri結構與程式碼提取

Uri詳解之——Uri結構與程式碼提取

前言:依然沒有前言……

上幾篇給大家講了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)、基本形式:

[scheme:]scheme-specific-part[#fragment]
這裡分為三部分:
scheme、scheme-specific-part、fragment

(2)、進一步劃分:

如果進一步劃分的話是這樣子的

[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的形式,即再次劃分後是這樣的:

[scheme:][//host:port][path][?query][#fragment]
所以這是劃分最細的形式,其中host:port用冒號分隔,冒號前的是host,冒號後的port;

三、示例

經過上面的講解,想必大家的Uri的結構就有所瞭解了,下面我們就例項看看各部分的識別方式。

[scheme:]scheme-specific-part[#fragment]
[scheme:][//authority][path][?query][#fragment]
[scheme:][//host:port][path][?query][#fragment]
先列出這三種Uri形式,好讓大家對比;
針對下面一個Uri字串來匹配一下各個部分:
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字串為例:

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為例:
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的字串,返回他對應的值。
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:[email protected]。由於不透明URI無需進行分解操作,因此不會對scheme-specific-part元件進行有效性驗證。
分層URI:scheme-specific-part元件是以正斜槓(/)起始的,如http://fsjohnhuang.com。

更多有關本擴充套件和標準化(Normalization)、解析化(Resolution)、相對化(Relativization)的知識參見:《Java魔法堂:URI、URL(含URL Protocol Handler)和URN》

下面原始碼中演示了各個提取函式的用法及結果;

如果本文有幫到你,記得關注哦

如果你喜歡我的文章,那麼你將會更喜歡我的微信公眾號,將定期推送博主最新文章與收集乾貨分享給大家(一週一次)


相關推薦

Uri——Uri結構程式碼提取

前言:依然沒有前言……上幾篇給大家講了ContentProvider,裡面有用到Uri,可能很多同學對Uri是什麼,怎麼來的,這些都不是很熟悉,今天就給大傢俱體講講Uri一、URI與Uri大家可能經常會看到在開發時,怎麼有的時候是URI,有的時候是Uri,這是怎麼回事?名稱如

Linux核心中RAID5原始碼基本架構資料結構

Linux核心中RAID5的基本架構與資料結構解析 眾所周知,早年的計算機儲存資料現在磁帶上,然後發展到了磁碟,然而僅僅是單個盤,速度和效能都不是很好,然是,要知道人類的聰明才智是連ET都想不到的,前輩們不斷的猜想,實驗來提高計算機的效能,於是磁碟陣列問世

#51CTO學院四周年#JWT的結構應用

json 升職啦 技能 1. JWT是什麽?JWT,全稱JSON WEB TOKEN, 是WEB客戶端與服務器之間相互進行安全通信的規範。通信雙方的對象本身通過JSON傳遞數據是不安全的,但是由於有了數字簽名的存在,這些信息變的可信的。2. JWT特點簡潔(Compact): 可以通過URL,PO

網路學習基礎 計算機網路Internet

網路學習之路之基礎詳解① 計算機網路概述之整體瞭解 首先我們理清總體思路,來看看計算機網路概述整體的框圖 從上圖我們可以大致瞭解到計算機網路包含內容,下面我們來對各方面進行詳細學習: (1)計算機網路VS Internet ①基礎理解: 計算機網路:一些互相連線的,自治的計算機的

Android入門——Fragment基本概念用法(一)

引言 Android在3.0中引入了Fragments的概念,其目的是用在大螢幕裝置上–例如平板電腦上,支援更加動態和靈活的UI設計。平板電腦的螢幕要比手機的大得多,有更多的空間來放更多的UI元件,並且這些元件之間會產生更多的互動。Fragment允許這樣的一

Nginx rewrite URI重寫

more conf/fastcgi.conf 相關的內建變數 rewrite功能     使用nginx提供的全域性變數或自己設定的變數,結合正則表示式和標誌位實現url重寫以及重定向。rewrite只能放在server{}, location{}, if{}中,並且只能對域名後

Nginx深入模組化體系結構

在開始嘮叨之前,先簡單介紹下配置系統,因為之後的東東會與這個有一定的關係。 一、配置系統     Nginx的配置系統由一個主配置檔案和一些輔助配置檔案構成,這些配置檔案預設在/etc/nginx/目錄下。     輔助配置檔案只在某些特定情況下才

openTSDB原始碼Deferred類程式碼簡單示例1

openTSDB原始碼詳解之Deferred類程式碼簡單示例1 1.示例1 1.1 程式碼 /** * simplest with only 1 defer * 最簡單的,僅僅只有1個defer */ public static void test

深入淺出Mybatis原始碼系列(三)---配置propertiesenvironments(mybatis原始碼篇)

上篇文章《深入淺出Mybatis原始碼系列(二)---配置簡介(mybatis原始碼篇)》我們通過對mybatis原始碼的簡單分析,可看出,在mybatis配置檔案中,在configuration根節點下面,可配置properties、typeAliases、plugins、

大資料hdfs三:put許可權剖析常用命令

–無論是對於hdfs的讀和寫,對於使用者來說都是無感知的、透明的操作,使用者並不關心資料如何讀出來如何寫進去的,只要返回一個結果告訴使用者資料讀出來了或寫進去了,至於怎麼讀怎麼寫,使用者並不關心 補充: 讀:hdfs dfs -ls / = hdfs dfs

JDBCmySQL資料庫的連線和基本操作一

JDBC詳解 JDBC詳解 一 JDBC基本操作 MySQL的JDBC驅動包: mysql-connector-java-5.1.3

golang echo 程式碼 log 篇

echo 自帶的 log 庫 log 結構 echo 框架的 log 結構體是 echo.Echo 結構體的一個屬性 type Echo struct { ... Logger Logger } 而 logger 是個

資料結構排序系列九 桶排序

基本思想:假定輸入是由一個隨機過程產生的[0, M)區間上均勻分佈的實數。將區間[0, M)劃分為n個大小相等的子區間(桶),將n個輸入元素分配到這些桶中,對桶中元素進行排序,然後依次連線桶輸入0 ≤A[1..n] <M輔助陣列B[0..n-1]是一指標陣列,指向桶(

hbase 命令namespacetable

1、/hbase shell命令 從檔案中讀取shell命令 /hbase shell ./sample_commands.txt sample_commands檔案中寫入命令,一行一個。 2、status 檢視伺服器狀態資訊(伺服器數量,死掉的

【OpenCV3影象處理】Mat類 元素的獲取賦值 ( 對比.at<>()函式 和 .ptr<>()函式)

Mat中畫素的獲取與賦值 計算機視覺中,影象的讀取是影象處理的基礎,影象就是一系列畫素值,OpenCV使用資料結構cv::Mat來儲存影象。cv::Mat是一個矩陣類,矩陣中每一個元素都代表一個畫素,對於灰度影象,畫素用8位無符號數,0表示黑色,255表示白色。對於彩色

iOS 開發 Object-C和JavaScript互動OCJS互動在WKWebView中使用

1.OC與JS互動在UIWebView中使用 2. WKWebView的使用詳解 3.OC與JS互動在WKWebView中使用 // // ViewController.m // oc與js互動WKWebView // // Cr

演算法導論學習--紅黑樹刪除(含完整紅黑樹程式碼)

前面我們討論了紅黑樹的插入的實現,基本思想是分類討論;然後分情況討論以後我們發現插入操作調整函式只需要處理三種情況,並不是太複雜。但是刪除操作會更復雜一點,因為二叉搜尋樹的刪除操作本身就分成了多種情況,這樣在執行刪除操作後要處理的情況會更多;下面對於刪除操作我們

C++繼承二——派生類成員函式(函式隱藏、建構函式相容覆蓋規則)

  在這一篇文章開始之前,我先解決一個問題。   在上一篇C++繼承詳解之一——初探繼承中,我提到了在派生類中可以定義一個與基類成員函式同名的函式,這樣派生類中的函式就會覆蓋掉基類的成員函式。   在譚浩強的C++程式設計這本書第十一章,351頁最下面有這麼

FastDFS的配置、部署API使用解讀(4)FastDFS配置Client配置

一種方式是通過呼叫ClientGlobal類的初始化方法對配置檔案進行載入,另一種是通過呼叫API逐一設定配置引數。後一種方式對於使用Zookeeper等載入屬性的方式很方便。 1. 載入配置檔案: String configFileName = "conf/dfs-c

Python---round函式四捨五入python2python3版本間區別

round()方法返回 數值 的小數點四捨五入到n個數字。 語法 以下是round()方法的語法: round( x [, n] ) 引數     x --這是一個數值,表示需要格式化的數值     n --這也是一個數值,表示小數點後保留多少位 返回值 該方法返回 數值x 的小數點四捨五入