• 读ActiveAndroid源码(一)


      首先ActiveAndroid是依靠注解工作的。

      

    @Table(name = "UserBean")
    public class UserBean extends Model {
    
        @Column(name = "uid")
        public String uid;
        @Column(name = "nick_name")
        public String nick_name;
    
        public String getUid() {
            return uid;
        }
    
        public void setUid(String uid) {
            this.uid = uid;
        }
    
        public String getNick_name() {
            return nick_name;
        }
    
        public void setNick_name(String nick_name) {
            this.nick_name = nick_name;
        }
    }

      对类添加Table注解,对类的成员添加Column注解,因此,我们可以先看看这两个注解的定义。

      

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Table {
    
        public static final String DEFAULT_ID_NAME = "Id";
        public String name();
        public String id() default DEFAULT_ID_NAME;
    }

      Table的定义如上,有两个成员,分别是idname,通常我们只需要设置nameid的名字为设置默认。这个name就是数据库的表名,id为表中作为id字段的名字。

      Column的定义比较复杂,但我们可以想象其中一定有name成员,name就是表中的字段名。

      然后,ActiveAndroid用了一个TableInfo类保存类和表的连接信息。先来看看这个类

      

    package com.activeandroid;
    
    /*
     * Copyright (C) 2010 Michael Pardo
     *
     * 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.lang.reflect.Field;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.LinkedHashMap;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    
    import android.text.TextUtils;
    import android.util.Log;
    
    import com.activeandroid.annotation.Column;
    import com.activeandroid.annotation.Table;
    import com.activeandroid.util.ReflectionUtils;
    
    public final class TableInfo {
        //////////////////////////////////////////////////////////////////////////////////////
        // PRIVATE MEMBERS
        //////////////////////////////////////////////////////////////////////////////////////
    
        private Class<? extends Model> mType;
        private String mTableName;
        private String mIdName = Table.DEFAULT_ID_NAME;
    
        private Map<Field, String> mColumnNames = new LinkedHashMap<Field, String>();
    
        //////////////////////////////////////////////////////////////////////////////////////
        // CONSTRUCTORS
        //////////////////////////////////////////////////////////////////////////////////////
    
        public TableInfo(Class<? extends Model> type) {
            mType = type;
    
            final Table tableAnnotation = type.getAnnotation(Table.class);
    
            if (tableAnnotation != null) {
                mTableName = tableAnnotation.name();
                mIdName = tableAnnotation.id();
            }
            else {
                mTableName = type.getSimpleName();
            }
    
            // Manually add the id column since it is not declared like the other columns.
            Field idField = getIdField(type);
            mColumnNames.put(idField, mIdName);
    
            List<Field> fields = new LinkedList<Field>(ReflectionUtils.getDeclaredColumnFields(type));
            Collections.reverse(fields);
    
            for (Field field : fields) {
                if (field.isAnnotationPresent(Column.class)) {
                    final Column columnAnnotation = field.getAnnotation(Column.class);
                    String columnName = columnAnnotation.name();
                    if (TextUtils.isEmpty(columnName)) {
                        columnName = field.getName();
                    }
    
                    mColumnNames.put(field, columnName);
                }
            }
    
        }
    
        //////////////////////////////////////////////////////////////////////////////////////
        // PUBLIC METHODS
        //////////////////////////////////////////////////////////////////////////////////////
    
        public Class<? extends Model> getType() {
            return mType;
        }
    
        public String getTableName() {
            return mTableName;
        }
    
        public String getIdName() {
            return mIdName;
        }
    
        public Collection<Field> getFields() {
            return mColumnNames.keySet();
        }
    
        public String getColumnName(Field field) {
            return mColumnNames.get(field);
        }
    
    
        private Field getIdField(Class<?> type) {
            if (type.equals(Model.class)) {
                try {
                    return type.getDeclaredField("mId");
                }
                catch (NoSuchFieldException e) {
                    Log.e("Impossible!", e.toString());
                }
            }
            else if (type.getSuperclass() != null) {
                return getIdField(type.getSuperclass());
            }
    
            return null;
        }
    
    }

      首先是成员变量

      

        private Class<? extends Model> mType;
        private String mTableName;
        private String mIdName = Table.DEFAULT_ID_NAME;
    
        private Map<Field, String> mColumnNames = new LinkedHashMap<Field, String>();

      mType:需要被储存的类的类型;

      mTableName:储存的类的表名;

      mIdName:储存的类的表的id字段名称;

      mColumnNames: 储存的表中的字段名与类中的成员的映射;

      

        public TableInfo(Class<? extends Model> type) {
            mType = type;
    
            final Table tableAnnotation = type.getAnnotation(Table.class);
    
            if (tableAnnotation != null) {
                mTableName = tableAnnotation.name();
                mIdName = tableAnnotation.id();
            }
            else {
                mTableName = type.getSimpleName();
            }

        ......

    }

      tableAnnotation保存被储存类的注解,并从注解中读出表名和表id名,如果没有注解,则默认类的简名为表名。

      

        public TableInfo(Class<? extends Model> type) {
            mType = type;
    
          ......
        
            // Manually add the id column since it is not declared like the other columns.
            Field idField = getIdField(type);
            mColumnNames.put(idField, mIdName);

        ......
    }

       手动添加表的id名与类的id关系。看看getIdField方法:

        private Field getIdField(Class<?> type) {
            if (type.equals(Model.class)) {
                try {
                    return type.getDeclaredField("mId");
                }
                catch (NoSuchFieldException e) {
                    Log.e("Impossible!", e.toString());
                }
            }
            else if (type.getSuperclass() != null) {
                return getIdField(type.getSuperclass());
            }
    
            return null;
        }

        一个递归,通过getSuperclass()寻找父类,一直到父类为Model,将其中mId成员返回。

      

      public TableInfo(Class<? extends Model> type) {      
    
         ......   
    
            List<Field> fields = new LinkedList<Field>(ReflectionUtils.getDeclaredColumnFields(type));
            Collections.reverse(fields);
    
            for (Field field : fields) {
                if (field.isAnnotationPresent(Column.class)) {
                    final Column columnAnnotation = field.getAnnotation(Column.class);
                    String columnName = columnAnnotation.name();
                    if (TextUtils.isEmpty(columnName)) {
                        columnName = field.getName();
                    }
    
                    mColumnNames.put(field, columnName);
                }
            }
    
        }

      如上这段代码,通过反射取出了要储存类的所有标注的成员,并获取它们的注解字段名,如果没有解注字段名,则用成员名代替。最终将它们全部与成员本身一一映射放入mColumnNames中。

      以上就是一个TableInfo的初始过程。

      综上,一个TableInfo类中,储存了,需要被储存对象A的类型;A的储存表名;A的id字段名;A的成员之间的映射与A的相关表的字段名。

       

      Done!

  • 相关阅读:
    android studio 各种问题
    关于Android开发中Arm、X86和Mips(草稿)
    每日更新
    Error creating bean with name 'userRepository': Invocation of init method failed;
    API 'variant.getJavaCompiler()' is obsolete and has been replaced with 'variant.getJavaCompileProvider()'
    increase the minSdkVersion to 26
    Exception thrown on Scheduler.Worker thread. Add `onError` handling
    M600 Pro 安装问题解决
    Could not parse multipart servlet request; nested exception is org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed.
    大疆无人机M100相关问题解决过程
  • 原文地址:https://www.cnblogs.com/fishbone-lsy/p/4869491.html
Copyright © 2020-2023  润新知