From ff87e7ee9f6a899f0a0ebf2b1ff5b592d19b31fe Mon Sep 17 00:00:00 2001 From: lsjwzh Date: Wed, 9 Oct 2013 09:26:04 +0800 Subject: [PATCH 1/5] =?UTF-8?q?1.=E5=A2=9E=E5=8A=A0FinalBitmap=20display?= =?UTF-8?q?=20=E6=97=B6=E8=BF=9B=E8=A1=8C=E5=89=8D=E7=BD=AE=E5=A4=84?= =?UTF-8?q?=E7=90=86=E7=9A=84=E5=8A=9F=E8=83=BD=202.=E7=94=9F=E6=88=90?= =?UTF-8?q?=E5=AE=9E=E4=BD=93=E7=B1=BB=E6=97=B6=EF=BC=8C=E8=B7=B3=E8=BF=87?= =?UTF-8?q?=E5=AE=9E=E4=BD=93=E7=B1=BB=E4=B8=AD=E7=9A=84=E9=9D=99=E6=80=81?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=203.=E4=BF=AE=E5=A4=8D=E6=9F=90=E4=BA=9B?= =?UTF-8?q?=E6=83=85=E5=86=B5=E4=B8=8Bfinaldb=20lazyload=20=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E4=B8=8D=E5=88=B0=E6=95=B0=E6=8D=AE=E7=9A=84=E5=8E=9F?= =?UTF-8?q?=E5=9B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/net/tsz/afinal/FinalBitmap.java | 9 ++++-- src/net/tsz/afinal/FinalDb.java | 6 ++-- .../bitmap/core/BitmapDisplayConfig.java | 31 +++++++++++++++++-- .../tsz/afinal/bitmap/core/BitmapProcess.java | 5 ++- .../afinal/db/sqlite/OneToManyLazyLoader.java | 2 +- src/net/tsz/afinal/utils/ClassUtils.java | 5 +++ 6 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/net/tsz/afinal/FinalBitmap.java b/src/net/tsz/afinal/FinalBitmap.java index b718da9..1721ad9 100644 --- a/src/net/tsz/afinal/FinalBitmap.java +++ b/src/net/tsz/afinal/FinalBitmap.java @@ -341,6 +341,10 @@ private void doDisplay(View imageView, String uri, BitmapDisplayConfig displayCo } if (bitmap != null) { + //在展示之前进行前置图形处理 + if(displayConfig.getBeforeDisplayProcess()!=null){ + bitmap =displayConfig.getBeforeDisplayProcess().process(bitmap); + } if(imageView instanceof ImageView){ ((ImageView)imageView).setImageBitmap(bitmap); }else{ @@ -352,7 +356,7 @@ private void doDisplay(View imageView, String uri, BitmapDisplayConfig displayCo final BitmapLoadAndDisplayTask task = new BitmapLoadAndDisplayTask(imageView, displayConfig ); //设置默认图片 final AsyncDrawable asyncDrawable = new AsyncDrawable(mContext.getResources(), displayConfig.getLoadingBitmap(), task); - + if(imageView instanceof ImageView){ ((ImageView)imageView).setImageDrawable(asyncDrawable); }else{ @@ -772,5 +776,6 @@ public FinalBitmapConfig(Context context) { } } - + + } diff --git a/src/net/tsz/afinal/FinalDb.java b/src/net/tsz/afinal/FinalDb.java index 203fe28..8858757 100644 --- a/src/net/tsz/afinal/FinalDb.java +++ b/src/net/tsz/afinal/FinalDb.java @@ -82,8 +82,10 @@ private SQLiteDatabase createDbFileOnSDCard(String sdcardPath,String dbfilename) File dbp=new File(pathCache+"/"+dir); if(!dbp.exists()){ dbp.mkdir(); - pathCache = dbp.getAbsolutePath(); + } + //确保部分目录存在时仍能正常创建 + pathCache = dbp.getAbsolutePath(); } File dbf=new File(dbPath+"/"+dbfilename); @@ -521,7 +523,7 @@ public T loadOneToMany(T entity ,Class clazz,Class ... findClass){ } if(isFind){ - List list = findAllByWhere(one.getOneClass(), one.getColumn()+"='"+id+"'"); + List list = findAllByWhere(one.getOneClass(), one.getColumn()+"='"+id+"' or "+one.getColumn()+"="+id); if(list!=null){ /*如果是OneToManyLazyLoader泛型,则执行灌入懒加载数据*/ if(one.getDataType()==OneToManyLazyLoader.class){ diff --git a/src/net/tsz/afinal/bitmap/core/BitmapDisplayConfig.java b/src/net/tsz/afinal/bitmap/core/BitmapDisplayConfig.java index a27ce5c..bedd736 100644 --- a/src/net/tsz/afinal/bitmap/core/BitmapDisplayConfig.java +++ b/src/net/tsz/afinal/bitmap/core/BitmapDisplayConfig.java @@ -15,12 +15,37 @@ */ package net.tsz.afinal.bitmap.core; +import android.content.Context; import android.graphics.Bitmap; +import android.util.DisplayMetrics; import android.view.animation.Animation; public class BitmapDisplayConfig { - - + public IBeforeDisplayProcess getBeforeDisplayProcess() { + return beforeDisplay; + } + + public void setBeforeDisplayProcess(IBeforeDisplayProcess beforeDisplay) { + this.beforeDisplay = beforeDisplay; + } + + /** + * 用于对网络图片进行前置处理 + */ + public interface IBeforeDisplayProcess { + public Bitmap process(Bitmap downloadedBitmap); + } + public static BitmapDisplayConfig newDefaultInstance(Context context){ + BitmapDisplayConfig defaultDisplayConfig = new BitmapDisplayConfig(); + defaultDisplayConfig.setAnimation(null); + defaultDisplayConfig.setAnimationType(BitmapDisplayConfig.AnimationType.fadeIn); + //设置图片的显示最大尺寸(为屏幕的大小,默认为屏幕宽度的1/2) + DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); + int defaultWidth = (int)Math.floor(displayMetrics.widthPixels/2); + defaultDisplayConfig.setBitmapHeight(defaultWidth); + defaultDisplayConfig.setBitmapWidth(defaultWidth); + return defaultDisplayConfig; + } private int bitmapWidth; private int bitmapHeight; @@ -29,7 +54,7 @@ public class BitmapDisplayConfig { private int animationType; private Bitmap loadingBitmap; private Bitmap loadfailBitmap; - + private IBeforeDisplayProcess beforeDisplay; public int getBitmapWidth() { return bitmapWidth; diff --git a/src/net/tsz/afinal/bitmap/core/BitmapProcess.java b/src/net/tsz/afinal/bitmap/core/BitmapProcess.java index 1fc5b2b..88c2f7d 100644 --- a/src/net/tsz/afinal/bitmap/core/BitmapProcess.java +++ b/src/net/tsz/afinal/bitmap/core/BitmapProcess.java @@ -48,7 +48,10 @@ public Bitmap getBitmap(String url, BitmapDisplayConfig config) { mCache.addToDiskCache(url, data); } } - + //在展示之前进行前置图形处理 + if(config.getBeforeDisplayProcess()!=null){ + bitmap =config.getBeforeDisplayProcess().process(bitmap); + } return bitmap; } diff --git a/src/net/tsz/afinal/db/sqlite/OneToManyLazyLoader.java b/src/net/tsz/afinal/db/sqlite/OneToManyLazyLoader.java index 3d701ad..7eb9740 100644 --- a/src/net/tsz/afinal/db/sqlite/OneToManyLazyLoader.java +++ b/src/net/tsz/afinal/db/sqlite/OneToManyLazyLoader.java @@ -29,7 +29,7 @@ public OneToManyLazyLoader(O ownerEntity,Class ownerClazz,Class listItemcl * 如果数据未加载,则调用loadOneToMany填充数据 * @return */ - public List getList(){ + public synchronized List getList(){ if(entities==null){ this.db.loadOneToMany((O)this.ownerEntity,this.ownerClazz,this.listItemClazz); } diff --git a/src/net/tsz/afinal/utils/ClassUtils.java b/src/net/tsz/afinal/utils/ClassUtils.java index 208876c..d44c69e 100644 --- a/src/net/tsz/afinal/utils/ClassUtils.java +++ b/src/net/tsz/afinal/utils/ClassUtils.java @@ -16,6 +16,7 @@ package net.tsz.afinal.utils; import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; @@ -160,6 +161,10 @@ public static List getPropertyList(Class clazz) { Field[] fs = clazz.getDeclaredFields(); String primaryKeyFieldName = getPrimaryKeyFieldName(clazz); for (Field f : fs) { + //如果是静态字段则跳过 + if(Modifier.isStatic(f.getModifiers())){ + continue; + } //必须是基本数据类型和没有标瞬时态的字段 if(!FieldUtils.isTransient(f)){ if (FieldUtils.isBaseDateType(f)) { From 64932a24d1668baa9c3bec8e6ec382dc05a9b00e Mon Sep 17 00:00:00 2001 From: lsjwzh Date: Tue, 17 Dec 2013 17:10:04 +0800 Subject: [PATCH 2/5] =?UTF-8?q?1.=E7=A1=AE=E4=BF=9DloadCompletedisplay?= =?UTF-8?q?=E8=83=BD=E5=9C=A8=E6=AF=8F=E6=AC=A1display=E6=97=B6=E8=B0=83?= =?UTF-8?q?=E7=94=A8,=E4=BE=BF=E4=BA=8E=E5=B1=95=E7=A4=BA=E5=89=8D?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=9B=BE=E7=89=87=EF=BC=88=E5=A6=82=E5=9C=86?= =?UTF-8?q?=E8=A7=92=E5=A4=84=E7=90=86=EF=BC=89=202.=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E5=8D=87=E7=BA=A7=E6=94=AF=E6=8C=81?= =?UTF-8?q?=203.=E4=B8=80=E5=AF=B9=E5=A4=9A=E5=A2=9E=E5=8A=A0=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=E6=8E=92=E5=BA=8F=E5=AD=97=E6=AE=B5=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=204.=E5=88=9B=E5=BB=BA=E5=AD=97=E6=AE=B5=E6=97=B6=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=E6=95=B0=E5=80=BC=E5=AD=97=E6=AE=B5=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=EF=BC=8C=E4=BB=A5=E5=85=8D=E6=8E=92=E5=BA=8F=E6=88=96=E6=9F=A5?= =?UTF-8?q?=E6=89=BE=E6=97=B6=E5=87=BA=E9=94=99=205.=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=B4=A2=E5=BC=95=E5=88=9B=E5=BB=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/net/tsz/afinal/FinalBitmap.java | 26 +++++----- src/net/tsz/afinal/FinalDb.java | 47 +++++++++++++++---- .../tsz/afinal/annotation/sqlite/Index.java | 14 ++++++ .../afinal/annotation/sqlite/OneToMany.java | 4 ++ .../bitmap/core/BitmapDisplayConfig.java | 31 ++---------- .../tsz/afinal/bitmap/core/BitmapProcess.java | 5 +- src/net/tsz/afinal/db/sqlite/CursorUtils.java | 20 +++++--- .../afinal/db/sqlite/ManyToOneLazyLoader.java | 3 -- .../afinal/db/sqlite/OneToManyLazyLoader.java | 2 +- src/net/tsz/afinal/db/sqlite/SqlBuilder.java | 30 ++++++++++-- src/net/tsz/afinal/db/table/OneToMany.java | 20 +++++++- src/net/tsz/afinal/utils/ClassUtils.java | 6 ++- 12 files changed, 135 insertions(+), 73 deletions(-) create mode 100644 src/net/tsz/afinal/annotation/sqlite/Index.java diff --git a/src/net/tsz/afinal/FinalBitmap.java b/src/net/tsz/afinal/FinalBitmap.java index 1721ad9..85b2d37 100644 --- a/src/net/tsz/afinal/FinalBitmap.java +++ b/src/net/tsz/afinal/FinalBitmap.java @@ -341,22 +341,19 @@ private void doDisplay(View imageView, String uri, BitmapDisplayConfig displayCo } if (bitmap != null) { - //在展示之前进行前置图形处理 - if(displayConfig.getBeforeDisplayProcess()!=null){ - bitmap =displayConfig.getBeforeDisplayProcess().process(bitmap); - } - if(imageView instanceof ImageView){ - ((ImageView)imageView).setImageBitmap(bitmap); - }else{ - imageView.setBackgroundDrawable(new BitmapDrawable(bitmap)); - } - - - }else if (checkImageTask(uri, imageView)) { +// if(imageView instanceof ImageView){ +// ((ImageView)imageView).setImageBitmap(bitmap); +// }else{ +// imageView.setBackgroundDrawable(new BitmapDrawable(bitmap)); +// } + //modify by pwy 20131015,确保loadCompletedisplay能在每次display时调用 + mConfig.displayer.loadCompletedisplay(imageView,bitmap,displayConfig); + + }else if (checkImageTask(uri, imageView)) { final BitmapLoadAndDisplayTask task = new BitmapLoadAndDisplayTask(imageView, displayConfig ); //设置默认图片 final AsyncDrawable asyncDrawable = new AsyncDrawable(mContext.getResources(), displayConfig.getLoadingBitmap(), task); - + if(imageView instanceof ImageView){ ((ImageView)imageView).setImageDrawable(asyncDrawable); }else{ @@ -776,6 +773,5 @@ public FinalBitmapConfig(Context context) { } } - - + } diff --git a/src/net/tsz/afinal/FinalDb.java b/src/net/tsz/afinal/FinalDb.java index 8858757..488ea12 100644 --- a/src/net/tsz/afinal/FinalDb.java +++ b/src/net/tsz/afinal/FinalDb.java @@ -38,8 +38,11 @@ import android.content.Context; import android.database.Cursor; import android.database.SQLException; +import android.database.sqlite.SQLiteCursorDriver; import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteOpenHelper; +import android.database.sqlite.SQLiteQuery; import android.util.Log; public class FinalDb { @@ -57,20 +60,22 @@ private FinalDb(DaoConfig config){ if(config.getContext() == null) throw new DbException("android context is null"); if(config.isSaveOnSDCard()){ - this.db = createDbFileOnSDCard(config.getTargetDirectory(),config.getDbName()); + this.db = createDbFileOnSDCard(config.getTargetDirectory(),config.getDbName(),config.getDbVersion(),config.getDbUpdateListener()); }else{ this.db = new SqliteDbHelper(config.getContext().getApplicationContext(), config.getDbName(), config.getDbVersion(),config.getDbUpdateListener()).getWritableDatabase(); } this.config = config; } + + /** * 在SD卡的指定目录上创建文件 * @param sdcardPath * @param dbfilename * @return */ - private SQLiteDatabase createDbFileOnSDCard(String sdcardPath,String dbfilename){ + private SQLiteDatabase createDbFileOnSDCard(String sdcardPath,String dbfilename, int dbVersion, DbUpdateListener dbUpdateListener){ String dbPath=android.os.Environment.getExternalStorageDirectory() .getAbsolutePath()+(sdcardPath==null||sdcardPath.length()==0?"":"/" +sdcardPath); String[] dirs = sdcardPath.split("/"); @@ -82,10 +87,8 @@ private SQLiteDatabase createDbFileOnSDCard(String sdcardPath,String dbfilename) File dbp=new File(pathCache+"/"+dir); if(!dbp.exists()){ dbp.mkdir(); - + pathCache = dbp.getAbsolutePath(); } - //确保部分目录存在时仍能正常创建 - pathCache = dbp.getAbsolutePath(); } File dbf=new File(dbPath+"/"+dbfilename); @@ -102,8 +105,29 @@ private SQLiteDatabase createDbFileOnSDCard(String sdcardPath,String dbfilename) else{ isFileCreateSuccess=true; } - if(isFileCreateSuccess) - return SQLiteDatabase.openOrCreateDatabase(dbf, null); + if(isFileCreateSuccess){ + //add by pwy 2013/11/14 增加数据库升级支持 + SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbf,null); + //目前只支持升级,不支持降级 + if(db.getVersion() T loadOneToMany(T entity ,Class clazz,Class ... findClass){ } if(isFind){ - List list = findAllByWhere(one.getOneClass(), one.getColumn()+"='"+id+"' or "+one.getColumn()+"="+id); + //add by pwy 20131015 for 懒加载排序 + String strWhere = "(" + one.getColumn()+"='"+id+"' or "+one.getColumn()+"="+id+")"+ + ((one.getOrderColumn()!=null&&one.getOrderColumn().length()>0) + ?" order by "+one.getOrderColumn()+ (one.isDesc()?" desc":" asc") + :""); + List list = findAllByWhere(one.getOneClass(), strWhere); if(list!=null){ /*如果是OneToManyLazyLoader泛型,则执行灌入懒加载数据*/ if(one.getDataType()==OneToManyLazyLoader.class){ @@ -648,7 +677,7 @@ public List findDbModelListBySQL(String strSQL){ - private void checkTableExist(Class clazz){ + public void checkTableExist(Class clazz){ if(!tableIsExist(TableInfo.get(clazz))){ String sql = SqlBuilder.getCreatTableSQL(clazz); debugSql(sql); diff --git a/src/net/tsz/afinal/annotation/sqlite/Index.java b/src/net/tsz/afinal/annotation/sqlite/Index.java new file mode 100644 index 0000000..5be3b8e --- /dev/null +++ b/src/net/tsz/afinal/annotation/sqlite/Index.java @@ -0,0 +1,14 @@ +package net.tsz.afinal.annotation.sqlite; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 是否有索引 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Index { +} diff --git a/src/net/tsz/afinal/annotation/sqlite/OneToMany.java b/src/net/tsz/afinal/annotation/sqlite/OneToMany.java index fad5bb9..508ea1a 100644 --- a/src/net/tsz/afinal/annotation/sqlite/OneToMany.java +++ b/src/net/tsz/afinal/annotation/sqlite/OneToMany.java @@ -25,4 +25,8 @@ public @interface OneToMany { public String manyColumn(); + + public String orderColumn() default ""; + + public boolean orderDesc() default false; } diff --git a/src/net/tsz/afinal/bitmap/core/BitmapDisplayConfig.java b/src/net/tsz/afinal/bitmap/core/BitmapDisplayConfig.java index bedd736..a27ce5c 100644 --- a/src/net/tsz/afinal/bitmap/core/BitmapDisplayConfig.java +++ b/src/net/tsz/afinal/bitmap/core/BitmapDisplayConfig.java @@ -15,37 +15,12 @@ */ package net.tsz.afinal.bitmap.core; -import android.content.Context; import android.graphics.Bitmap; -import android.util.DisplayMetrics; import android.view.animation.Animation; public class BitmapDisplayConfig { - public IBeforeDisplayProcess getBeforeDisplayProcess() { - return beforeDisplay; - } - - public void setBeforeDisplayProcess(IBeforeDisplayProcess beforeDisplay) { - this.beforeDisplay = beforeDisplay; - } - - /** - * 用于对网络图片进行前置处理 - */ - public interface IBeforeDisplayProcess { - public Bitmap process(Bitmap downloadedBitmap); - } - public static BitmapDisplayConfig newDefaultInstance(Context context){ - BitmapDisplayConfig defaultDisplayConfig = new BitmapDisplayConfig(); - defaultDisplayConfig.setAnimation(null); - defaultDisplayConfig.setAnimationType(BitmapDisplayConfig.AnimationType.fadeIn); - //设置图片的显示最大尺寸(为屏幕的大小,默认为屏幕宽度的1/2) - DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); - int defaultWidth = (int)Math.floor(displayMetrics.widthPixels/2); - defaultDisplayConfig.setBitmapHeight(defaultWidth); - defaultDisplayConfig.setBitmapWidth(defaultWidth); - return defaultDisplayConfig; - } + + private int bitmapWidth; private int bitmapHeight; @@ -54,7 +29,7 @@ public static BitmapDisplayConfig newDefaultInstance(Context context){ private int animationType; private Bitmap loadingBitmap; private Bitmap loadfailBitmap; - private IBeforeDisplayProcess beforeDisplay; + public int getBitmapWidth() { return bitmapWidth; diff --git a/src/net/tsz/afinal/bitmap/core/BitmapProcess.java b/src/net/tsz/afinal/bitmap/core/BitmapProcess.java index 88c2f7d..1fc5b2b 100644 --- a/src/net/tsz/afinal/bitmap/core/BitmapProcess.java +++ b/src/net/tsz/afinal/bitmap/core/BitmapProcess.java @@ -48,10 +48,7 @@ public Bitmap getBitmap(String url, BitmapDisplayConfig config) { mCache.addToDiskCache(url, data); } } - //在展示之前进行前置图形处理 - if(config.getBeforeDisplayProcess()!=null){ - bitmap =config.getBeforeDisplayProcess().process(bitmap); - } + return bitmap; } diff --git a/src/net/tsz/afinal/db/sqlite/CursorUtils.java b/src/net/tsz/afinal/db/sqlite/CursorUtils.java index 7e2a767..5381b4e 100644 --- a/src/net/tsz/afinal/db/sqlite/CursorUtils.java +++ b/src/net/tsz/afinal/db/sqlite/CursorUtils.java @@ -41,13 +41,19 @@ public static T getEntity(Cursor cursor, Class clazz,FinalDb db){ String column = cursor.getColumnName(i); Property property = table.propertyMap.get(column); - if(property!=null){ - property.setValue(entity, cursor.getString(i)); - }else{ - if(table.getId().getColumn().equals(column)){ - table.getId().setValue(entity, cursor.getString(i)); - } - } + //add by pwy 2013/12/04 防止因为一个值异常导致输出null实体 + try { + if(property!=null){ + property.setValue(entity, cursor.getString(i)); + }else{ + if(table.getId().getColumn().equals(column)){ + table.getId().setValue(entity, cursor.getString(i)); + } + } + }catch (Exception e){ + e.printStackTrace(); + } + } /** diff --git a/src/net/tsz/afinal/db/sqlite/ManyToOneLazyLoader.java b/src/net/tsz/afinal/db/sqlite/ManyToOneLazyLoader.java index 5bb32c9..1876ce7 100644 --- a/src/net/tsz/afinal/db/sqlite/ManyToOneLazyLoader.java +++ b/src/net/tsz/afinal/db/sqlite/ManyToOneLazyLoader.java @@ -2,9 +2,6 @@ import net.tsz.afinal.FinalDb; -import java.util.ArrayList; -import java.util.List; - /** * * 一对多延迟加载类 diff --git a/src/net/tsz/afinal/db/sqlite/OneToManyLazyLoader.java b/src/net/tsz/afinal/db/sqlite/OneToManyLazyLoader.java index 7eb9740..0adae2b 100644 --- a/src/net/tsz/afinal/db/sqlite/OneToManyLazyLoader.java +++ b/src/net/tsz/afinal/db/sqlite/OneToManyLazyLoader.java @@ -38,7 +38,7 @@ public synchronized List getList(){ } return entities; } - public void setList(List value){ + public synchronized void setList(List value){ entities = value; } diff --git a/src/net/tsz/afinal/db/sqlite/SqlBuilder.java b/src/net/tsz/afinal/db/sqlite/SqlBuilder.java index 971051c..08d14de 100644 --- a/src/net/tsz/afinal/db/sqlite/SqlBuilder.java +++ b/src/net/tsz/afinal/db/sqlite/SqlBuilder.java @@ -21,6 +21,7 @@ import android.text.TextUtils; +import net.tsz.afinal.annotation.sqlite.Index; import net.tsz.afinal.db.table.Id; import net.tsz.afinal.db.table.KeyValue; import net.tsz.afinal.db.table.ManyToOne; @@ -304,6 +305,7 @@ public static String getCreatTableSQL(Class clazz){ TableInfo table=TableInfo.get(clazz); Id id=table.getId(); + StringBuffer strIndexCreatorSQL = new StringBuffer(); StringBuffer strSQL = new StringBuffer(); strSQL.append("CREATE TABLE IF NOT EXISTS "); strSQL.append(table.getTableName()); @@ -318,15 +320,37 @@ public static String getCreatTableSQL(Class clazz){ Collection propertys = table.propertyMap.values(); for(Property property : propertys){ strSQL.append("\"").append(property.getColumn()); - strSQL.append("\","); + //add by pwy 2013/10/26 for 创建字段时指定数值字段类型,以免排序或查找时出错 + if(property.getDataType() == int.class || property.getDataType()==Integer.class){ + strSQL.append("\" ").append("INTEGER DEFAULT(0),"); + }else if(property.getDataType() == Double.class || property.getDataType()==double.class + ||property.getDataType() == Float.class || property.getDataType()==float.class){ + strSQL.append("\" ").append("REAL DEFAULT(0),"); + }else { + strSQL.append("\","); + } + //add by pwy 2013/11/4 for 创建索引 + if(property.getField().getAnnotation(Index.class)!=null){ + strIndexCreatorSQL.append("create index ") + .append(property.getColumn()+"_idx on ") + .append(table.getTableName()+"("+property.getColumn()+");"); + } } Collection manyToOnes = table.manyToOneMap.values(); for(ManyToOne manyToOne : manyToOnes){ - strSQL.append("\"").append(manyToOne.getColumn()).append("\","); + strSQL.append("\"").append(manyToOne.getColumn()); + if(manyToOne.getDataType() == int.class || manyToOne.getDataType()==Integer.class){ + strSQL.append("\" ").append("INTEGER DEFAULT(0),"); + }else if(manyToOne.getDataType() == Double.class || manyToOne.getDataType()==double.class + ||manyToOne.getDataType() == Float.class || manyToOne.getDataType()==float.class){ + strSQL.append("\" ").append("REAL DEFAULT(0),"); + }else { + strSQL.append("\","); + } } strSQL.deleteCharAt(strSQL.length() - 1); - strSQL.append(" )"); + strSQL.append(" );").append(strIndexCreatorSQL.toString()); return strSQL.toString(); } diff --git a/src/net/tsz/afinal/db/table/OneToMany.java b/src/net/tsz/afinal/db/table/OneToMany.java index a209a47..483be09 100644 --- a/src/net/tsz/afinal/db/table/OneToMany.java +++ b/src/net/tsz/afinal/db/table/OneToMany.java @@ -18,6 +18,9 @@ public class OneToMany extends Property{ private Class oneClass; + //add by pwy for lazyload时实现排序 + private String orderColumn; + private boolean isDesc; public Class getOneClass() { return oneClass; @@ -27,6 +30,19 @@ public void setOneClass(Class oneClass) { this.oneClass = oneClass; } - - + public String getOrderColumn(){ + return orderColumn; + } + public void setOrderColumn(String column){ + orderColumn = column; + } + + + public boolean isDesc() { + return isDesc; + } + + public void setDesc(boolean desc) { + isDesc = desc; + } } diff --git a/src/net/tsz/afinal/utils/ClassUtils.java b/src/net/tsz/afinal/utils/ClassUtils.java index d44c69e..afe2f06 100644 --- a/src/net/tsz/afinal/utils/ClassUtils.java +++ b/src/net/tsz/afinal/utils/ClassUtils.java @@ -252,7 +252,11 @@ public static List getOneToManyList(Class clazz) { otm.setColumn(FieldUtils.getColumnByField(f)); otm.setFieldName(f.getName()); - + //add by pwy 20131015 for 懒加载中嵌入排序 + net.tsz.afinal.annotation.sqlite.OneToMany oneToMany = f.getAnnotation(net.tsz.afinal.annotation.sqlite.OneToMany.class); + otm.setOrderColumn(oneToMany.orderColumn()); + otm.setDesc(oneToMany.orderDesc()); + //add end Type type = f.getGenericType(); if(type instanceof ParameterizedType){ From 988402fe813a34b67775aaa672d7c8d526b46863 Mon Sep 17 00:00:00 2001 From: lsjwzh Date: Tue, 17 Dec 2013 18:12:42 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E4=B8=8E=E4=B8=BB=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=90=88=E5=B9=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/net/tsz/afinal/FinalActivity.java | 188 +-- src/net/tsz/afinal/FinalDb.java | 1404 +++++++++-------- .../bitmap/core/SoftMemoryCacheImpl.java | 18 +- .../bitmap/download/SimpleDownloader.java | 181 ++- .../afinal/db/sqlite/ManyToOneLazyLoader.java | 3 + src/net/tsz/afinal/db/sqlite/SqlBuilder.java | 36 +- src/net/tsz/afinal/db/table/KeyValue.java | 5 +- src/net/tsz/afinal/db/table/Property.java | 27 +- src/net/tsz/afinal/utils/FieldUtils.java | 7 +- 9 files changed, 960 insertions(+), 909 deletions(-) diff --git a/src/net/tsz/afinal/FinalActivity.java b/src/net/tsz/afinal/FinalActivity.java index 6f665a7..52ddb71 100644 --- a/src/net/tsz/afinal/FinalActivity.java +++ b/src/net/tsz/afinal/FinalActivity.java @@ -21,169 +21,109 @@ import net.tsz.afinal.annotation.view.Select; import net.tsz.afinal.annotation.view.ViewInject; import android.app.Activity; -import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.widget.AbsListView; -public class FinalActivity extends Activity { +public abstract class FinalActivity extends Activity { - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - public void setContentView(int layoutResID) { super.setContentView(layoutResID); - FinalActivity.initInjectedView(this); + initView(); } public void setContentView(View view, LayoutParams params) { super.setContentView(view, params); - FinalActivity.initInjectedView(this); + initView(); } - public void setContentView(View view) { super.setContentView(view); - FinalActivity.initInjectedView(this); + initView(); } - /** - * 初始化Actvity中的注入属性 - * 可用于与其他框架合用(如ActionBarShelock) - *

- * *必须在setContentView之后调用: - *

-     * protected void onCreate(Bundle savedInstanceState) {
-     *  super.onCreate(savedInstanceState);
-     *   setContentView(view);
-     *   FinalActivity.initInjectedView(this);
-     * }
-     * 
- * @param sourceActivity - */ - public static void initInjectedView(Activity sourceActivity){ - initInjectedView(sourceActivity,sourceActivity.getWindow().getDecorView()); - } - - /** - * 初始化指定View中的注入属性 - * 可用于Fragment内使用InjectView

- * 示例:

- * 在onCreateView中: - *

-     * public View onCreateView(LayoutInflater inflater, ViewGroup container,
-     *      Bundle savedInstanceState) {
-     *  View viewRoot = inflater.inflate(R.layout.map_frame, container, false);
-     *  FinalActivity.initInjectedView(this,viewRoot);
-     * }
-     * 
- * @param sourceView - */ - public static void initInjectedView(Object injectedSource,View sourceView){ - Field[] fields = injectedSource.getClass().getDeclaredFields(); + private void initView(){ + Field[] fields = getClass().getDeclaredFields(); if(fields!=null && fields.length>0){ for(Field field : fields){ - ViewInject viewInject = field.getAnnotation(ViewInject.class); - if(viewInject!=null){ - int viewId = viewInject.id(); - try { - field.setAccessible(true); - /*当已经被赋值时,不在重复赋值,用于include,inflate情景下的viewinject组合*/ - if(field.get(injectedSource)==null){ - field.set(injectedSource,sourceView.findViewById(viewId)); - }else{ - continue; - } - } catch (Exception e) { - e.printStackTrace(); - } - - String clickMethod = viewInject.click(); - if(!TextUtils.isEmpty(clickMethod)) - setViewClickListener(injectedSource,field,clickMethod); + try { + field.setAccessible(true); - String longClickMethod = viewInject.longClick(); - if(!TextUtils.isEmpty(longClickMethod)) - setViewLongClickListener(injectedSource,field,longClickMethod); - - String itemClickMethod = viewInject.itemClick(); - if(!TextUtils.isEmpty(itemClickMethod)) - setItemClickListener(injectedSource,field,itemClickMethod); - - - String itemLongClickMethod = viewInject.itemLongClick(); - if(!TextUtils.isEmpty(itemLongClickMethod)) - setItemLongClickListener(injectedSource,field,itemLongClickMethod); - - Select select = viewInject.select(); - if(!TextUtils.isEmpty(select.selected())) - setViewSelectListener(injectedSource,field,select.selected(),select.noSelected()); + if(field.get(this)!= null ) + continue; + + ViewInject viewInject = field.getAnnotation(ViewInject.class); + if(viewInject!=null){ + + int viewId = viewInject.id(); + field.set(this,findViewById(viewId)); + setListener(field,viewInject.click(),Method.Click); + setListener(field,viewInject.longClick(),Method.LongClick); + setListener(field,viewInject.itemClick(),Method.ItemClick); + setListener(field,viewInject.itemLongClick(),Method.itemLongClick); + + Select select = viewInject.select(); + if(!TextUtils.isEmpty(select.selected())){ + setViewSelectListener(field,select.selected(),select.noSelected()); + } + + } + } catch (Exception e) { + e.printStackTrace(); } } } } - private static void setViewClickListener(Object injectedSource,Field field,String clickMethod){ - try { - Object obj = field.get(injectedSource); - if(obj instanceof View){ - ((View)obj).setOnClickListener(new EventListener(injectedSource).click(clickMethod)); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - private static void setViewLongClickListener(Object injectedSource,Field field,String clickMethod){ - try { - Object obj = field.get(injectedSource); - if(obj instanceof View){ - ((View)obj).setOnLongClickListener(new EventListener(injectedSource).longClick(clickMethod)); - } - } catch (Exception e) { - e.printStackTrace(); + private void setViewSelectListener(Field field,String select,String noSelect)throws Exception{ + Object obj = field.get(this); + if(obj instanceof View){ + ((AbsListView)obj).setOnItemSelectedListener(new EventListener(this).select(select).noSelect(noSelect)); } } - private static void setItemClickListener(Object injectedSource,Field field,String itemClickMethod){ - try { - Object obj = field.get(injectedSource); - if(obj instanceof AbsListView){ - ((AbsListView)obj).setOnItemClickListener(new EventListener(injectedSource).itemClick(itemClickMethod)); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - private static void setItemLongClickListener(Object injectedSource,Field field,String itemClickMethod){ - try { - Object obj = field.get(injectedSource); - if(obj instanceof AbsListView){ - ((AbsListView)obj).setOnItemLongClickListener(new EventListener(injectedSource).itemLongClick(itemClickMethod)); - } - } catch (Exception e) { - e.printStackTrace(); + private void setListener(Field field,String methodName,Method method)throws Exception{ + if(methodName == null || methodName.trim().length() == 0) + return; + + Object obj = field.get(this); + + switch (method) { + case Click: + if(obj instanceof View){ + ((View)obj).setOnClickListener(new EventListener(this).click(methodName)); + } + break; + case ItemClick: + if(obj instanceof AbsListView){ + ((AbsListView)obj).setOnItemClickListener(new EventListener(this).itemClick(methodName)); + } + break; + case LongClick: + if(obj instanceof View){ + ((View)obj).setOnLongClickListener(new EventListener(this).longClick(methodName)); + } + break; + case itemLongClick: + if(obj instanceof AbsListView){ + ((AbsListView)obj).setOnItemLongClickListener(new EventListener(this).itemLongClick(methodName)); + } + break; + default: + break; } } - private static void setViewSelectListener(Object injectedSource,Field field,String select,String noSelect){ - try { - Object obj = field.get(injectedSource); - if(obj instanceof View){ - ((AbsListView)obj).setOnItemSelectedListener(new EventListener(injectedSource).select(select).noSelect(noSelect)); - } - } catch (Exception e) { - e.printStackTrace(); - } + public enum Method{ + Click,LongClick,ItemClick,itemLongClick } - } diff --git a/src/net/tsz/afinal/FinalDb.java b/src/net/tsz/afinal/FinalDb.java index 488ea12..24efbd4 100644 --- a/src/net/tsz/afinal/FinalDb.java +++ b/src/net/tsz/afinal/FinalDb.java @@ -38,437 +38,490 @@ import android.content.Context; import android.database.Cursor; import android.database.SQLException; -import android.database.sqlite.SQLiteCursorDriver; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteOpenHelper; -import android.database.sqlite.SQLiteQuery; import android.util.Log; public class FinalDb { - - private static final String TAG = "FinalDb"; - - private static HashMap daoMap = new HashMap(); - - private SQLiteDatabase db; - private DaoConfig config; - - private FinalDb(DaoConfig config){ - if(config == null) - throw new DbException("daoConfig is null"); - if(config.getContext() == null) - throw new DbException("android context is null"); - if(config.isSaveOnSDCard()){ - this.db = createDbFileOnSDCard(config.getTargetDirectory(),config.getDbName(),config.getDbVersion(),config.getDbUpdateListener()); - }else{ - this.db = new SqliteDbHelper(config.getContext().getApplicationContext(), config.getDbName(), config.getDbVersion(),config.getDbUpdateListener()).getWritableDatabase(); - } - this.config = config; - } + private static final String TAG = "FinalDb"; + + private static HashMap daoMap = new HashMap(); + + private SQLiteDatabase db; + private DaoConfig config; + + private FinalDb(DaoConfig config) { + if (config == null) + throw new DbException("daoConfig is null"); + if (config.getContext() == null) + throw new DbException("android context is null"); + if (config.getTargetDirectory() != null + && config.getTargetDirectory().trim().length() > 0) { + this.db = createDbFileOnSDCard(config.getTargetDirectory(), + config.getDbName(),config.getDbVersion(), config.getDbUpdateListener()); + } else { + this.db = new SqliteDbHelper(config.getContext() + .getApplicationContext(), config.getDbName(), + config.getDbVersion(), config.getDbUpdateListener()) + .getWritableDatabase(); + } + this.config = config; + } + private synchronized static FinalDb getInstance(DaoConfig daoConfig) { + FinalDb dao = daoMap.get(daoConfig.getDbName()); + if (dao == null) { + dao = new FinalDb(daoConfig); + daoMap.put(daoConfig.getDbName(), dao); + } + return dao; + } /** - * 在SD卡的指定目录上创建文件 - * @param sdcardPath - * @param dbfilename + * 创建FinalDb + * + * @param context + */ + public static FinalDb create(Context context) { + DaoConfig config = new DaoConfig(); + config.setContext(context); + return create(config); + } + + /** + * 创建FinalDb + * + * @param context + * @param isDebug + * 是否是debug模式(debug模式进行数据库操作的时候将会打印sql语句) + */ + public static FinalDb create(Context context, boolean isDebug) { + DaoConfig config = new DaoConfig(); + config.setContext(context); + config.setDebug(isDebug); + return create(config); + + } + + /** + * 创建FinalDb + * + * @param context + * @param dbName + * 数据库名称 + */ + public static FinalDb create(Context context, String dbName) { + DaoConfig config = new DaoConfig(); + config.setContext(context); + config.setDbName(dbName); + return create(config); + } + + /** + * 创建 FinalDb + * + * @param context + * @param dbName + * 数据库名称 + * @param isDebug + * 是否为debug模式(debug模式进行数据库操作的时候将会打印sql语句) + */ + public static FinalDb create(Context context, String dbName, boolean isDebug) { + DaoConfig config = new DaoConfig(); + config.setContext(context); + config.setDbName(dbName); + config.setDebug(isDebug); + return create(config); + } + + /** + * 创建FinalDb + * + * @param context + * @param dbName + * 数据库名称 + */ + public static FinalDb create(Context context, String targetDirectory, + String dbName) { + DaoConfig config = new DaoConfig(); + config.setContext(context); + config.setDbName(dbName); + config.setTargetDirectory(targetDirectory); + return create(config); + } + + /** + * 创建 FinalDb + * + * @param context + * @param dbName + * 数据库名称 + * @param isDebug + * 是否为debug模式(debug模式进行数据库操作的时候将会打印sql语句) + */ + public static FinalDb create(Context context, String targetDirectory, + String dbName, boolean isDebug) { + DaoConfig config = new DaoConfig(); + config.setContext(context); + config.setTargetDirectory(targetDirectory); + config.setDbName(dbName); + config.setDebug(isDebug); + return create(config); + } + + /** + * 创建 FinalDb + * + * @param context + * 上下文 + * @param dbName + * 数据库名字 + * @param isDebug + * 是否是调试模式:调试模式会log出sql信息 + * @param dbVersion + * 数据库版本信息 + * @param dbUpdateListener + * 数据库升级监听器:如果监听器为null,升级的时候将会清空所所有的数据 * @return */ - private SQLiteDatabase createDbFileOnSDCard(String sdcardPath,String dbfilename, int dbVersion, DbUpdateListener dbUpdateListener){ - String dbPath=android.os.Environment.getExternalStorageDirectory() - .getAbsolutePath()+(sdcardPath==null||sdcardPath.length()==0?"":"/" +sdcardPath); - String[] dirs = sdcardPath.split("/"); - String pathCache =android.os.Environment.getExternalStorageDirectory() - .getAbsolutePath(); - for(String dir :dirs){ - if(dir.length()==0) - continue; - File dbp=new File(pathCache+"/"+dir); - if(!dbp.exists()){ - dbp.mkdir(); - pathCache = dbp.getAbsolutePath(); - } + public static FinalDb create(Context context, String dbName, + boolean isDebug, int dbVersion, DbUpdateListener dbUpdateListener) { + DaoConfig config = new DaoConfig(); + config.setContext(context); + config.setDbName(dbName); + config.setDebug(isDebug); + config.setDbVersion(dbVersion); + config.setDbUpdateListener(dbUpdateListener); + return create(config); + } + + /** + * + * @param context + * 上下文 + * @param targetDirectory + * db文件路径,可以配置为sdcard的路径 + * @param dbName + * 数据库名字 + * @param isDebug + * 是否是调试模式:调试模式会log出sql信息 + * @param dbVersion + * 数据库版本信息 + * @param dbUpdateListener 数据库升级监听器 + * :如果监听器为null,升级的时候将会清空所所有的数据 + * @return + */ + public static FinalDb create(Context context, String targetDirectory, + String dbName, boolean isDebug, int dbVersion, + DbUpdateListener dbUpdateListener) { + DaoConfig config = new DaoConfig(); + config.setContext(context); + config.setTargetDirectory(targetDirectory); + config.setDbName(dbName); + config.setDebug(isDebug); + config.setDbVersion(dbVersion); + config.setDbUpdateListener(dbUpdateListener); + return create(config); + } + + /** + * 创建FinalDb + * + * @param daoConfig + * @return + */ + public static FinalDb create(DaoConfig daoConfig) { + return getInstance(daoConfig); + } + + /** + * 保存数据库,速度要比save快 + * + * @param entity + */ + public void save(Object entity) { + checkTableExist(entity.getClass()); + exeSqlInfo(SqlBuilder.buildInsertSql(entity)); + } + + /** + * 保存数据到数据库
+ * 注意:
+ * 保存成功后,entity的主键将被赋值(或更新)为数据库的主键, 只针对自增长的id有效 + * + * @param entity + * 要保存的数据 + * @return ture: 保存成功 false:保存失败 + */ + public boolean saveBindId(Object entity) { + checkTableExist(entity.getClass()); + List entityKvList = SqlBuilder + .getSaveKeyValueListByEntity(entity); + if (entityKvList != null && entityKvList.size() > 0) { + TableInfo tf = TableInfo.get(entity.getClass()); + ContentValues cv = new ContentValues(); + insertContentValues(entityKvList, cv); + Long id = db.insert(tf.getTableName(), null, cv); + if (id == -1) + return false; + tf.getId().setValue(entity, id); + return true; } - File dbf=new File(dbPath+"/"+dbfilename); + return false; + } - //数据库文件是否创建成功 - boolean isFileCreateSuccess=false; - if(!dbf.exists()){ - try{ - isFileCreateSuccess=dbf.createNewFile(); + /** + * 把List数据存储到ContentValues + * + * @param list + * @param cv + */ + private void insertContentValues(List list, ContentValues cv) { + if (list != null && cv != null) { + for (KeyValue kv : list) { + cv.put(kv.getKey(), kv.getValue().toString()); } - catch(IOException ioex){ - throw new DbException("数据库文件创建失败",ioex); + } else { + Log.w(TAG, + "insertContentValues: List is empty or ContentValues is empty!"); + } + + } + + /** + * 更新数据 (主键ID必须不能为空) + * + * @param entity + */ + public void update(Object entity) { + checkTableExist(entity.getClass()); + exeSqlInfo(SqlBuilder.getUpdateSqlAsSqlInfo(entity)); + } + + /** + * 根据条件更新数据 + * + * @param entity + * @param strWhere + * 条件为空的时候,将会更新所有的数据 + */ + public void update(Object entity, String strWhere) { + checkTableExist(entity.getClass()); + exeSqlInfo(SqlBuilder.getUpdateSqlAsSqlInfo(entity, strWhere)); + } + + /** + * 删除数据 + * + * @param entity + * entity的主键不能为空 + */ + public void delete(Object entity) { + checkTableExist(entity.getClass()); + exeSqlInfo(SqlBuilder.buildDeleteSql(entity)); + } + + /** + * 根据主键删除数据 + * + * @param clazz + * 要删除的实体类 + * @param id + * 主键值 + */ + public void deleteById(Class clazz, Object id) { + checkTableExist(clazz); + exeSqlInfo(SqlBuilder.buildDeleteSql(clazz, id)); + } + + /** + * 根据条件删除数据 + * + * @param clazz + * @param strWhere + * 条件为空的时候 将会删除所有的数据 + */ + public void deleteByWhere(Class clazz, String strWhere) { + checkTableExist(clazz); + String sql = SqlBuilder.buildDeleteSql(clazz, strWhere); + debugSql(sql); + db.execSQL(sql); + } + + /** + * 删除表的所有数据 + * + * @param clazz + */ + public void deleteAll(Class clazz) { + checkTableExist(clazz); + String sql = SqlBuilder.buildDeleteSql(clazz, null); + debugSql(sql); + db.execSQL(sql); + } + + /** + * 删除指定的表 + * + * @param clazz + */ + public void dropTable(Class clazz) { + checkTableExist(clazz); + TableInfo table = TableInfo.get(clazz); + String sql = "DROP TABLE " + table.getTableName(); + debugSql(sql); + db.execSQL(sql); + } + + /** + * 删除所有数据表 + */ + public void dropDb() { + Cursor cursor = db.rawQuery( + "SELECT name FROM sqlite_master WHERE type ='table' AND name != 'sqlite_sequence'", null); + if (cursor != null) { + while (cursor.moveToNext()) { + db.execSQL("DROP TABLE " + cursor.getString(0)); } } - else{ - isFileCreateSuccess=true; - } - if(isFileCreateSuccess){ - //add by pwy 2013/11/14 增加数据库升级支持 - SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbf,null); - //目前只支持升级,不支持降级 - if(db.getVersion() T findById(Object id, Class clazz) { + checkTableExist(clazz); + SqlInfo sqlInfo = SqlBuilder.getSelectSqlAsSqlInfo(clazz, id); + if (sqlInfo != null) { + debugSql(sqlInfo.getSql()); + Cursor cursor = db.rawQuery(sqlInfo.getSql(), + sqlInfo.getBindArgsAsStringArray()); + try { + if (cursor.moveToNext()) { + return CursorUtils.getEntity(cursor, clazz, this); } + } catch (Exception e) { + e.printStackTrace(); + } finally { + cursor.close(); } - return db; } return null; } - - private synchronized static FinalDb getInstance(DaoConfig daoConfig) { - FinalDb dao = daoMap.get(daoConfig.getDbName()); - if(dao == null){ - dao = new FinalDb(daoConfig); - daoMap.put(daoConfig.getDbName(), dao); - } - return dao; - } - /** - * 在sd卡上创建FinalDb - * @param context - * @param targetDirectory 目标目录 + + /** + * 根据主键查找,同时查找“多对一”的数据(如果有多个“多对一”属性,则查找所有的“多对一”属性) + * + * @param id + * @param clazz */ - public static FinalDb createOnSDCard(Context context,String targetDirectory){ - DaoConfig config = new DaoConfig(); - config.setContext(context); - config.setSaveOnSDCard(true); - config.setTargetDirectory(targetDirectory); - return getInstance(config); - - } - /** - * 创建FinalDb - * @param context - */ - public static FinalDb create(Context context){ - DaoConfig config = new DaoConfig(); - config.setContext(context); - - return getInstance(config); - - } - - /** - * 创建FinalDb - * @param context - * @param isDebug 是否是debug模式(debug模式进行数据库操作的时候将会打印sql语句) - */ - public static FinalDb create(Context context,boolean isDebug){ - DaoConfig config = new DaoConfig(); - config.setContext(context); - config.setDebug(isDebug); - return getInstance(config); - - } - - /** - * 创建FinalDb - * @param context - * @param dbName 数据库名称 - */ - public static FinalDb create(Context context,String dbName){ - DaoConfig config = new DaoConfig(); - config.setContext(context); - config.setDbName(dbName); - - return getInstance(config); - } - - /** - * 创建 FinalDb - * @param context - * @param dbName 数据库名称 - * @param isDebug 是否为debug模式(debug模式进行数据库操作的时候将会打印sql语句) - */ - public static FinalDb create(Context context,String dbName,boolean isDebug){ - DaoConfig config = new DaoConfig(); - config.setContext(context); - config.setDbName(dbName); - config.setDebug(isDebug); - return getInstance(config); - } - - /** - * 创建 FinalDb - * @param context 上下文 - * @param dbName 数据库名字 - * @param isDebug 是否是调试模式:调试模式会log出sql信息 - * @param dbVersion 数据库版本信息 - * @param dbUpdateListener 数据库升级监听器:如果监听器为null,升级的时候将会清空所所有的数据 - * @return - */ - public static FinalDb create(Context context,String dbName,boolean isDebug,int dbVersion,DbUpdateListener dbUpdateListener){ - DaoConfig config = new DaoConfig(); - config.setContext(context); - config.setDbName(dbName); - config.setDebug(isDebug); - config.setDbVersion(dbVersion); - config.setDbUpdateListener(dbUpdateListener); - return getInstance(config); - } - - /** - * 创建FinalDb - * @param daoConfig - * @return - */ - public static FinalDb create(DaoConfig daoConfig){ - return getInstance(daoConfig); - } - - - - /** - * 保存数据库,速度要比save快 - * @param entity - */ - public void save(Object entity){ - checkTableExist(entity.getClass()); - exeSqlInfo(SqlBuilder.buildInsertSql(entity)); - } - - - /** - * 保存数据到数据库
- * 注意:
- * 保存成功后,entity的主键将被赋值(或更新)为数据库的主键, 只针对自增长的id有效 - * @param entity 要保存的数据 - * @return ture: 保存成功 false:保存失败 - */ - public boolean saveBindId(Object entity){ - checkTableExist(entity.getClass()); - List entityKvList = SqlBuilder.getSaveKeyValueListByEntity(entity); - if(entityKvList != null && entityKvList.size() > 0){ - TableInfo tf = TableInfo.get(entity.getClass()); - ContentValues cv = new ContentValues(); - insertContentValues(entityKvList,cv); - Long id = db.insert(tf.getTableName(), null, cv); - if(id == -1) - return false; - tf.getId().setValue(entity, id); - return true; - } - return false; - } - - /** - * 把List数据存储到ContentValues - * @param list - * @param cv - */ - private void insertContentValues(List list , ContentValues cv){ - if(list!=null && cv!=null){ - for(KeyValue kv : list){ - cv.put(kv.getKey(), kv.getValue().toString()); - } - }else{ - Log.w(TAG, "insertContentValues: List is empty or ContentValues is empty!"); - } - - } - - /** - * 更新数据 (主键ID必须不能为空) - * @param entity - */ - public void update(Object entity){ - checkTableExist(entity.getClass()); - exeSqlInfo(SqlBuilder.getUpdateSqlAsSqlInfo(entity)); - } - - /** - * 根据条件更新数据 - * @param entity - * @param strWhere 条件为空的时候,将会更新所有的数据 - */ - public void update(Object entity,String strWhere){ - checkTableExist(entity.getClass()); - exeSqlInfo(SqlBuilder.getUpdateSqlAsSqlInfo(entity, strWhere)); - } - - /** - * 删除数据 - * @param entity entity的主键不能为空 - */ - public void delete(Object entity) { - checkTableExist(entity.getClass()); - exeSqlInfo(SqlBuilder.buildDeleteSql(entity)); - } - - /** - * 根据主键删除数据 - * @param clazz 要删除的实体类 - * @param id 主键值 - */ - public void deleteById(Class clazz , Object id) { - checkTableExist(clazz); - exeSqlInfo(SqlBuilder.buildDeleteSql(clazz, id)); - } - - /** - * 根据条件删除数据 - * @param clazz - * @param strWhere 条件为空的时候 将会删除所有的数据 - */ - public void deleteByWhere(Class clazz , String strWhere ) { - checkTableExist(clazz); - String sql = SqlBuilder.buildDeleteSql(clazz, strWhere); - debugSql(sql); - db.execSQL(sql); - } - /** - * 删除所有数据表 - */ - public void dropDb() { - Cursor cursor = db.rawQuery("SELECT name FROM sqlite_master WHERE type ='table'", null); - if(cursor!=null){ - while(cursor.moveToNext()){ - //添加异常捕获.忽略删除所有表时出现的异常: - //table sqlite_sequence may not be dropped - try { - db.execSQL("DROP TABLE "+cursor.getString(0)); - } catch (SQLException e) { - Log.e(TAG, e.getMessage()); - } - } - } - if(cursor!=null){ - cursor.close(); - cursor=null; - } - } - - - private void exeSqlInfo(SqlInfo sqlInfo){ - if(sqlInfo!=null){ - debugSql(sqlInfo.getSql()); - db.execSQL(sqlInfo.getSql(),sqlInfo.getBindArgsAsArray()); - }else{ - Log.e(TAG, "sava error:sqlInfo is null"); - } - } - - /** - * 根据主键查找数据(默认不查询多对一或者一对多的关联数据) - * @param id - * @param clazz - */ - public T findById(Object id ,Class clazz){ - checkTableExist(clazz); - SqlInfo sqlInfo = SqlBuilder.getSelectSqlAsSqlInfo(clazz, id); - if(sqlInfo!=null){ - debugSql(sqlInfo.getSql()); - Cursor cursor = db.rawQuery(sqlInfo.getSql(), sqlInfo.getBindArgsAsStringArray()); - try { - if(cursor.moveToNext()){ - return CursorUtils.getEntity(cursor, clazz,this); - } - } catch (Exception e) { - e.printStackTrace(); - }finally{ - cursor.close(); - } - } - return null; - } - - /** - * 根据主键查找,同时查找“多对一”的数据(如果有多个“多对一”属性,则查找所有的“多对一”属性) - * @param id - * @param clazz - */ - public T findWithManyToOneById(Object id ,Class clazz){ - checkTableExist(clazz); - String sql = SqlBuilder.getSelectSQL(clazz, id); - debugSql(sql); - DbModel dbModel = findDbModelBySQL(sql); - if(dbModel!=null){ - T entity = CursorUtils.dbModel2Entity(dbModel, clazz); - return loadManyToOne(dbModel,entity,clazz); - } - - return null; - } - - - /** - * 根据条件查找,同时查找“多对一”的数据(只查找findClass中的类的数据) - * @param id - * @param clazz - * @param findClass 要查找的类 - */ - public T findWithManyToOneById(Object id ,Class clazz,Class ... findClass){ - checkTableExist(clazz); - String sql = SqlBuilder.getSelectSQL(clazz, id); - debugSql(sql); - DbModel dbModel = findDbModelBySQL(sql); - if(dbModel!=null){ - T entity = CursorUtils.dbModel2Entity(dbModel, clazz); - return loadManyToOne(dbModel,entity,clazz,findClass); - } - return null; - } - - /** - * 将entity中的“多对一”的数据填充满 - * 如果是懒加载填充,则dbModel参数可为null + public T findWithManyToOneById(Object id, Class clazz) { + checkTableExist(clazz); + String sql = SqlBuilder.getSelectSQL(clazz, id); + debugSql(sql); + DbModel dbModel = findDbModelBySQL(sql); + if (dbModel != null) { + T entity = CursorUtils.dbModel2Entity(dbModel, clazz); + return loadManyToOne(dbModel, entity, clazz); + } + + return null; + } + + /** + * 根据条件查找,同时查找“多对一”的数据(只查找findClass中的类的数据) + * + * @param id + * @param clazz + * @param findClass + * 要查找的类 + */ + public T findWithManyToOneById(Object id, Class clazz, + Class... findClass) { + checkTableExist(clazz); + String sql = SqlBuilder.getSelectSQL(clazz, id); + debugSql(sql); + DbModel dbModel = findDbModelBySQL(sql); + if (dbModel != null) { + T entity = CursorUtils.dbModel2Entity(dbModel, clazz); + return loadManyToOne(dbModel, entity, clazz, findClass); + } + return null; + } + + /** + * 将entity中的“多对一”的数据填充满 如果是懒加载填充,则dbModel参数可为null + * * @param clazz * @param entity * @param * @return */ - public T loadManyToOne(DbModel dbModel,T entity,Class clazz,Class ... findClass) { - if(entity!=null){ + public T loadManyToOne(DbModel dbModel, T entity, Class clazz, + Class... findClass) { + if (entity != null) { try { - Collection manys = TableInfo.get(clazz).manyToOneMap.values(); - for(ManyToOne many : manys){ + Collection manys = TableInfo.get(clazz).manyToOneMap + .values(); + for (ManyToOne many : manys) { Object id = null; - if(dbModel!=null){ + if (dbModel != null) { id = dbModel.get(many.getColumn()); - }else if(many.getValue(entity).getClass()== ManyToOneLazyLoader.class - &&many.getValue(entity)!=null){ - id = ((ManyToOneLazyLoader)many.getValue(entity)).getFieldValue(); + } else if (many.getValue(entity).getClass() == ManyToOneLazyLoader.class + && many.getValue(entity) != null) { + id = ((ManyToOneLazyLoader) many.getValue(entity)) + .getFieldValue(); } - if(id!=null){ + if (id != null) { boolean isFind = false; - if(findClass == null || findClass.length==0){ + if (findClass == null || findClass.length == 0) { isFind = true; } - for(Class mClass : findClass){ - if(many.getManyClass()==mClass){ + for (Class mClass : findClass) { + if (many.getManyClass() == mClass) { isFind = true; break; } } - if(isFind){ + if (isFind) { @SuppressWarnings("unchecked") - T manyEntity = (T) findById(Integer.valueOf(id.toString()), many.getManyClass()); - if(manyEntity!=null){ - if(many.getValue(entity).getClass()== ManyToOneLazyLoader.class){ - if(many.getValue(entity)==null){ - many.setValue(entity,new ManyToOneLazyLoader(entity,clazz,many.getManyClass(),this)); + T manyEntity = (T) findById( + Integer.valueOf(id.toString()), + many.getManyClass()); + if (manyEntity != null) { + if (many.getValue(entity).getClass() == ManyToOneLazyLoader.class) { + if (many.getValue(entity) == null) { + many.setValue( + entity, + new ManyToOneLazyLoader(entity, + clazz, + many.getManyClass(), + this)); } - ((ManyToOneLazyLoader)many.getValue(entity)).set(manyEntity); - }else{ + ((ManyToOneLazyLoader) many + .getValue(entity)).set(manyEntity); + } else { many.setValue(entity, manyEntity); } @@ -482,45 +535,46 @@ public T loadManyToOne(DbModel dbModel,T entity,Class clazz,Class ... } return entity; } - - /** - * 根据主键查找,同时查找“一对多”的数据(如果有多个“一对多”属性,则查找所有的一对多”属性) - * @param id - * @param clazz - */ - public T findWithOneToManyById(Object id ,Class clazz){ - checkTableExist(clazz); - String sql = SqlBuilder.getSelectSQL(clazz, id); - debugSql(sql); - DbModel dbModel = findDbModelBySQL(sql); - if(dbModel!=null){ - T entity = CursorUtils.dbModel2Entity(dbModel, clazz); - return loadOneToMany(entity,clazz); - } - - return null; - } - - - - /** - * 根据主键查找,同时查找“一对多”的数据(只查找findClass中的“一对多”) - * @param id - * @param clazz - * @param findClass - */ - public T findWithOneToManyById(Object id ,Class clazz,Class ... findClass){ - checkTableExist(clazz); - String sql = SqlBuilder.getSelectSQL(clazz, id); - debugSql(sql); - DbModel dbModel = findDbModelBySQL(sql); - if(dbModel!=null){ - T entity = CursorUtils.dbModel2Entity(dbModel, clazz); - return loadOneToMany(entity,clazz,findClass); - } - - return null; - } + + /** + * 根据主键查找,同时查找“一对多”的数据(如果有多个“一对多”属性,则查找所有的一对多”属性) + * + * @param id + * @param clazz + */ + public T findWithOneToManyById(Object id, Class clazz) { + checkTableExist(clazz); + String sql = SqlBuilder.getSelectSQL(clazz, id); + debugSql(sql); + DbModel dbModel = findDbModelBySQL(sql); + if (dbModel != null) { + T entity = CursorUtils.dbModel2Entity(dbModel, clazz); + return loadOneToMany(entity, clazz); + } + + return null; + } + + /** + * 根据主键查找,同时查找“一对多”的数据(只查找findClass中的“一对多”) + * + * @param id + * @param clazz + * @param findClass + */ + public T findWithOneToManyById(Object id, Class clazz, + Class... findClass) { + checkTableExist(clazz); + String sql = SqlBuilder.getSelectSQL(clazz, id); + debugSql(sql); + DbModel dbModel = findDbModelBySQL(sql); + if (dbModel != null) { + T entity = CursorUtils.dbModel2Entity(dbModel, clazz); + return loadOneToMany(entity, clazz, findClass); + } + + return null; + } /** * 将entity中的“一对多”的数据填充满 @@ -549,9 +603,9 @@ public T loadOneToMany(T entity ,Class clazz,Class ... findClass){ if(isFind){ //add by pwy 20131015 for 懒加载排序 String strWhere = "(" + one.getColumn()+"='"+id+"' or "+one.getColumn()+"="+id+")"+ - ((one.getOrderColumn()!=null&&one.getOrderColumn().length()>0) - ?" order by "+one.getOrderColumn()+ (one.isDesc()?" desc":" asc") - :""); + ((one.getOrderColumn()!=null&&one.getOrderColumn().length()>0) + ?" order by "+one.getOrderColumn()+ (one.isDesc()?" desc":" asc") + :""); List list = findAllByWhere(one.getOneClass(), strWhere); if(list!=null){ /*如果是OneToManyLazyLoader泛型,则执行灌入懒加载数据*/ @@ -571,206 +625,221 @@ public T loadOneToMany(T entity ,Class clazz,Class ... findClass){ return entity; } + /** + * 查找所有的数据 + * + * @param clazz + */ + public List findAll(Class clazz) { + checkTableExist(clazz); + return findAllBySql(clazz, SqlBuilder.getSelectSQL(clazz)); + } + + /** + * 查找所有数据 + * + * @param clazz + * @param orderBy + * 排序的字段 + */ + public List findAll(Class clazz, String orderBy) { + checkTableExist(clazz); + return findAllBySql(clazz, SqlBuilder.getSelectSQL(clazz) + + " ORDER BY " + orderBy); + } + + /** + * 根据条件查找所有数据 + * + * @param clazz + * @param strWhere + * 条件为空的时候查找所有数据 + */ + public List findAllByWhere(Class clazz, String strWhere) { + checkTableExist(clazz); + return findAllBySql(clazz, + SqlBuilder.getSelectSQLByWhere(clazz, strWhere)); + } + + /** + * 根据条件查找所有数据 + * + * @param clazz + * @param strWhere + * 条件为空的时候查找所有数据 + * @param orderBy + * 排序字段 + */ + public List findAllByWhere(Class clazz, String strWhere, + String orderBy) { + checkTableExist(clazz); + return findAllBySql(clazz, + SqlBuilder.getSelectSQLByWhere(clazz, strWhere) + " ORDER BY " + + orderBy); + } /** - * 查找所有的数据 - * @param clazz - */ - public List findAll(Class clazz){ - checkTableExist(clazz); - return findAllBySql(clazz,SqlBuilder.getSelectSQL(clazz)); - } - - /** - * 查找所有数据 - * @param clazz - * @param orderBy 排序的字段 - */ - public List findAll(Class clazz,String orderBy){ - checkTableExist(clazz); - return findAllBySql(clazz,SqlBuilder.getSelectSQL(clazz)+" ORDER BY "+orderBy); - } - - /** - * 根据条件查找所有数据 - * @param clazz - * @param strWhere 条件为空的时候查找所有数据 - */ - public List findAllByWhere(Class clazz,String strWhere){ - checkTableExist(clazz); - return findAllBySql(clazz,SqlBuilder.getSelectSQLByWhere(clazz,strWhere)); - } - - /** - * 根据条件查找所有数据 - * @param clazz - * @param strWhere 条件为空的时候查找所有数据 - * @param orderBy 排序字段 - */ - public List findAllByWhere(Class clazz,String strWhere,String orderBy){ - checkTableExist(clazz); - return findAllBySql(clazz,SqlBuilder.getSelectSQLByWhere(clazz,strWhere)+" ORDER BY "+orderBy); - } - - /** - * 根据条件查找所有数据 - * @param clazz - * @param strSQL - */ - private List findAllBySql(Class clazz,String strSQL){ - checkTableExist(clazz); - debugSql(strSQL); - Cursor cursor = db.rawQuery(strSQL, null); - try { - List list = new ArrayList(); - while(cursor.moveToNext()){ - T t = CursorUtils.getEntity(cursor, clazz,this); - list.add(t); - } - return list; - } catch (Exception e) { - e.printStackTrace(); - }finally{ - if(cursor!=null) - cursor.close(); - cursor=null; - } - return null; - } - - - - /** - * 根据sql语句查找数据,这个一般用于数据统计 - * @param strSQL - */ - public DbModel findDbModelBySQL(String strSQL){ - debugSql(strSQL); - Cursor cursor = db.rawQuery(strSQL,null); - try { - if(cursor.moveToNext()){ - return CursorUtils.getDbModel(cursor); - } - } catch (Exception e) { - e.printStackTrace(); - }finally{ - cursor.close(); - } - return null; - } - - public List findDbModelListBySQL(String strSQL){ - debugSql(strSQL); - Cursor cursor = db.rawQuery(strSQL,null); - List dbModelList = new ArrayList(); - try { - while(cursor.moveToNext()){ - dbModelList.add(CursorUtils.getDbModel(cursor)); - } - } catch (Exception e) { - e.printStackTrace(); - }finally{ - cursor.close(); - } - return dbModelList; - } - - - - public void checkTableExist(Class clazz){ - if(!tableIsExist(TableInfo.get(clazz))){ - String sql = SqlBuilder.getCreatTableSQL(clazz); - debugSql(sql); - db.execSQL(sql); - } - } - - - private boolean tableIsExist(TableInfo table){ - if(table.isCheckDatabese()) - return true; - + * 根据条件查找所有数据 + * + * @param clazz + * @param strSQL + */ + private List findAllBySql(Class clazz, String strSQL) { + checkTableExist(clazz); + debugSql(strSQL); + Cursor cursor = db.rawQuery(strSQL, null); + try { + List list = new ArrayList(); + while (cursor.moveToNext()) { + T t = CursorUtils.getEntity(cursor, clazz, this); + list.add(t); + } + return list; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (cursor != null) + cursor.close(); + cursor = null; + } + return null; + } + + /** + * 根据sql语句查找数据,这个一般用于数据统计 + * + * @param strSQL + */ + public DbModel findDbModelBySQL(String strSQL) { + debugSql(strSQL); + Cursor cursor = db.rawQuery(strSQL, null); + try { + if (cursor.moveToNext()) { + return CursorUtils.getDbModel(cursor); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + cursor.close(); + } + return null; + } + + public List findDbModelListBySQL(String strSQL) { + debugSql(strSQL); + Cursor cursor = db.rawQuery(strSQL, null); + List dbModelList = new ArrayList(); + try { + while (cursor.moveToNext()) { + dbModelList.add(CursorUtils.getDbModel(cursor)); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + cursor.close(); + } + return dbModelList; + } + + private void checkTableExist(Class clazz) { + if (!tableIsExist(TableInfo.get(clazz))) { + String sql = SqlBuilder.getCreatTableSQL(clazz); + debugSql(sql); + db.execSQL(sql); + } + } + + private boolean tableIsExist(TableInfo table) { + if (table.isCheckDatabese()) + return true; + Cursor cursor = null; try { - String sql = "SELECT COUNT(*) AS c FROM sqlite_master WHERE type ='table' AND name ='"+table.getTableName()+"' "; - debugSql(sql); - cursor = db.rawQuery(sql, null); - if(cursor!=null && cursor.moveToNext()){ - int count = cursor.getInt(0); - if(count>0){ - table.setCheckDatabese(true); - return true; - } + String sql = "SELECT COUNT(*) AS c FROM sqlite_master WHERE type ='table' AND name ='" + + table.getTableName() + "' "; + debugSql(sql); + cursor = db.rawQuery(sql, null); + if (cursor != null && cursor.moveToNext()) { + int count = cursor.getInt(0); + if (count > 0) { + table.setCheckDatabese(true); + return true; } - + } + } catch (Exception e) { - e.printStackTrace(); - }finally{ - if(cursor!=null) - cursor.close(); - cursor=null; + e.printStackTrace(); + } finally { + if (cursor != null) + cursor.close(); + cursor = null; } - + return false; - } - - - private void debugSql(String sql){ - if(config!=null && config.isDebug()) - android.util.Log.d("Debug SQL", ">>>>>> "+sql); - } - - - - - public static class DaoConfig{ - private Context mContext = null; //android上下文 - private String mDbName = "afinal.db"; //数据库名字 - private int dbVersion = 1; //数据库版本 - private boolean debug = true; //是否是调试模式(调试模式 增删改查的时候显示SQL语句) - private DbUpdateListener dbUpdateListener; - private boolean saveOnSDCard = false;//是否保存到SD卡 - private String targetDirectory;//数据库文件在sd卡中的目录 - - public Context getContext() { - return mContext; - } - public void setContext(Context context) { - this.mContext = context; - } - public String getDbName() { - return mDbName; - } - public void setDbName(String dbName) { - this.mDbName = dbName; - } - public int getDbVersion() { - return dbVersion; - } - public void setDbVersion(int dbVersion) { - this.dbVersion = dbVersion; - } - public boolean isDebug() { - return debug; - } - public void setDebug(boolean debug) { - this.debug = debug; - } - public DbUpdateListener getDbUpdateListener() { - return dbUpdateListener; - } - public void setDbUpdateListener(DbUpdateListener dbUpdateListener) { - this.dbUpdateListener = dbUpdateListener; - } - - public boolean isSaveOnSDCard() { - return saveOnSDCard; - } - - public void setSaveOnSDCard(boolean saveOnSDCard) { - this.saveOnSDCard = saveOnSDCard; + } + + private void debugSql(String sql) { + if (config != null && config.isDebug()) + android.util.Log.d("Debug SQL", ">>>>>> " + sql); + } + + public static class DaoConfig { + private Context mContext = null; // android上下文 + private String mDbName = "afinal.db"; // 数据库名字 + private int dbVersion = 1; // 数据库版本 + private boolean debug = true; // 是否是调试模式(调试模式 增删改查的时候显示SQL语句) + private DbUpdateListener dbUpdateListener; + // private boolean saveOnSDCard = false;//是否保存到SD卡 + private String targetDirectory;// 数据库文件在sd卡中的目录 + + public Context getContext() { + return mContext; + } + + public void setContext(Context context) { + this.mContext = context; + } + + public String getDbName() { + return mDbName; + } + + public void setDbName(String dbName) { + this.mDbName = dbName; + } + + public int getDbVersion() { + return dbVersion; + } + + public void setDbVersion(int dbVersion) { + this.dbVersion = dbVersion; + } + + public boolean isDebug() { + return debug; + } + + public void setDebug(boolean debug) { + this.debug = debug; + } + + public DbUpdateListener getDbUpdateListener() { + return dbUpdateListener; + } + + public void setDbUpdateListener(DbUpdateListener dbUpdateListener) { + this.dbUpdateListener = dbUpdateListener; } + // public boolean isSaveOnSDCard() { + // return saveOnSDCard; + // } + // + // public void setSaveOnSDCard(boolean saveOnSDCard) { + // this.saveOnSDCard = saveOnSDCard; + // } + public String getTargetDirectory() { return targetDirectory; } @@ -779,31 +848,78 @@ public void setTargetDirectory(String targetDirectory) { this.targetDirectory = targetDirectory; } } - - - class SqliteDbHelper extends SQLiteOpenHelper { - - private DbUpdateListener mDbUpdateListener; - public SqliteDbHelper(Context context, String name,int version, DbUpdateListener dbUpdateListener) { - super(context, name, null, version); - this.mDbUpdateListener = dbUpdateListener; - } - - public void onCreate(SQLiteDatabase db) { - } - - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - if(mDbUpdateListener!=null){ - mDbUpdateListener.onUpgrade(db, oldVersion, newVersion); - }else{ //清空所有的数据信息 - dropDb(); - } - } - - } - - public interface DbUpdateListener{ - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion); - } + + /** + * 在SD卡的指定目录上创建文件 + * + * @param sdcardPath + * @param dbfilename + * @return + */ + private SQLiteDatabase createDbFileOnSDCard(String sdcardPath, + String dbfilename, int dbVersion, DbUpdateListener dbUpdateListener) { + File dbf = new File(sdcardPath, dbfilename); + SQLiteDatabase retDb = null; + if (!dbf.exists()) { + try { + if (dbf.createNewFile()) { + retDb = SQLiteDatabase.openOrCreateDatabase(dbf, null); + } + } catch (IOException ioex) { + throw new DbException("数据库文件创建失败", ioex); + } + } else { + retDb = SQLiteDatabase.openOrCreateDatabase(dbf, null); + } + //add by pwy 2013/11/14 增加数据库升级支持 + //目前只支持升级,不支持降级 + if(retDb.getVersion()> mMemoryCache; + private final HashMap> mMemoryCache; public SoftMemoryCacheImpl(int size) { - mMemoryCache = new LruMemoryCache>(size) { - @Override - protected int sizeOf(String key, SoftReference sBitmap) { - final Bitmap bitmap = sBitmap==null ? null : sBitmap.get(); - if(bitmap == null) - return 1; - return Utils.getBitmapSize(bitmap); - } - }; + + mMemoryCache = new HashMap>(); } @Override @@ -53,7 +45,7 @@ public Bitmap get(String key) { @Override public void evictAll() { - mMemoryCache.evictAll(); + mMemoryCache.clear(); } @Override diff --git a/src/net/tsz/afinal/bitmap/download/SimpleDownloader.java b/src/net/tsz/afinal/bitmap/download/SimpleDownloader.java index beeba19..ce4c6c0 100644 --- a/src/net/tsz/afinal/bitmap/download/SimpleDownloader.java +++ b/src/net/tsz/afinal/bitmap/download/SimpleDownloader.java @@ -19,7 +19,7 @@ import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.FileReader; +import java.io.FileInputStream; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; @@ -31,52 +31,67 @@ import android.util.Log; /** - * @title 根据 图片url地址下载图片 可以是本地和网络 - * @author 杨福海(michael) www.yangfuhai.com + * @title 根据 图片url地址下载图片 可以是本地和网络 + * @author 杨福海(michael) www.yangfuhai.com */ -public class SimpleDownloader implements Downloader{ - - private static final String TAG = "SimpleHttpDownloader"; - private static final int IO_BUFFER_SIZE = 8 * 1024; //8k - - - public byte[] download(String urlString) { - if(urlString == null) - return null; - - if(urlString.trim().toLowerCase().startsWith("http")){ - return getFromHttp(urlString); - }else if(urlString.trim().toLowerCase().startsWith("file")){ - try { - return getFromFile(new URI(urlString).getPath()); - } catch (URISyntaxException e) { - e.printStackTrace(); - } - }else if(urlString.trim().toLowerCase().startsWith("/")){ - return getFromFile(urlString); - } - - return null; - } +public class SimpleDownloader implements Downloader { + private static final String TAG = SimpleDownloader.class.getSimpleName(); + private static final int IO_BUFFER_SIZE = 8 * 1024; // 8k - private byte[] getFromFile(String urlString) { + public byte[] download (String urlString){ + if (urlString == null) + return null; + + if (urlString.trim().toLowerCase().startsWith("http")) { + return getFromHttp(urlString); + }else if(urlString.trim().toLowerCase().startsWith("file:")){ + try { + File f = new File(new URI(urlString)); + if (f.exists() && f.canRead()) { + return getFromFile(f); + } + } catch (URISyntaxException e) { + Log.e(TAG, "Error in read from file - " + urlString + " : " + e); + } + }else{ + File f = new File(urlString); + if (f.exists() && f.canRead()) { + return getFromFile(f); + } + } + + return null; + } + + private byte[] getFromFile(File file) { + if(file == null) return null; + + FileInputStream fis = null; try { + fis = new FileInputStream(file); ByteArrayOutputStream baos = new ByteArrayOutputStream(); - FileReader f = new FileReader(new File(urlString)); - int b; - while ((b = f.read()) != -1) { - baos.write(b); - } - return baos.toByteArray(); + int len = 0; + byte[] buffer = new byte[1024]; + while ((len = fis.read(buffer)) != -1) { + baos.write(buffer, 0, len); + } + return baos.toByteArray(); } catch (Exception e) { - e.printStackTrace(); + Log.e(TAG, "Error in read from file - " + file + " : " + e); + } finally { + if (fis != null) { + try { + fis.close(); + fis = null; + } catch (IOException e) { + // do nothing + } + } } - + return null; } - - private byte[] getFromHttp(String urlString) { HttpURLConnection urlConnection = null; @@ -84,56 +99,56 @@ private byte[] getFromHttp(String urlString) { FlushedInputStream in = null; try { - final URL url = new URL(urlString); - urlConnection = (HttpURLConnection) url.openConnection(); - in = new FlushedInputStream(new BufferedInputStream(urlConnection.getInputStream(), IO_BUFFER_SIZE)); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int b; - while ((b = in.read()) != -1) { - baos.write(b); - } - return baos.toByteArray(); + final URL url = new URL(urlString); + urlConnection = (HttpURLConnection) url.openConnection(); + in = new FlushedInputStream(new BufferedInputStream(urlConnection.getInputStream(), IO_BUFFER_SIZE)); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int b; + while ((b = in.read()) != -1) { + baos.write(b); + } + return baos.toByteArray(); } catch (final IOException e) { - Log.e(TAG, "Error in downloadBitmap - "+urlString +" : " + e); + Log.e(TAG, "Error in downloadBitmap - " + urlString + " : " + e); } finally { - if (urlConnection != null) { - urlConnection.disconnect(); - } - try { - if (out != null) { - out.close(); - } - if (in != null) { - in.close(); - } - } catch (final IOException e) {} + if (urlConnection != null) { + urlConnection.disconnect(); + } + try { + if (out != null) { + out.close(); + } + if (in != null) { + in.close(); + } + } catch (final IOException e) { + } } return null; } - - public class FlushedInputStream extends FilterInputStream { - - public FlushedInputStream(InputStream inputStream) { - super(inputStream); - } + + public class FlushedInputStream extends FilterInputStream { + public FlushedInputStream(InputStream inputStream) { + super(inputStream); + } - @Override - public long skip(long n) throws IOException { - long totalBytesSkipped = 0L; - while (totalBytesSkipped < n) { - long bytesSkipped = in.skip(n - totalBytesSkipped); - if (bytesSkipped == 0L) { - int by_te = read(); - if (by_te < 0) { - break; // we reached EOF - } else { - bytesSkipped = 1; // we read one byte - } - } - totalBytesSkipped += bytesSkipped; - } - return totalBytesSkipped; - } - } + @Override + public long skip(long n) throws IOException { + long totalBytesSkipped = 0L; + while (totalBytesSkipped < n) { + long bytesSkipped = in.skip(n - totalBytesSkipped); + if (bytesSkipped == 0L) { + int by_te = read(); + if (by_te < 0) { + break; // we reached EOF + } else { + bytesSkipped = 1; // we read one byte + } + } + totalBytesSkipped += bytesSkipped; + } + return totalBytesSkipped; + } + } } diff --git a/src/net/tsz/afinal/db/sqlite/ManyToOneLazyLoader.java b/src/net/tsz/afinal/db/sqlite/ManyToOneLazyLoader.java index 1876ce7..5bb32c9 100644 --- a/src/net/tsz/afinal/db/sqlite/ManyToOneLazyLoader.java +++ b/src/net/tsz/afinal/db/sqlite/ManyToOneLazyLoader.java @@ -2,6 +2,9 @@ import net.tsz.afinal.FinalDb; +import java.util.ArrayList; +import java.util.List; + /** * * 一对多延迟加载类 diff --git a/src/net/tsz/afinal/db/sqlite/SqlBuilder.java b/src/net/tsz/afinal/db/sqlite/SqlBuilder.java index 08d14de..1d3a1db 100644 --- a/src/net/tsz/afinal/db/sqlite/SqlBuilder.java +++ b/src/net/tsz/afinal/db/sqlite/SqlBuilder.java @@ -312,23 +312,26 @@ public static String getCreatTableSQL(Class clazz){ strSQL.append(" ( "); Class primaryClazz = id.getDataType(); - if( primaryClazz == int.class || primaryClazz==Integer.class) - strSQL.append("\"").append(id.getColumn()).append("\" ").append("INTEGER PRIMARY KEY AUTOINCREMENT,"); - else - strSQL.append("\"").append(id.getColumn()).append("\" ").append("TEXT PRIMARY KEY,"); - + if( primaryClazz == int.class || primaryClazz==Integer.class + || primaryClazz == long.class || primaryClazz == Long.class){ + strSQL.append(id.getColumn()).append(" INTEGER PRIMARY KEY AUTOINCREMENT,"); + }else{ + strSQL.append(id.getColumn()).append(" TEXT PRIMARY KEY,"); + } Collection propertys = table.propertyMap.values(); for(Property property : propertys){ - strSQL.append("\"").append(property.getColumn()); - //add by pwy 2013/10/26 for 创建字段时指定数值字段类型,以免排序或查找时出错 - if(property.getDataType() == int.class || property.getDataType()==Integer.class){ - strSQL.append("\" ").append("INTEGER DEFAULT(0),"); - }else if(property.getDataType() == Double.class || property.getDataType()==double.class - ||property.getDataType() == Float.class || property.getDataType()==float.class){ - strSQL.append("\" ").append("REAL DEFAULT(0),"); - }else { - strSQL.append("\","); - } + strSQL.append(property.getColumn()); + Class dataType = property.getDataType(); + if( dataType== int.class || dataType == Integer.class + || dataType == long.class || dataType == Long.class){ + strSQL.append(" INTEGER"); + }else if(dataType == float.class ||dataType == Float.class + ||dataType == double.class || dataType == Double.class){ + strSQL.append(" REAL"); + }else if (dataType == boolean.class || dataType == Boolean.class) { + strSQL.append(" NUMERIC"); + } + strSQL.append(","); //add by pwy 2013/11/4 for 创建索引 if(property.getField().getAnnotation(Index.class)!=null){ strIndexCreatorSQL.append("create index ") @@ -340,7 +343,8 @@ public static String getCreatTableSQL(Class clazz){ Collection manyToOnes = table.manyToOneMap.values(); for(ManyToOne manyToOne : manyToOnes){ strSQL.append("\"").append(manyToOne.getColumn()); - if(manyToOne.getDataType() == int.class || manyToOne.getDataType()==Integer.class){ + if(manyToOne.getDataType() == int.class || manyToOne.getDataType()==Integer.class +|| manyToOne.getDataType() == long.class || manyToOne.getDataType() == Long.class){ strSQL.append("\" ").append("INTEGER DEFAULT(0),"); }else if(manyToOne.getDataType() == Double.class || manyToOne.getDataType()==double.class ||manyToOne.getDataType() == Float.class || manyToOne.getDataType()==float.class){ diff --git a/src/net/tsz/afinal/db/table/KeyValue.java b/src/net/tsz/afinal/db/table/KeyValue.java index 9e885ec..ac4e270 100644 --- a/src/net/tsz/afinal/db/table/KeyValue.java +++ b/src/net/tsz/afinal/db/table/KeyValue.java @@ -15,7 +15,7 @@ */ package net.tsz.afinal.db.table; -import java.text.SimpleDateFormat; +import net.tsz.afinal.utils.FieldUtils; public class KeyValue { private String key; @@ -36,10 +36,9 @@ public String getKey() { public void setKey(String key) { this.key = key; } - private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); public Object getValue() { if(value instanceof java.util.Date || value instanceof java.sql.Date){ - return sdf.format(value); + return FieldUtils.SDF.format(value); } return value; } diff --git a/src/net/tsz/afinal/db/table/Property.java b/src/net/tsz/afinal/db/table/Property.java index 26a99cc..bd7e70c 100644 --- a/src/net/tsz/afinal/db/table/Property.java +++ b/src/net/tsz/afinal/db/table/Property.java @@ -15,14 +15,12 @@ */ package net.tsz.afinal.db.table; -import android.annotation.SuppressLint; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.Date; +import net.tsz.afinal.utils.FieldUtils; + /** * @title 属性 * @description 【非主键】的【基本数据类型】 都是属性 @@ -55,7 +53,7 @@ public void setValue(Object receiver , Object value){ } else if (dataType == long.class || dataType == Long.class) { set.invoke(receiver, value == null ? (Long) null: Long.parseLong(value.toString())); } else if (dataType == java.util.Date.class || dataType == java.sql.Date.class) { - set.invoke(receiver, value == null ? (Date) null: stringToDateTime(value.toString())); + set.invoke(receiver, value == null ? (Date) null: FieldUtils.stringToDateTime(value.toString())); } else if (dataType == boolean.class || dataType == Boolean.class) { set.invoke(receiver, value == null ? (Boolean) null: "1".equals(value.toString())); } else { @@ -85,24 +83,7 @@ public T getValue(Object obj){ if(obj != null && get != null) { try { return (T)get.invoke(obj); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } - } - return null; - } - - @SuppressLint("SimpleDateFormat") - private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private static Date stringToDateTime(String strDate) { - if (strDate != null) { - try { - return sdf.parse(strDate); - } catch (ParseException e) { + } catch (Exception e) { e.printStackTrace(); } } diff --git a/src/net/tsz/afinal/utils/FieldUtils.java b/src/net/tsz/afinal/utils/FieldUtils.java index 513b94b..43cd31e 100644 --- a/src/net/tsz/afinal/utils/FieldUtils.java +++ b/src/net/tsz/afinal/utils/FieldUtils.java @@ -37,6 +37,8 @@ * @created 2012-10-10 */ public class FieldUtils { + public static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static Method getFieldGetMethod(Class clazz, Field f) { String fn = f.getName(); Method m = null; @@ -337,11 +339,10 @@ public static boolean isBaseDateType(Field field){ clazz.isPrimitive(); } - private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private static Date stringToDateTime(String strDate) { + public static Date stringToDateTime(String strDate) { if (strDate != null) { try { - return sdf.parse(strDate); + return SDF.parse(strDate); } catch (ParseException e) { e.printStackTrace(); } From 9820a068f74714e0b2db150444d50b2a0929dbe6 Mon Sep 17 00:00:00 2001 From: lsjwzh Date: Thu, 26 Dec 2013 11:11:47 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=9C=80=E6=96=B0?= =?UTF-8?q?=E7=9A=84Afinal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/net/tsz/afinal/FinalActivity.java | 256 ++++++++++++++++---------- src/net/tsz/afinal/FinalDb.java | 6 +- 2 files changed, 163 insertions(+), 99 deletions(-) diff --git a/src/net/tsz/afinal/FinalActivity.java b/src/net/tsz/afinal/FinalActivity.java index 52ddb71..2207f09 100644 --- a/src/net/tsz/afinal/FinalActivity.java +++ b/src/net/tsz/afinal/FinalActivity.java @@ -21,6 +21,7 @@ import net.tsz.afinal.annotation.view.Select; import net.tsz.afinal.annotation.view.ViewInject; import android.app.Activity; +import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.view.ViewGroup.LayoutParams; @@ -28,102 +29,161 @@ public abstract class FinalActivity extends Activity { + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } - public void setContentView(int layoutResID) { - super.setContentView(layoutResID); - initView(); - } - - - public void setContentView(View view, LayoutParams params) { - super.setContentView(view, params); - initView(); - } - - - public void setContentView(View view) { - super.setContentView(view); - initView(); - } - - private void initView(){ - Field[] fields = getClass().getDeclaredFields(); - if(fields!=null && fields.length>0){ - for(Field field : fields){ - try { - field.setAccessible(true); - - if(field.get(this)!= null ) - continue; - - ViewInject viewInject = field.getAnnotation(ViewInject.class); - if(viewInject!=null){ - - int viewId = viewInject.id(); - field.set(this,findViewById(viewId)); - - setListener(field,viewInject.click(),Method.Click); - setListener(field,viewInject.longClick(),Method.LongClick); - setListener(field,viewInject.itemClick(),Method.ItemClick); - setListener(field,viewInject.itemLongClick(),Method.itemLongClick); - - Select select = viewInject.select(); - if(!TextUtils.isEmpty(select.selected())){ - setViewSelectListener(field,select.selected(),select.noSelected()); - } - - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - - - - private void setViewSelectListener(Field field,String select,String noSelect)throws Exception{ - Object obj = field.get(this); - if(obj instanceof View){ - ((AbsListView)obj).setOnItemSelectedListener(new EventListener(this).select(select).noSelect(noSelect)); - } - } - - - private void setListener(Field field,String methodName,Method method)throws Exception{ - if(methodName == null || methodName.trim().length() == 0) - return; - - Object obj = field.get(this); - - switch (method) { - case Click: - if(obj instanceof View){ - ((View)obj).setOnClickListener(new EventListener(this).click(methodName)); - } - break; - case ItemClick: - if(obj instanceof AbsListView){ - ((AbsListView)obj).setOnItemClickListener(new EventListener(this).itemClick(methodName)); - } - break; - case LongClick: - if(obj instanceof View){ - ((View)obj).setOnLongClickListener(new EventListener(this).longClick(methodName)); - } - break; - case itemLongClick: - if(obj instanceof AbsListView){ - ((AbsListView)obj).setOnItemLongClickListener(new EventListener(this).itemLongClick(methodName)); - } - break; - default: - break; - } - } - - public enum Method{ - Click,LongClick,ItemClick,itemLongClick - } - -} + + public void setContentView(int layoutResID) { + super.setContentView(layoutResID); + FinalActivity.initInjectedView(this); + } + + + public void setContentView(View view, LayoutParams params) { + super.setContentView(view, params); + FinalActivity.initInjectedView(this); + } + + + + public void setContentView(View view) { + super.setContentView(view); + FinalActivity.initInjectedView(this); + } + + /** + * 初始化Actvity中的注入属性 + * 可用于与其他框架合用(如ActionBarShelock) + *

+ * *必须在setContentView之后调用: + *

+     * protected void onCreate(Bundle savedInstanceState) {
+     *  super.onCreate(savedInstanceState);
+     *   setContentView(view);
+     *   FinalActivity.initInjectedView(this);
+     * }
+     * 
+ * @param sourceActivity + */ + public static void initInjectedView(Activity sourceActivity){ + initInjectedView(sourceActivity,sourceActivity.getWindow().getDecorView()); + } + + /** + * 初始化指定View中的注入属性 + * 可用于Fragment内使用InjectView

+ * 示例:

+ * 在onCreateView中: + *

+     * public View onCreateView(LayoutInflater inflater, ViewGroup container,
+     *      Bundle savedInstanceState) {
+     *  View viewRoot = inflater.inflate(R.layout.map_frame, container, false);
+     *  FinalActivity.initInjectedView(this,viewRoot);
+     * }
+     * 
+ * @param sourceView + */ + public static void initInjectedView(Object injectedSource,View sourceView){ + Field[] fields = injectedSource.getClass().getDeclaredFields(); + if(fields!=null && fields.length>0){ + for(Field field : fields){ + ViewInject viewInject = field.getAnnotation(ViewInject.class); + if(viewInject!=null){ + int viewId = viewInject.id(); + try { + field.setAccessible(true); + /*当已经被赋值时,不在重复赋值,用于include,inflate情景下的viewinject组合*/ + if(field.get(injectedSource)==null){ + field.set(injectedSource,sourceView.findViewById(viewId)); + }else{ + continue; + } + } catch (Exception e) { + e.printStackTrace(); + } + + String clickMethod = viewInject.click(); + if(!TextUtils.isEmpty(clickMethod)) + setViewClickListener(injectedSource,field,clickMethod); + + String longClickMethod = viewInject.longClick(); + if(!TextUtils.isEmpty(longClickMethod)) + setViewLongClickListener(injectedSource,field,longClickMethod); + + String itemClickMethod = viewInject.itemClick(); + if(!TextUtils.isEmpty(itemClickMethod)) + setItemClickListener(injectedSource,field,itemClickMethod); + + + String itemLongClickMethod = viewInject.itemLongClick(); + if(!TextUtils.isEmpty(itemLongClickMethod)) + setItemLongClickListener(injectedSource,field,itemLongClickMethod); + + Select select = viewInject.select(); + if(!TextUtils.isEmpty(select.selected())) + setViewSelectListener(injectedSource,field,select.selected(),select.noSelected()); + + } + } + } + } + + + private static void setViewClickListener(Object injectedSource,Field field,String clickMethod){ + try { + Object obj = field.get(injectedSource); + if(obj instanceof View){ + ((View)obj).setOnClickListener(new EventListener(injectedSource).click(clickMethod)); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void setViewLongClickListener(Object injectedSource,Field field,String clickMethod){ + try { + Object obj = field.get(injectedSource); + if(obj instanceof View){ + ((View)obj).setOnLongClickListener(new EventListener(injectedSource).longClick(clickMethod)); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void setItemClickListener(Object injectedSource,Field field,String itemClickMethod){ + try { + Object obj = field.get(injectedSource); + if(obj instanceof AbsListView){ + ((AbsListView)obj).setOnItemClickListener(new EventListener(injectedSource).itemClick(itemClickMethod)); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void setItemLongClickListener(Object injectedSource,Field field,String itemClickMethod){ + try { + Object obj = field.get(injectedSource); + if(obj instanceof AbsListView){ + ((AbsListView)obj).setOnItemLongClickListener(new EventListener(injectedSource).itemLongClick(itemClickMethod)); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void setViewSelectListener(Object injectedSource,Field field,String select,String noSelect){ + try { + Object obj = field.get(injectedSource); + if(obj instanceof View){ + ((AbsListView)obj).setOnItemSelectedListener(new EventListener(injectedSource).select(select).noSelect(noSelect)); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + +} \ No newline at end of file diff --git a/src/net/tsz/afinal/FinalDb.java b/src/net/tsz/afinal/FinalDb.java index 24efbd4..e1e9064 100644 --- a/src/net/tsz/afinal/FinalDb.java +++ b/src/net/tsz/afinal/FinalDb.java @@ -741,7 +741,7 @@ public List findDbModelListBySQL(String strSQL) { return dbModelList; } - private void checkTableExist(Class clazz) { + public void checkTableExist(Class clazz) { if (!tableIsExist(TableInfo.get(clazz))) { String sql = SqlBuilder.getCreatTableSQL(clazz); debugSql(sql); @@ -858,6 +858,10 @@ public void setTargetDirectory(String targetDirectory) { */ private SQLiteDatabase createDbFileOnSDCard(String sdcardPath, String dbfilename, int dbVersion, DbUpdateListener dbUpdateListener) { + File dbDir = new File(sdcardPath); + if(!dbDir.exists()){ + dbDir.mkdirs(); + } File dbf = new File(sdcardPath, dbfilename); SQLiteDatabase retDb = null; if (!dbf.exists()) { From 7626cba5bc224d7b4c06d7fecaa310dc10a916ee Mon Sep 17 00:00:00 2001 From: lsjwzh Date: Thu, 26 Dec 2013 11:26:28 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E6=81=A2=E5=A4=8D=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bitmap/core/SoftMemoryCacheImpl.java | 74 ++++++++++--------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/src/net/tsz/afinal/bitmap/core/SoftMemoryCacheImpl.java b/src/net/tsz/afinal/bitmap/core/SoftMemoryCacheImpl.java index 7539de6..461aea8 100644 --- a/src/net/tsz/afinal/bitmap/core/SoftMemoryCacheImpl.java +++ b/src/net/tsz/afinal/bitmap/core/SoftMemoryCacheImpl.java @@ -16,41 +16,49 @@ package net.tsz.afinal.bitmap.core; import java.lang.ref.SoftReference; -import java.util.HashMap; + +import net.tsz.afinal.utils.Utils; import android.graphics.Bitmap; public class SoftMemoryCacheImpl implements IMemoryCache { - private final HashMap> mMemoryCache; - - public SoftMemoryCacheImpl(int size) { - - mMemoryCache = new HashMap>(); - } - - @Override - public void put(String key, Bitmap bitmap) { - mMemoryCache.put(key, new SoftReference(bitmap)); - } - - @Override - public Bitmap get(String key) { - SoftReference memBitmap = mMemoryCache.get(key); - if(memBitmap!=null){ - return memBitmap.get(); - } - return null; - } - - @Override - public void evictAll() { - mMemoryCache.clear(); - } - - @Override - public void remove(String key) { - mMemoryCache.remove(key); - } - -} + private final LruMemoryCache> mMemoryCache; + + public SoftMemoryCacheImpl(int size) { + mMemoryCache = new LruMemoryCache>(size) { + @Override + protected int sizeOf(String key, SoftReference sBitmap) { + final Bitmap bitmap = sBitmap==null ? null : sBitmap.get(); + if(bitmap == null) + return 1; + return Utils.getBitmapSize(bitmap); + } + }; + } + + @Override + public void put(String key, Bitmap bitmap) { + mMemoryCache.put(key, new SoftReference(bitmap)); + } + + @Override + public Bitmap get(String key) { + SoftReference memBitmap = mMemoryCache.get(key); + if(memBitmap!=null){ + return memBitmap.get(); + } + return null; + } + + @Override + public void evictAll() { + mMemoryCache.evictAll(); + } + + @Override + public void remove(String key) { + mMemoryCache.remove(key); + } + +} \ No newline at end of file