From 4514272f06eb6d5d5ff7474c5750550b76caeb96 Mon Sep 17 00:00:00 2001 From: AriaLyy <511455842@qq.com> Date: Mon, 24 Jul 2017 11:17:39 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=8C=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E9=95=BF=E5=BA=A6=E6=94=BE=E5=9C=A8header=E4=B8=AD=EF=BC=8CAri?= =?UTF-8?q?a=E4=B8=8D=E8=AF=86=E5=88=AB=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=9B=E4=BF=AE=E5=A4=8D=E5=8D=95=E4=BB=BB=E5=8A=A1=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E6=97=B6=E6=9C=89=E5=8F=AF=E8=83=BD=E5=87=BA=E7=8E=B0?= =?UTF-8?q?=E7=9A=84=E8=BF=9B=E5=BA=A6=E6=9D=A1=E9=94=99=E8=AF=AF=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/download/DownloadGroupTarget.java | 6 +- .../aria/core/download/DownloadTarget.java | 11 +- .../download/downloader/FileInfoThread.java | 6 +- .../downloader/SimpleDownloadUtil.java | 2 +- .../download/downloader/SingleThreadTask.java | 18 +- ...rmalTarget.java => AbsDownloadTarget.java} | 61 +++-- .../com/arialyy/aria/core/inf/AbsTarget.java | 14 + .../arialyy/aria/core/inf/AbsTaskEntity.java | 11 +- ...sGroupTarget.java => AbsUploadTarget.java} | 2 +- .../aria/core/upload/UploadTarget.java | 5 +- .../java/com/arialyy/aria/orm/DBConfig.java | 4 +- .../java/com/arialyy/aria/orm/DbEntity.java | 14 +- .../java/com/arialyy/aria/orm/SqlHelper.java | 257 +++--------------- .../java/com/arialyy/aria/orm/SqlUtil.java | 208 ++++++++++++++ .../simple/download/SingleTaskActivity.java | 3 +- 15 files changed, 341 insertions(+), 281 deletions(-) rename Aria/src/main/java/com/arialyy/aria/core/inf/{AbsNormalTarget.java => AbsDownloadTarget.java} (58%) rename Aria/src/main/java/com/arialyy/aria/core/inf/{AbsGroupTarget.java => AbsUploadTarget.java} (85%) create mode 100644 Aria/src/main/java/com/arialyy/aria/orm/SqlUtil.java diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java index 90f6c7c8..53f8b79c 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java @@ -16,9 +16,9 @@ package com.arialyy.aria.core.download; import android.text.TextUtils; -import com.arialyy.aria.core.inf.AbsGroupTarget; +import com.arialyy.aria.core.inf.AbsDownloadTarget; +import com.arialyy.aria.core.inf.AbsUploadTarget; import com.arialyy.aria.orm.DbEntity; -import com.arialyy.aria.orm.DbUtil; import com.arialyy.aria.util.CheckUtil; import com.arialyy.aria.util.CommonUtil; import java.io.File; @@ -29,7 +29,7 @@ import java.util.List; * Created by AriaL on 2017/6/29. */ public class DownloadGroupTarget - extends AbsGroupTarget { + extends AbsDownloadTarget { private List mUrls = new ArrayList<>(); private final String TAG = "DownloadGroupTarget"; /** diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java index 68cbcd5e..206e24b4 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java @@ -17,7 +17,7 @@ package com.arialyy.aria.core.download; import android.support.annotation.NonNull; import android.text.TextUtils; -import com.arialyy.aria.core.inf.AbsNormalTarget; +import com.arialyy.aria.core.inf.AbsDownloadTarget; import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.queue.DownloadTaskQueue; import com.arialyy.aria.orm.DbEntity; @@ -29,7 +29,7 @@ import java.io.File; * https://github.com/AriaLyy/Aria */ public class DownloadTarget - extends AbsNormalTarget { + extends AbsDownloadTarget { DownloadTarget(DownloadEntity entity, String targetName) { this(entity.getDownloadUrl(), targetName); @@ -87,13 +87,6 @@ public class DownloadTarget super.setHighestPriority(); } - /** - * 重定向后,新url的key,默认为location - */ - public DownloadTarget setRedirectUrlKey(String redirectUrlKey) { - super._setRedirectUrlKey(redirectUrlKey); - return this; - } /** * 下载任务是否存在 diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FileInfoThread.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FileInfoThread.java index 90bb447c..71fbbc27 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FileInfoThread.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FileInfoThread.java @@ -85,7 +85,10 @@ class FileInfoThread implements Runnable { } private void handleConnect(HttpURLConnection conn) throws IOException { - int len = conn.getContentLength(); + long len = conn.getContentLength(); + if (len < 0) { + len = Long.parseLong(conn.getHeaderField(mTaskEntity.contentLength)); + } int code = conn.getResponseCode(); boolean isComplete = false; if (TextUtils.isEmpty(mEntity.getMd5Code())) { @@ -93,6 +96,7 @@ class FileInfoThread implements Runnable { mEntity.setMd5Code(md5Code); } String disposition = conn.getHeaderField(mTaskEntity.dispositionKey); + //Map> headers = conn.getHeaderFields(); if (!TextUtils.isEmpty(disposition)) { mEntity.setDisposition(disposition); if (disposition.contains(mTaskEntity.dispositionFileKey)) { diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java index ac15d85d..bd22f7aa 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java @@ -98,7 +98,7 @@ public class SimpleDownloadUtil implements IDownloadUtil, Runnable { } })).start(); } else { - new Downloader(mListener, mTaskEntity).startDownload(); + mDT.startDownload(); } } } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SingleThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SingleThreadTask.java index 65c51cc4..ea7666c2 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SingleThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SingleThreadTask.java @@ -109,23 +109,15 @@ final class SingleThreadTask implements Runnable { //当前子线程的下载位置 mChildCurrentLocation = mConfigEntity.START_LOCATION; while ((len = is.read(buffer)) != -1) { - if (CONSTANCE.isCancel) { - break; - } - if (CONSTANCE.isStop) { - break; - } - Thread.sleep(mSleepTime); + if (CONSTANCE.isCancel) break; + if (CONSTANCE.isStop) break; + if (mSleepTime > 0) Thread.sleep(mSleepTime); file.write(buffer, 0, len); progress(len); } - if (CONSTANCE.isCancel) { - return; - } + if (CONSTANCE.isCancel) return; //停止状态不需要删除记录文件 - if (CONSTANCE.isStop) { - return; - } + if (CONSTANCE.isStop) return; //支持断点的处理 if (mConfigEntity.IS_SUPPORT_BREAK_POINT) { Log.i(TAG, "任务【" diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalTarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsDownloadTarget.java similarity index 58% rename from Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalTarget.java rename to Aria/src/main/java/com/arialyy/aria/core/inf/AbsDownloadTarget.java index 31de1c13..c9414414 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsDownloadTarget.java @@ -19,14 +19,54 @@ import android.text.TextUtils; import android.util.Log; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.command.normal.NormalCmdFactory; +import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.util.CommonUtil; /** * Created by lyy on 2017/2/28. */ -public abstract class AbsNormalTarget +public abstract class AbsDownloadTarget extends AbsTarget { + /** + * 如果你的下载链接的header中含有md5码信息,那么你可以通过设置key,来获取从header获取该md5码信息。 + * key默认值为:Content-MD5 + * 获取md5信息:{@link DownloadEntity#getMd5Code()} + */ + public void setHeaderMd5Key(String md5Key) { + if (TextUtils.isEmpty(md5Key)) return; + mTaskEntity.md5Key = md5Key; + } + + /** + * 如果你的文件长度是放在header中,那么你需要配置key来让Aria知道正确的文件长度 + * key默认值为:Content-Length + */ + public void setHeaderContentLengthKey(String contentLength) { + if (TextUtils.isEmpty(contentLength)) return; + mTaskEntity.contentLength = contentLength; + } + + /** + * 如果你的下载链接的header中含有文件描述信息,那么你可以通过设置key,来获取从header获取该文件描述信息。 + * key默认值为:Content-Disposition + * 获取文件描述信息:{@link DownloadEntity#getDisposition()} + */ + public void setHeaderDispositionKey(String dispositionKey) { + if (TextUtils.isEmpty(dispositionKey)) return; + mTaskEntity.dispositionKey = dispositionKey; + } + + /** + * 从文件描述信息{@link #setHeaderDispositionKey(String)}中含有文件名信息,你可以通过设置key来获取header中的文件名 + * key默认值为:attachment;filename + * 获取文件名信息:{@link DownloadEntity#getServerFileName()} + */ + public void setHeaderDispositionFileKey(String dispositionFileKey) { + if (TextUtils.isEmpty(dispositionFileKey)) return; + mTaskEntity.dispositionFileKey = dispositionFileKey; + } + /** * 将任务设置为最高优先级任务,最高优先级任务有以下特点: * 1、在下载队列中,有且只有一个最高优先级任务 @@ -46,21 +86,14 @@ public abstract class AbsNormalTarget extends DbEntity { public RequestEnum requestEnum = RequestEnum.GET; /** - * 从链接中含有的文件md5码信息所需要的key + * 从header中含有的文件md5码信息所需要的key */ public String md5Key = "Content-MD5"; /** - * 从链接中获取文件描述信息所需要的key + * 从header中获取文件描述信息所需要的key */ public String dispositionKey = "Content-Disposition"; /** - * 重定向后,从链接中获取新url所需要的key + * 重定向后,从header中获取新url所需要的key */ public String redirectUrlKey = "location"; @@ -62,6 +62,11 @@ public abstract class AbsTaskEntity extends DbEntity { */ public String dispositionFileKey = "attachment;filename"; + /** + * 从header中含有的文件长度信息所需要的key + */ + public String contentLength = "Content-Length"; + /** * 重定向链接 */ diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupTarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsUploadTarget.java similarity index 85% rename from Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupTarget.java rename to Aria/src/main/java/com/arialyy/aria/core/inf/AbsUploadTarget.java index c201a010..5422007c 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsUploadTarget.java @@ -19,7 +19,7 @@ package com.arialyy.aria.core.inf; * Created by AriaL on 2017/6/29. * 任务组超类 */ -public abstract class AbsGroupTarget +public abstract class AbsUploadTarget extends AbsTarget { diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java index 690ebc4c..b6ef2f1d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java @@ -16,7 +16,8 @@ package com.arialyy.aria.core.upload; import android.support.annotation.NonNull; -import com.arialyy.aria.core.inf.AbsNormalTarget; +import com.arialyy.aria.core.inf.AbsDownloadTarget; +import com.arialyy.aria.core.inf.AbsUploadTarget; import com.arialyy.aria.core.queue.UploadTaskQueue; import com.arialyy.aria.orm.DbEntity; import java.util.regex.Pattern; @@ -24,7 +25,7 @@ import java.util.regex.Pattern; /** * Created by lyy on 2017/2/28. */ -public class UploadTarget extends AbsNormalTarget { +public class UploadTarget extends AbsUploadTarget { UploadTarget(String filePath, String targetName) { this.mTargetName = targetName; diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java b/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java index b8178ba5..11b6f2d5 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java @@ -29,10 +29,10 @@ import java.util.Map; * Created by lyy on 2017/4/6. * 数据库配置信息 */ -public class DBConfig { +class DBConfig { static Map mapping = new HashMap<>(); static String DB_NAME; - static int VERSION = 10; + static int VERSION = 11; static { if (TextUtils.isEmpty(DB_NAME)) { diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java b/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java index f872e5d2..88b1c2c4 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java @@ -170,21 +170,21 @@ public class DbEntity { List values = new ArrayList<>(); for (Field field : fields) { field.setAccessible(true); - if (SqlHelper.ignoreField(field)) { + if (SqlUtil.ignoreField(field)) { continue; } where.add(field.getName()); Type type = field.getType(); - if (SqlHelper.isOneToOne(field)) { - values.add(SqlHelper.getOneToOneParams(field)); + if (SqlUtil.isOneToOne(field)) { + values.add(SqlUtil.getOneToOneParams(field)); } else if (type == List.class) { - if (SqlHelper.isOneToMany(field)) { - values.add(SqlHelper.getOneToManyElementParams(field)); + if (SqlUtil.isOneToMany(field)) { + values.add(SqlUtil.getOneToManyElementParams(field)); } else { - values.add(SqlHelper.list2Str(this, field)); + values.add(SqlUtil.list2Str(this, field)); } } else if (type == Map.class) { - values.add(SqlHelper.map2Str((Map) field.get(this))); + values.add(SqlUtil.map2Str((Map) field.get(this))); } else { values.add(field.get(this) + ""); } diff --git a/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java b/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java index 2cdc017d..c5affd31 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java @@ -27,12 +27,9 @@ import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.util.CheckUtil; import com.arialyy.aria.util.CommonUtil; import java.lang.reflect.Field; -import java.lang.reflect.Modifier; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -57,7 +54,17 @@ final class SqlHelper extends SQLiteOpenHelper { if (INSTANCE == null) { synchronized (AriaManager.LOCK) { INSTANCE = new SqlHelper(context.getApplicationContext()); - checkTable(INSTANCE.getWritableDatabase()); + SQLiteDatabase db = INSTANCE.getWritableDatabase(); + db = checkDb(db); + Set tables = DBConfig.mapping.keySet(); + for (String tableName : tables) { + Class clazz = null; + clazz = DBConfig.mapping.get(tableName); + + if (!tableExists(db, clazz)) { + createTable(db, clazz, null); + } + } } } return INSTANCE; @@ -86,8 +93,6 @@ final class SqlHelper extends SQLiteOpenHelper { /** * 处理数据库升级 - * - * @throws ClassNotFoundException */ private void handleDbUpdate(SQLiteDatabase db) { if (db == null) { @@ -148,7 +153,7 @@ final class SqlHelper extends SQLiteOpenHelper { if (fields != null && fields.size() > 0) { for (Field field : fields) { field.setAccessible(true); - if (ignoreField(field)) { + if (SqlUtil.ignoreField(field)) { continue; } count++; @@ -157,22 +162,6 @@ final class SqlHelper extends SQLiteOpenHelper { return count; } - /** - * 检查数据库表,如果配置的表不存在,则创建新表 - */ - static synchronized void checkTable(SQLiteDatabase db) { - db = checkDb(db); - Set tables = DBConfig.mapping.keySet(); - for (String tableName : tables) { - Class clazz = null; - clazz = DBConfig.mapping.get(tableName); - - if (!tableExists(db, clazz)) { - createTable(db, clazz, null); - } - } - } - /** * 条件查寻数据 */ @@ -286,7 +275,7 @@ final class SqlHelper extends SQLiteOpenHelper { int i = 0; for (Field field : fields) { field.setAccessible(true); - if (SqlHelper.ignoreField(field)) { + if (SqlUtil.ignoreField(field)) { continue; } sb.append(i > 0 ? ", " : ""); @@ -295,15 +284,15 @@ final class SqlHelper extends SQLiteOpenHelper { sb.append(field.getName()).append("='"); Type type = field.getType(); if (type == Map.class) { - value = map2Str((Map) field.get(dbEntity)); + value = SqlUtil.map2Str((Map) field.get(dbEntity)); } else if (type == List.class) { - if (isOneToMany(field)) { - value = getOneToManyElementParams(field); + if (SqlUtil.isOneToMany(field)) { + value = SqlUtil.getOneToManyElementParams(field); } else { - value = list2Str(dbEntity, field); + value = SqlUtil.list2Str(dbEntity, field); } - } else if (isOneToOne(field)) { - value = getOneToOneParams(field); + } else if (SqlUtil.isOneToOne(field)) { + value = SqlUtil.getOneToOneParams(field); } else { Object obj = field.get(dbEntity); value = obj == null ? "" : obj.toString(); @@ -336,11 +325,10 @@ final class SqlHelper extends SQLiteOpenHelper { int i = 0; for (Field field : fields) { field.setAccessible(true); - if (ignoreField(field)) { + if (SqlUtil.ignoreField(field)) { continue; } sb.append(i > 0 ? ", " : ""); - //sb.append(getFieldName(field.getType(), field)); sb.append(field.getName()); i++; } @@ -349,22 +337,22 @@ final class SqlHelper extends SQLiteOpenHelper { try { for (Field field : fields) { field.setAccessible(true); - if (ignoreField(field)) { + if (SqlUtil.ignoreField(field)) { continue; } sb.append(i > 0 ? ", " : ""); sb.append("'"); Type type = field.getType(); if (type == Map.class) { - sb.append(map2Str((Map) field.get(dbEntity))); + sb.append(SqlUtil.map2Str((Map) field.get(dbEntity))); } else if (type == List.class) { - if (isOneToMany(field)) { - sb.append(getOneToManyElementParams(field)); + if (SqlUtil.isOneToMany(field)) { + sb.append(SqlUtil.getOneToManyElementParams(field)); } else { - sb.append(list2Str(dbEntity, field)); + sb.append(SqlUtil.list2Str(dbEntity, field)); } - } else if (isOneToOne(field)) { - sb.append(getOneToOneParams(field)); + } else if (SqlUtil.isOneToOne(field)) { + sb.append(SqlUtil.getOneToOneParams(field)); } else { sb.append(field.get(dbEntity)); } @@ -381,104 +369,6 @@ final class SqlHelper extends SQLiteOpenHelper { close(db); } - /** - * 获取一对一参数 - */ - static String getOneToOneParams(Field field) { - OneToOne oneToOne = field.getAnnotation(OneToOne.class); - if (oneToOne == null) { - throw new IllegalArgumentException("@OneToOne注解的对象必须要有@Primary注解的字段"); - } - return oneToOne.table().getName() + "$$" + oneToOne.key(); - } - - /** - * 获取List一对多参数 - * - * @param field list反射字段 - */ - static String getOneToManyElementParams(Field field) { - OneToMany oneToMany = field.getAnnotation(OneToMany.class); - if (oneToMany == null) { - throw new IllegalArgumentException("一对多元素必须被@OneToMany注解"); - } - //关联的表名 - String tableName = oneToMany.table().getName(); - //关联的字段 - String key = oneToMany.key(); - return tableName + "$$" + key; - } - - /** - * 列表数据转字符串 - * - * @param field list反射字段 - */ - static String list2Str(DbEntity dbEntity, Field field) throws IllegalAccessException { - NormalList normalList = field.getAnnotation(NormalList.class); - if (normalList == null) { - throw new IllegalArgumentException("List中元素必须被@NormalList注解"); - } - List list = (List) field.get(dbEntity); - if (list == null || list.isEmpty()) return ""; - StringBuilder sb = new StringBuilder(); - for (Object aList : list) { - sb.append(aList).append("$$"); - } - return sb.toString(); - } - - /** - * 字符串转列表 - * - * @param str 数据库中的字段 - * @return 如果str为null,则返回null - */ - private static List str2List(String str, Field field) { - NormalList normalList = field.getAnnotation(NormalList.class); - if (normalList == null) { - throw new IllegalArgumentException("List中元素必须被@NormalList注解"); - } - if (TextUtils.isEmpty(str)) return null; - String[] datas = str.split("$$"); - List list = new ArrayList(); - String type = normalList.clazz().getName(); - for (String data : datas) { - list.add(checkData(data, type)); - } - return list; - } - - private static Object checkData(String type, String data) { - switch (type) { - case "String": - return data; - case "int": - case "Integer": - return Integer.parseInt(data); - case "double": - case "Double": - return Double.parseDouble(data); - case "float": - case "Float": - return Float.parseFloat(data); - } - return null; - } - - /** - * 查找class的主键字段 - * - * @return 返回主键字段名 - */ - private static String getPrimaryName(Class clazz) { - List fields = CommonUtil.getAllFields(clazz); - for (Field field : fields) { - if (isPrimary(field)) return field.getName(); - } - return null; - } - /** * 查找表是否存在 * @@ -526,7 +416,7 @@ final class SqlHelper extends SQLiteOpenHelper { .append("("); for (Field field : fields) { field.setAccessible(true); - if (ignoreField(field)) { + if (SqlUtil.ignoreField(field)) { continue; } Class type = field.getType(); @@ -534,7 +424,7 @@ final class SqlHelper extends SQLiteOpenHelper { if (type == String.class || type == Map.class || type == List.class - || isOneToOne(field) + || SqlUtil.isOneToOne(field) || type.isEnum()) { sb.append(" varchar"); } else if (type == int.class || type == Integer.class) { @@ -554,7 +444,7 @@ final class SqlHelper extends SQLiteOpenHelper { } else { continue; } - if (isPrimary(field)) { + if (SqlUtil.isPrimary(field)) { //sb.append(" PRIMARY KEY"); sb.append(" NOT NULL"); } @@ -614,7 +504,7 @@ final class SqlHelper extends SQLiteOpenHelper { T entity = clazz.newInstance(); for (Field field : fields) { field.setAccessible(true); - if (ignoreField(field)) { + if (SqlUtil.ignoreField(field)) { continue; } Class type = field.getType(); @@ -637,12 +527,12 @@ final class SqlHelper extends SQLiteOpenHelper { } else if (type == byte[].class) { field.set(entity, cursor.getBlob(column)); } else if (type == Map.class) { - field.set(entity, str2Map(cursor.getString(column))); + field.set(entity, SqlUtil.str2Map(cursor.getString(column))); } else if (type == List.class) { String value = cursor.getString(column); - if (isOneToMany(field)) { + if (SqlUtil.isOneToMany(field)) { //主键字段 - String primaryKey = getPrimaryName(clazz); + String primaryKey = SqlUtil.getPrimaryName(clazz); if (TextUtils.isEmpty(primaryKey)) { throw new IllegalArgumentException("List中的元素对象必须需要@Primary注解的字段"); } @@ -654,10 +544,10 @@ final class SqlHelper extends SQLiteOpenHelper { if (list == null) continue; field.set(entity, findForeignData(db, primaryData, value)); } else { - field.set(entity, str2List(value, field)); + field.set(entity, SqlUtil.str2List(value, field)); } - } else if (isOneToOne(field)) { - String primaryKey = getPrimaryName(clazz); + } else if (SqlUtil.isOneToOne(field)) { + String primaryKey = SqlUtil.getPrimaryName(clazz); if (TextUtils.isEmpty(primaryKey)) { throw new IllegalArgumentException("@OneToOne的注解对象必须需要@Primary注解的字段"); } @@ -696,41 +586,6 @@ final class SqlHelper extends SQLiteOpenHelper { return findData(db, params[0], params[1] + "=?", primary); } - /** - * 字符串转Map,只支持 - *
-   *   {@code Map}
-   * 
- */ - private static Map str2Map(String str) { - Map map = new HashMap<>(); - if (TextUtils.isEmpty(str)) { - return map; - } - String[] element = str.split(","); - for (String data : element) { - String[] s = data.split("\\$"); - map.put(s[0], s[1]); - } - return map; - } - - /** - * Map转字符串,只支持 - *
-   *   {@code Map}
-   * 
- */ - static String map2Str(Map map) { - StringBuilder sb = new StringBuilder(); - Set keys = map.keySet(); - for (String key : keys) { - sb.append(key).append("$").append(map.get(key)).append(","); - } - String str = sb.toString(); - return TextUtils.isEmpty(str) ? str : str.substring(0, str.length() - 1); - } - private static void close(SQLiteDatabase db) { //if (db != null && db.isOpen()) db.close(); } @@ -741,42 +596,4 @@ final class SqlHelper extends SQLiteOpenHelper { } return db; } - - /** - * @return true 忽略该字段 - */ - static boolean ignoreField(Field field) { - // field.isSynthetic(), 使用as热启动App时,AS会自动给你的class添加change字段 - Ignore ignore = field.getAnnotation(Ignore.class); - int modifiers = field.getModifiers(); - return (ignore != null && ignore.value()) - || field.getName().equals("rowID") - || field.isSynthetic() - || Modifier.isStatic(modifiers) - || Modifier.isFinal(modifiers); - } - - /** - * 判断是否一对多注解 - */ - static boolean isOneToMany(Field field) { - OneToMany oneToMany = field.getAnnotation(OneToMany.class); - return oneToMany != null; - } - - /** - * 判断是否是一对一注解 - */ - static boolean isOneToOne(Field field) { - OneToOne oneToOne = field.getAnnotation(OneToOne.class); - return oneToOne != null; - } - - /** - * 判断是否是主键 - */ - static boolean isPrimary(Field field) { - Primary pk = field.getAnnotation(Primary.class); - return pk != null; - } } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/orm/SqlUtil.java b/Aria/src/main/java/com/arialyy/aria/orm/SqlUtil.java new file mode 100644 index 00000000..76a1f08d --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/orm/SqlUtil.java @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * 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. + */ +package com.arialyy.aria.orm; + +import android.database.sqlite.SQLiteDatabase; +import android.text.TextUtils; +import com.arialyy.aria.util.CommonUtil; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Created by Aria.Lao on 2017/7/24. + * sql工具 + */ +final class SqlUtil { + + /** + * 获取一对一参数 + */ + static String getOneToOneParams(Field field) { + OneToOne oneToOne = field.getAnnotation(OneToOne.class); + if (oneToOne == null) { + throw new IllegalArgumentException("@OneToOne注解的对象必须要有@Primary注解的字段"); + } + return oneToOne.table().getName() + "$$" + oneToOne.key(); + } + + /** + * 获取List一对多参数 + * + * @param field list反射字段 + */ + static String getOneToManyElementParams(Field field) { + OneToMany oneToMany = field.getAnnotation(OneToMany.class); + if (oneToMany == null) { + throw new IllegalArgumentException("一对多元素必须被@OneToMany注解"); + } + //关联的表名 + String tableName = oneToMany.table().getName(); + //关联的字段 + String key = oneToMany.key(); + return tableName + "$$" + key; + } + + /** + * 列表数据转字符串 + * + * @param field list反射字段 + */ + static String list2Str(DbEntity dbEntity, Field field) throws IllegalAccessException { + NormalList normalList = field.getAnnotation(NormalList.class); + if (normalList == null) { + throw new IllegalArgumentException("List中元素必须被@NormalList注解"); + } + List list = (List) field.get(dbEntity); + if (list == null || list.isEmpty()) return ""; + StringBuilder sb = new StringBuilder(); + for (Object aList : list) { + sb.append(aList).append("$$"); + } + return sb.toString(); + } + + /** + * 字符串转列表 + * + * @param str 数据库中的字段 + * @return 如果str为null,则返回null + */ + static List str2List(String str, Field field) { + NormalList normalList = field.getAnnotation(NormalList.class); + if (normalList == null) { + throw new IllegalArgumentException("List中元素必须被@NormalList注解"); + } + if (TextUtils.isEmpty(str)) return null; + String[] datas = str.split("$$"); + List list = new ArrayList(); + String type = normalList.clazz().getName(); + for (String data : datas) { + list.add(checkData(data, type)); + } + return list; + } + + /** + * 字符串转Map,只支持 + *
+   *   {@code Map}
+   * 
+ */ + static Map str2Map(String str) { + Map map = new HashMap<>(); + if (TextUtils.isEmpty(str)) { + return map; + } + String[] element = str.split(","); + for (String data : element) { + String[] s = data.split("\\$"); + map.put(s[0], s[1]); + } + return map; + } + + /** + * Map转字符串,只支持 + *
+   *   {@code Map}
+   * 
+ */ + static String map2Str(Map map) { + StringBuilder sb = new StringBuilder(); + Set keys = map.keySet(); + for (String key : keys) { + sb.append(key).append("$").append(map.get(key)).append(","); + } + String str = sb.toString(); + return TextUtils.isEmpty(str) ? str : str.substring(0, str.length() - 1); + } + + + + /** + * @return true 忽略该字段 + */ + static boolean ignoreField(Field field) { + // field.isSynthetic(), 使用as热启动App时,AS会自动给你的class添加change字段 + Ignore ignore = field.getAnnotation(Ignore.class); + int modifiers = field.getModifiers(); + return (ignore != null && ignore.value()) + || field.getName().equals("rowID") + || field.isSynthetic() + || Modifier.isStatic(modifiers) + || Modifier.isFinal(modifiers); + } + + /** + * 判断是否一对多注解 + */ + static boolean isOneToMany(Field field) { + OneToMany oneToMany = field.getAnnotation(OneToMany.class); + return oneToMany != null; + } + + /** + * 判断是否是一对一注解 + */ + static boolean isOneToOne(Field field) { + OneToOne oneToOne = field.getAnnotation(OneToOne.class); + return oneToOne != null; + } + + /** + * 判断是否是主键 + */ + static boolean isPrimary(Field field) { + Primary pk = field.getAnnotation(Primary.class); + return pk != null; + } + + private static Object checkData(String type, String data) { + switch (type) { + case "String": + return data; + case "int": + case "Integer": + return Integer.parseInt(data); + case "double": + case "Double": + return Double.parseDouble(data); + case "float": + case "Float": + return Float.parseFloat(data); + } + return null; + } + + + /** + * 查找class的主键字段 + * + * @return 返回主键字段名 + */ + static String getPrimaryName(Class clazz) { + List fields = CommonUtil.getAllFields(clazz); + for (Field field : fields) { + if (isPrimary(field)) return field.getName(); + } + return null; + } +} diff --git a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java index aaab2bb9..b6b8528d 100644 --- a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java @@ -41,7 +41,8 @@ public class SingleTaskActivity extends BaseActivity { private static final String DOWNLOAD_URL = //"http://kotlinlang.org/docs/kotlin-docs.pdf"; //"https://atom-installer.github.com/v1.13.0/AtomSetup.exe?s=1484074138&ext=.exe"; - "http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk"; + //"http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk"; + "https://d.pcs.baidu.com/file/7330524ec2affe80914cd306e16fd0ac?fid=3965548007-250528-918323254381453&time=1500859695&rt=sh&sign=FDTAERVY-DCb740ccc5511e5e8fedcff06b081203-7u09%2BsA23HuD53M3bCJpH1HVp3o%3D&expires=8h&chkv=1&chkbd=0&chkpc=et&dp-logid=4740488282618906999&dp-callid=0&r=714336419"; //"http://down2.xiaoshuofuwuqi.com/d/file/filetxt/20170608/14/%BA%DA%CE%D7%CA%A6%E1%C8%C6%F0.txt"; //"http://tinghuaapp.oss-cn-shanghai.aliyuncs.com/20170612201739607815"; //"http://static.gaoshouyou.com/d/36/69/2d3699acfa69e9632262442c46516ad8.apk";