TableInfo在構造時會傳入一個Class<\? extends Model> type對象作爲參數:
- 調用type.getAnnotation(Table.class) 得到一個Table註解類,裏面描述了該Model對應的DB的table的信息
- 如果確實得到了一個Table註解對象,那麼會將該對象的name/id保存在mTableName/mIdName中.
- 如果沒有得到對應的Table註解對象(即該Model類並沒有加table註解), 那麼mTableName會取成該Model類的getSimpleName(). 而mIdName則使用一開始的默認值: Table.DEFAULT_ID_NAME = “Id”
- 調用getIdField(type)得到Model類中標識Id的Field: getIdField(type)的邏輯是:
- 如果傳入的Class類型是Model.class, 那麼返回該Class對象的”mId” Field.
- 否則如果不是,並且該Class還有父類,那麼對此父類調用getIdField(type.getSuperClass())
- 最終返回的應該是一個對應的name爲”mId”的Field.
- 得到Field對象以後,會將其作爲key, mIdName爲Value放入到mColumnNames中.
調用ReflectionUtils.getDeclaredColumnFields(type)得到一個Field的列表.
- ReflectionUtils.getDeclaredColumnFields()的實現:
- 只有在傳入的type是 Model.class以及其子類時纔會對其進行解析.
- 奪取type的getDeclaredFields(), 然後對得到的Field數組其進行遍歷, 如果某個Field isAnnotationPresent(Column.class)即有Column註解. 那麼會將此Field加入到返回的結果中.
- 在處理完此類本身以後,還會對其父類也做同樣的處理,最終將該類以及其祖先的所有滿足條件的Field對象得到並返回.
- ReflectionUtils.getDeclaredColumnFields()的實現:
回到TableInfo的構造函數, 對返回的具有Column註解的Field對象進行遍歷處理, 得到每個Field對象的Column.class註解即一個Column對象. 獲取此Column對象的name作爲Table的columnName, 如果是空的話,就用Field本身的name作爲ColumnName. 將此Field對象和前面得到的columnName放入到mColumnNames中.
- 從上面分析可見, 對於Id這個特殊的Column, 其columnName是有特殊處理的.
TypeSerializer:
- 在Configuration的構造過程中調用addTypeSerializer(…)可以加入一個具體的TypeSerializer子類實現對象.
- 在Configuration的構造中,如果之前填入了有效的TypeSerializer對象,那麼Configuration的mTypeSerializers就使用之前填入的TypeSerializer對象.
- 否則,如果沒有添加過有效的TypeSerializer對象, 那麼會調用ReflectionUtils.getMetaData(mContext, AA_SERIALIZERS(“AA_SERIALIZERS”))獲取一個String, 然後在String不爲空的情況下,調用loadSerializerList(serializerList.split(“,”)(字符串之間以“,”分割))得到一批TypeSerializer對象.
- loadSerializerList(String[] serializers): 獲取當前的classLoader(mContext.getClass().getClassLoader()), 然後使用檢測傳入的serializers字符串數組, 以字符串內容作爲類名,結合Class.forName(serializer.trim(), false, classLoader)獲取一個Class對象,並檢測該Class對象是否是一個TypeSerializer,如果是的話,就加入到一個list中, 最後返回該list, list中裝的都是在AA_SERIALIZERS meta data中指定,並且是TypeSerializer的Class的Class對象.
- 由上可見,在Configuration構造過程中加入TypeSerializer和在meta-data中指定TypeSerializer, 是互斥的.
- Configuration中的mTypeSerializers(即TypeSerializer類對象列表), 會在ModelInfo中的loadModelFromMetaData(Configuration configuration)中被使用,並將該List中所有的Class進行實例化instance然後mTypeSerializers.put(instance**.getDeserializedType()**, instance)將其存儲在TypeSerializerMap中.
- TypeSerializer的getDeserializedType()返回的是一個Class 對象,標識了該Serializer可以進行串行化的類型.
- ModelInfo中保存的mTypeSerializers會通過Cache的getParserForType(Class<\?> type)調用ModelInfo的getTypeSerializer(type)得到一個針對輸入的Type的Class類型的TypeSerializer
- Cache的getParserForType(..)會在Model的save()和loadFromCursor(…)中被使用,以進行數組的串行化和恢復.
- TypeSerializer使得調用者可以自行決定自己定義的Model類中的特殊非基本類型成員該如何被序列化已經持久化到DB中, 比如Map/List
Model save()
- 先調用Cache的openDatabase()得到一個SQLiteDatabase db,並new一個ContentValues用來保存要存儲的值.
- Model的mTableInfo中保存了此Model類中需要進行保存的所有相關的Field.
- 並根據此Field從mTableInfo中取出對應的columnName.
- 獲取field.get(this)得到此Field
- 根據Field的Type可以在Cache中通過getParserForType得到相應的TypeSerializer, 如果不是null, 那麼說明找到了一個可以用的TypeSerializer.
- 使用得到的TypeSerializer來對Field的Value的進行serialize(value), 如果serialize以後得到的結果對象不是null, 那麼調用其getClass(因爲TypeSerializer的serialize()和deserialize()返回的類型都是Object, 而標識其串行和反串行類型的則是由getDeserializedType()/getSerializedType()來標識的), 並檢測結果對象的類型是不是TypeSerializer指定的getSerializedType()即在序列化以後的結果的類型. 之前表明Field類型的fieldType也會替換爲序列化之後的結果對象的類型.
- 在經過Serialize以後(如果有對應的TypeSerializer的話), 會根據此時Value的類型將value進行轉型並存放到要傳給SqlDataBase的ContentValue中.
- 轉型只支持幾種類型: null(會調用contentValue的putNull(fieldName))/Byte/byte/Short/short/Integer/int/Long/long/Float/float/Double/double/Boolean/boolean/Character/char/String/Byte[]/byte[]/Model及其衍生類,不過這裏實際存的只是Model的Id/Enum,但是實際存的是name(), 對於其他的類型的數據,一概忽略.
ActiveAndroid TableInfo TypeSerializer
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.