首先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!

 

posted on 2015-10-11 16:21  Fishbonell  阅读(300)  评论(0编辑  收藏  举报