android 中的Uri
2015-08-14 19:40
501 查看
文章出处:http://blog.csdn.net/shift_wwx/article/details/47663373
请转载的朋友标明出处~~
前言:关于Uri网上相关的例子还是很多的,但是结合source code来讲解的很少,个人还是习惯性根据source code 总结一下。
总结版本基于4.4
一、source code(frameworks/base/core/java/android/net/Uri.java)
Uri就是Android系统为了特殊需要,而制定的一种拥有特殊格式的一种数据模式。
从注释看:
1)scheme:访问资源的命名机制,通过这个可以获悉Uri 的具体资源存在形式,如http、content、file、market等
2)authority:存放资源的主机名,例如Provider 里面会对资源进行操作、存放,这个时候Provider就需要指出authority。
对于Provider 具体可以看一下:《Android基础总结之八:ContentProvider详解》
authority 应该是scheme:// 之后到第一次出现 ‘/’ 或‘?’ 或‘#’之间的string
3)path:authority之后第一个 ‘/’ 开始到 ‘?’ 或 ‘#’ 之前的string(包含'/')
4)query:'?' 号之后 '#' 号之前的string
经常看到的Uri形式有:
2、getScheme、getSchemeSpecificPart、getEncodedSchemeSpecificPart
1)getScheme:返回scheme,如果Uri是相对路径,那么就返回null
2)getSchemeSpecificPart :这里出现了ssp 概念,从这里可以将Uri 重新格式化为:
3)getEncodedSchemeSpecificPart:如果ssp里面有出现非A~Z、a~z、0~9、‘_’、‘-’、‘叹号’、‘点号’、‘~’、‘单引号’、‘(’、‘)’、‘星号’,都需要encode一把,有时候会看到%连接的一串,那都是encode。
详细的可以看一下source code:
3、isRelative、isAbsolute
isRelative:就是没有明确的scheme
isAbsolute:非isRelative
4、分层、不透明
通过注释可以大概理解两api 的意义:
如果ssp开头是 ‘/’,那么就是hierarchical,如果不是就是opaque。
当然,通过source code也能够确定的:
1)getHost:authority 中 ‘@’ 之后到 ‘:’ 之前的string
2)getPort:authority 中 ‘:’ 之后的 integer
6、Uri是个abstract类,好多函数是abstract的,肯定是有地方实现的。
那么Uri是abstract类,并不能实例化,应用的时候是怎么使用这些method,提供了两种方法:
总结:
根据之前的解释可以清楚知道Uri 的格式:
scheme:ssp#fragment
1)scheme 就是第一个 ‘:’ 之前的部分,没有的就返回null
2)ssp:authority + path + query
当然其中的部分可能不存在,反正ssp就是这三部分的统称
ssp 语法:[//aurhority][path][?query]
authority 也可能包含了userinfo + host + port
authority语法:[userinfo@]host[:port]
3)fragment:第一次出现 ‘#’ 之后的string
请转载的朋友标明出处~~
前言:关于Uri网上相关的例子还是很多的,但是结合source code来讲解的很少,个人还是习惯性根据source code 总结一下。
总结版本基于4.4
一、source code(frameworks/base/core/java/android/net/Uri.java)
public abstract class Uri implements Parcelable, Comparable<Uri> { private Uri() {} public abstract boolean isHierarchical(); public boolean isOpaque() { return !isHierarchical(); } public abstract boolean isRelative(); public boolean isAbsolute() { return !isRelative(); } public abstract String getScheme(); public abstract String getSchemeSpecificPart(); public abstract String getEncodedSchemeSpecificPart(); public abstract String getAuthority(); public abstract String getEncodedAuthority(); public abstract String getUserInfo(); public abstract String getEncodedUserInfo(); public abstract String getHost(); public abstract int getPort(); public abstract String getPath(); public abstract String getEncodedPath(); public abstract String getQuery(); public abstract String getEncodedQuery(); public abstract String getFragment(); public abstract String getEncodedFragment(); public abstract List<String> getPathSegments(); public abstract String getLastPathSegment(); public boolean equals(Object o) { if (!(o instanceof Uri)) { return false; } Uri other = (Uri) o; return toString().equals(other.toString()); } public int hashCode() { return toString().hashCode(); } public int compareTo(Uri other) { return toString().compareTo(other.toString()); } public abstract String toString(); public String toSafeString() { String scheme = getScheme(); String ssp = getSchemeSpecificPart(); if (scheme != null) { if (scheme.equalsIgnoreCase("tel") || scheme.equalsIgnoreCase("sip") || scheme.equalsIgnoreCase("sms") || scheme.equalsIgnoreCase("smsto") || scheme.equalsIgnoreCase("mailto")) { StringBuilder builder = new StringBuilder(64); builder.append(scheme); builder.append(':'); if (ssp != null) { for (int i=0; i<ssp.length(); i++) { char c = ssp.charAt(i); if (c == '-' || c == '@' || c == '.') { builder.append(c); } else { builder.append('x'); } } } return builder.toString(); } } // Not a sensitive scheme, but let's still be conservative about // the data we include -- only the ssp, not the query params or // fragment, because those can often have sensitive info. StringBuilder builder = new StringBuilder(64); if (scheme != null) { builder.append(scheme); builder.append(':'); } if (ssp != null) { builder.append(ssp); } return builder.toString(); } public abstract Builder buildUpon(); /** Index of a component which was not found. */ private final static int NOT_FOUND = -1; /** Placeholder value for an index which hasn't been calculated yet. */ private final static int NOT_CALCULATED = -2; private static final String NOT_HIERARCHICAL = "This isn't a hierarchical URI."; /** Default encoding. */ private static final String DEFAULT_ENCODING = "UTF-8"; /** * Creates a Uri which parses the given encoded URI string. * * @param uriString an RFC 2396-compliant, encoded URI * @throws NullPointerException if uriString is null * @return Uri for this given uri string */ public static Uri parse(String uriString) { return new StringUri(uriString); } /** * Creates a Uri from a file. The URI has the form * "file://<absolute path>". Encodes path characters with the exception of * '/'. * * <p>Example: "file:///tmp/android.txt" * * @throws NullPointerException if file is null * @return a Uri for the given file */ public static Uri fromFile(File file) { if (file == null) { throw new NullPointerException("file"); } PathPart path = PathPart.fromDecoded(file.getAbsolutePath()); return new HierarchicalUri( "file", Part.EMPTY, path, Part.NULL, Part.NULL); } ...... }1、什么是Uri
Uri就是Android系统为了特殊需要,而制定的一种拥有特殊格式的一种数据模式。
从注释看:
The "four main components" of a hierarchical URI consist of <scheme>://<authority><path>?<query>就是说hierarchical 格式的Uri分为四部分:
1)scheme:访问资源的命名机制,通过这个可以获悉Uri 的具体资源存在形式,如http、content、file、market等
2)authority:存放资源的主机名,例如Provider 里面会对资源进行操作、存放,这个时候Provider就需要指出authority。
对于Provider 具体可以看一下:《Android基础总结之八:ContentProvider详解》
authority 应该是scheme:// 之后到第一次出现 ‘/’ 或‘?’ 或‘#’之间的string
3)path:authority之后第一个 ‘/’ 开始到 ‘?’ 或 ‘#’ 之前的string(包含'/')
4)query:'?' 号之后 '#' 号之前的string
经常看到的Uri形式有:
#打开一个网页 http://blog.3gstdy.com/ #打开地图并定位到一个点 geo:52.76,-79.0342 #拨打电话 tel:10086 #播放音频文件 file:///sdcard/download/everything.mp3 #打开发邮件界面 mailto:admin@3gstdy.com #寻找某个应用 market://search?q=pname:pkg_name #路径规划 http://maps.google .com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en
2、getScheme、getSchemeSpecificPart、getEncodedSchemeSpecificPart
1)getScheme:返回scheme,如果Uri是相对路径,那么就返回null
2)getSchemeSpecificPart :这里出现了ssp 概念,从这里可以将Uri 重新格式化为:
[scheme:]schemeSpecificPart[#fragment] ([...]表示可选)如果是个相对路径的话,就返回整个。
3)getEncodedSchemeSpecificPart:如果ssp里面有出现非A~Z、a~z、0~9、‘_’、‘-’、‘叹号’、‘点号’、‘~’、‘单引号’、‘(’、‘)’、‘星号’,都需要encode一把,有时候会看到%连接的一串,那都是encode。
详细的可以看一下source code:
for (int i = 0; i < bytesLength; i++) { encoded.append('%'); encoded.append(HEX_DIGITS[(bytes[i] & 0xf0) >> 4]); encoded.append(HEX_DIGITS[bytes[i] & 0xf]); }后面相关encode都是这样的,具体实现情况看函数:
String encode(String s, String allow)
3、isRelative、isAbsolute
isRelative:就是没有明确的scheme
isAbsolute:非isRelative
public boolean isAbsolute() { return !isRelative(); }
4、分层、不透明
/** * Returns true if this URI is hierarchical like "http://google.com". * Absolute URIs are hierarchical if the scheme-specific part starts with * a '/'. Relative URIs are always hierarchical. */ public abstract boolean isHierarchical(); /** * Returns true if this URI is opaque like "mailto:nobody@google.com". The * scheme-specific part of an opaque URI cannot start with a '/'. */ public boolean isOpaque() { return !isHierarchical(); }不透明也就是不分层。
通过注释可以大概理解两api 的意义:
如果ssp开头是 ‘/’,那么就是hierarchical,如果不是就是opaque。
当然,通过source code也能够确定的:
public boolean isHierarchical() { int ssi = findSchemeSeparator(); if (ssi == NOT_FOUND) { // All relative URIs are hierarchical. return true; } if (uriString.length() == ssi + 1) { // No ssp. return false; } // If the ssp starts with a '/', this is hierarchical. return uriString.charAt(ssi + 1) == '/'; }5、getHost()、getPort()
1)getHost:authority 中 ‘@’ 之后到 ‘:’ 之前的string
2)getPort:authority 中 ‘:’ 之后的 integer
6、Uri是个abstract类,好多函数是abstract的,肯定是有地方实现的。
那么Uri是abstract类,并不能实例化,应用的时候是怎么使用这些method,提供了两种方法:
public static Uri parse(String uriString) { return new StringUri(uriString); }
public static Uri fromFile(File file) { if (file == null) { throw new NullPointerException("file"); } PathPart path = PathPart.fromDecoded(file.getAbsolutePath()); return new HierarchicalUri( "file", Part.EMPTY, path, Part.NULL, Part.NULL); }显然是在这里new 出来了,返回的类型都是Uri,可以确定StringUri 和 HierarchicalUri都是Uri的子类了。
总结:
根据之前的解释可以清楚知道Uri 的格式:
scheme:ssp#fragment
1)scheme 就是第一个 ‘:’ 之前的部分,没有的就返回null
2)ssp:authority + path + query
当然其中的部分可能不存在,反正ssp就是这三部分的统称
ssp 语法:[//aurhority][path][?query]
authority 也可能包含了userinfo + host + port
authority语法:[userinfo@]host[:port]
3)fragment:第一次出现 ‘#’ 之后的string
相关文章推荐
- Android TextView中文字通过SpannableString来设置超链接、颜色、字体等属性
- android 物理按键
- android measure
- android 电容屏(三):驱动调试之驱动程序分析篇
- android 电容屏(二):驱动调试之基本概念篇
- 如何在Android智能手机上捕获数据包?
- android 电容屏(一):电容屏基本原理篇
- Android 自己的自动化测试(5)<robotium>
- Android自定义控件之乱涂
- Android常用的一些make命令
- Gradle 发布公共模块到maven库(android版)
- Android WiFi驱动测试 wireless-tools + wpa_supplicant
- 学习笔记-----Android的View绘制过程
- Android蓝牙聊天程序的扩展开发(基于Google Sample,类QQ设计)
- android布局margin和padding差异!
- 使用 android:paddingLeft报错解决办法
- [android]onTouch事件分发
- 【Android】四大组件(2)BroadcastReceiver详解
- 安卓中利用TranslateAnimation实现图片循环移动时候的出现的一个问题,在这里记一下
- GitHub 优秀的 Android 开源项目