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,当匹配成功时则codeURI可以是精确的字符串,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 size0uriAuthoritynull则返回默认值(此默认值在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[i];
			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 it
				child = new UriMatcher();
				if (token.equals("#")) {
					//mWhich=1
					child.mWhich = NUMBER;
				} else if (token.equals("*")) {
					//mWhich=2
					child.mWhich = TEXT;
				} else {
					//mWhich=0
					child.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;

}

 

 

 

你可能感兴趣的:(android,urimatcher)