liyf155 发表于 2013-1-14 18:00:11

UriMatcher类的学习

UriMatcher类
 
          在ContentProvider中,该类主要用来帮助匹配相对应的URI。
 
1.       构造函数:创建URI树的根节点
a)       Public UriMatcher():默认根节点编码为-1;
b)       Public UriMatcher(int code):code参数表示指定根节点的编码。
 
2.       方法
a)       Public void addURI(String authority, String path, int code)
添加一个用于匹配的URI,当匹配成功时则code。URI可以是精确的字符串,uri中带有*表示可匹配任意text,#表示只能匹配数字。
Authority:用于匹配的域名;
Path:匹配路径,*表示text的占位符,#表示使用数字的占位符;
Code:当使用匹配成功后返回code,值需要大于0,否则抛出IllegalArgument异常。
此方法将authority按照”/”进行拆分,然后将拆分后的每一部分保存到UriMatcher类型的ArrayList中;在添加的时候会判断当前authority是否已经添加过,若已加则break;若未添加过,则判断是否含有”#”则将其标识成1代表域名后面跟随的是数字;”*”标识成2,代表域名后面跟随的是文本;0代表后面没有跟随数据;最后创建一个新的UriMatcher对象添加到集合中。
b)       Public int match(Uri uri)
尝试在url中匹配相对应的路径
Uri:指定需要匹配的url;
返回值:在使用addURI时产生的code,若没有匹配则返回-1。
使用uri. getPathSegments()获取uri中各段存入list中,若list size为0或uri的Authority为null则返回默认值(此默认值在new时指定,若为指定则为-1);
然后遍历ArrayLis<UriMatcher>进行匹配uri。
 
参考源码:
/* Copyright (C) 2006 The Android Open Source Project   *   * Licensed under the Apache License, Version 2.0 (the "License");   * you may not use this file except in compliance with the License.   * You may obtain a copy of the License at   *   *      http://www.apache.org/licenses/LICENSE-2.0   *   * Unless required by applicable law or agreed to in writing, software   * distributed under the License is distributed on an "AS IS" BASIS,   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   * See the License for the specific language governing permissions and   * limitations under the License.   */import java.util.ArrayList;import java.util.List;import java.util.regex.Pattern;import android.net.Uri;public class UriMatcher{public static final int NO_MATCH = -1;/*** ** Creates the root node of the URI tree. **** @param code *            the code to match for the root URI */public UriMatcher(int code){mCode = code;mWhich = -1;mChildren = new ArrayList<UriMatcher>();mText = null;}private UriMatcher(){mCode = NO_MATCH;mWhich = -1;mChildren = new ArrayList<UriMatcher>();mText = null;}/*** ** Add a URI to match, and the code to return when this URI is ** matched. URI nodes may be exact match string, the token "*" ** that matches any text, or the token "#" that matches only ** numbers. **** @param authority *            the authority to match ** @param path *            the path to match. * may be used as a wild card for **            any text, and # may be used as a wild card for numbers. ** @param code *            the code that is returned when a URI is matched **            against the given components. Must be positive. */public void addURI(String authority, String path, int code){if (code < 0) {throw new IllegalArgumentException("code " + code+ " is invalid: it must be positive");}String[] tokens = path != null ? PATH_SPLIT_PATTERN.split(path) : null;int numTokens = tokens != null ? tokens.length : 0;UriMatcher node = this;for (int i = -1; i < numTokens; i++) {String token = i < 0 ? authority : tokens;ArrayList<UriMatcher> children = node.mChildren;int numChildren = children.size();          UriMatcher child;int j;for (j = 0; j < numChildren; j++) {child = children.get(j);if (token.equals(child.mText)) {node = child;break;}}if (j == numChildren) {// Child not found, create itchild = new UriMatcher();if (token.equals("#")) {//mWhich=1child.mWhich = NUMBER;} else if (token.equals("*")) {//mWhich=2child.mWhich = TEXT;} else {//mWhich=0child.mWhich = EXACT;}child.mText = token;node.mChildren.add(child);//node = child;node = child;}}//node.mCode = code;node.mCode = code;}static final Pattern PATH_SPLIT_PATTERN = Pattern.compile("/");/*** ** Try to match against the path in a url. **** @param uri *            The url whose path we will match against. **** @return The code for the matched node (added using addURI), **         or -1 if there is no matched node. */public int match(Uri uri){final List<String> pathSegments = uri.getPathSegments();final int li = pathSegments.size();UriMatcher node = this;if (li == 0 && uri.getAuthority() == null) {return this.mCode;}for (int i = -1; i < li; i++) {String u = i < 0 ? uri.getAuthority() : pathSegments.get(i);ArrayList<UriMatcher> list = node.mChildren;if (list == null) {break;}node = null;int lj = list.size();for (int j = 0; j < lj; j++) {UriMatcher n = list.get(j);which_switch:switch (n.mWhich) {case EXACT:if (n.mText.equals(u)) {node = n;}      break;case NUMBER:int lk = u.length();for (int k = 0; k < lk; k++) {char c = u.charAt(k);             if (c < '0' || c > '9') {break which_switch;}}node = n;break;case TEXT:node = n;break;}if (node != null) {   break;}}if (node == null) {return NO_MATCH;}}return node.mCode;}private static final int EXACT = 0;private static final int NUMBER = 1;private static final int TEXT = 2;private int mCode;private int mWhich;private String mText;private final ArrayList<UriMatcher> mChildren;} 

 
 
页: [1]
查看完整版本: UriMatcher类的学习