zoukankan      html  css  js  c++  java
  • android的UriMatcher类

    package fkshl.activity.contentProvider;
    
    /* 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");
    
            }
            //以"/"分隔path
            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++) {
                //当前循环变量小于0就取authority,否则就获取分隔后的数组的字符,并赋值给token
                String token = i < 0 ? authority : tokens[i];
                //把当前对象的集合赋值给children
                ArrayList<UriMatcher> children = node.mChildren;
                //获取其长度
                int numChildren = children.size();    
                      UriMatcher child;
                int j;    
                for (j = 0; j < numChildren; j++) {
                    //获取children对象的孩子
                    child = children.get(j);
                    //判断当前的token和child对象中的mText是否相等
                    if (token.equals(child.mText)) {
                        //把child 赋值给 node;
                        node = child;
                        break;
                    }
                }
                //获取循环变量j并判断是否等于children对应的大小.也就是判断是否是最后一个
                if (j == numChildren) {
                    // Child not found, create it
                    //没有发现孩子,并创建
                    child = new UriMatcher();
                    ///判断当前的token是否等于"#"
                    if (token.equals("#")) {
                        //mWhich=1
                        child.mWhich = NUMBER;
                    } else if (token.equals("*")) {
                        //mWhich=2
                        child.mWhich = TEXT;
                    } else {
                        //mWhich=0
                        child.mWhich = EXACT;
                    }
                    //mText=当前的token
                    child.mText = token;
                    //添加到mChildren集合中
                    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源码.
    由于不懂所以就把它粘贴的项目中.所以包自然就改成自己项目的了..
    package fkshl.activity.contentProvider;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import android.content.ContentProvider;
    import android.content.ContentUris;
    import android.content.ContentValues;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteQueryBuilder;
    import android.net.Uri;
    import android.text.TextUtils;
    import fkshl.activity.contentProviderMetaData.ContentProviderMetaData;
    import fkshl.activity.contentProviderMetaData.ContentProviderMetaData.UserTableMetaData;
    import fkshl.activity.dataBase.DBHelper;
    
    public class FkshlContentProvider extends ContentProvider {
    
        public static final UriMatcher URI_MATCHER;
        public static final int FKSHL_TABLE = 1;
        public static final int FKSHL_TABLE_COLUMN = 2;
        public static final Map<String, String> COLUM_MAPPIGN;
    
        public DBHelper dbHelper;
    
        static {
            /**
             * uri验证
             */
            URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
            URI_MATCHER.addURI(ContentProviderMetaData.AUTHORIY, "users", 1);
            URI_MATCHER.addURI(ContentProviderMetaData.AUTHORIY, "users/#", 2);
    
            /**
             * 列的映射
             */
            COLUM_MAPPIGN = new HashMap<String, String>();
            COLUM_MAPPIGN.put(UserTableMetaData._ID, UserTableMetaData._ID);
            COLUM_MAPPIGN.put(UserTableMetaData.COLUMN_NAME, UserTableMetaData.COLUMN_NAME);
        }
    
        @Override
        public int delete(Uri uri, String selection, String[] selectionArgs) {
            // TODO Auto-generated method stub
            return 0;
        }
    
        @Override
        public String getType(Uri uri) {
            // TODO Auto-generated method stub
            switch (URI_MATCHER.match(uri)) {
            case FKSHL_TABLE:
                return UserTableMetaData.CONTENT_TYPE;
            case FKSHL_TABLE_COLUMN:
                return UserTableMetaData.CONTENT_TYPE_ITEM;
            default:
                throw new IllegalArgumentException("Unknown URI!!!!!" + uri);
            }
        }
    
        @Override
        public Uri insert(Uri uri, ContentValues values) {
            // TODO Auto-generated method stub
            SQLiteDatabase database = dbHelper.getWritableDatabase();
            Long rowId = database.insert(ContentProviderMetaData.TABLE_NAME, null, values);
            if (rowId > 0) {
                Uri empuri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId);
                getContext().getContentResolver().notifyChange(empuri, null);
                System.out.println("insert success!!!");
            }
            return null;
        }
    
        @Override
        public boolean onCreate() {
            // TODO Auto-generated method stub
            dbHelper = new DBHelper(getContext(), ContentProviderMetaData.DATABASE_NAME);
            dbHelper.getReadableDatabase();
            System.out.println("create database success!!");
            return true;
        }
    
        @Override
        public Cursor query(Uri uri, String[] projection, String selection,
                String[] selectionArgs, String sortOrder) {
            SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
            // TODO Auto-generated method stub
            switch (URI_MATCHER.match(uri)) {
            case FKSHL_TABLE:
                builder.setTables(UserTableMetaData.TABLE_NAME);
                builder.setProjectionMap(COLUM_MAPPIGN);
                break;
            case FKSHL_TABLE_COLUMN:
                builder.setTables(UserTableMetaData.TABLE_NAME);
                builder.setProjectionMap(COLUM_MAPPIGN);
                builder.appendWhere(UserTableMetaData.COLUMN_NAME + "="
                        + uri.getPathSegments().get(1));
                break;
    
            default:
                throw new IllegalArgumentException("uri error !!!!" + uri);
            }
            String orderBy;
            if (TextUtils.isEmpty(sortOrder)) {
                orderBy = UserTableMetaData.ORDER_BY + " Desc";
            } else {
                orderBy = sortOrder;
            }
            SQLiteDatabase database = dbHelper.getReadableDatabase();
            Cursor c =    builder.query(database, projection, selection, selectionArgs, null, null, orderBy);
            c.setNotificationUri(getContext().getContentResolver(), uri);
            System.out.println("seach end!!!!");
            return c;
        }
    
        @Override
        public int update(Uri uri, ContentValues values, String selection,
                String[] selectionArgs) {
            // TODO Auto-generated method stub
            return 0;
        }
    
    }
    做的时间发现一个问题.
    这是之前发现在按官方提示做的.
        URI_MATCHER.addURI(ContentProviderMetaData.AUTHORIY, "/users", 1);
            URI_MATCHER.addURI(ContentProviderMetaData.AUTHORIY, "/users/#", 2);
    可是在getType中怎么都走default.都是抛异常.
    05-22 09:39:23.449: ERROR/AndroidRuntime(581): java.lang.IllegalArgumentException: uri error !!!!content://fkshl.activity.contentProvider.FkshlContentProvider/users
    最后看了源码,改成了.
        URI_MATCHER.addURI(ContentProviderMetaData.AUTHORIY, "users", 1);
            URI_MATCHER.addURI(ContentProviderMetaData.AUTHORIY, "users/#", 2);
    这样就好.
    原因是在add方法中它会以"/"分隔users/#,然后把分隔后的字符串像树型的一级一级保存在mChildren中.如果在users/#前面加"/",哪么就导致在"/"之前有一个空字符(content://fkshl.activity.contentProvider.FkshlContentProvider//users),而在我的项目中调用getType方法传过来时的uir中没有这样的一个空字符(content://fkshl.activity.contentProvider.FkshlContentProvider/users)
    没有.

    转  http://fkshl.iteye.com/blog/1054518

  • 相关阅读:
    Google C++单元测试框架GoogleTest---值参数化测试
    Google C++单元测试框架GoogleTest---Extending Google Test by Handling Test Events
    Google C++单元测试框架GoogleTest---AdvancedGuide(译文)上
    Google C++单元测试框架GoogleTest---TestFixture使用
    Android View的绘制流程
    第一节:Python+Selenium环境搭建
    Holmos框架
    log4j.properties配置详解与实例-全部测试通过
    Selenium+Java完整框架搭建(2019完整版)
    Mac JDK 卸载方法
  • 原文地址:https://www.cnblogs.com/622698abc/p/2761908.html
Copyright © 2011-2022 走看看