From fd7e7cc7f4cec13da1cfbf7b7415dd2509d018a8 Mon Sep 17 00:00:00 2001 From: AriaLyy <511455842@qq.com> Date: Tue, 4 Jul 2017 19:40:53 +0800 Subject: [PATCH] =?UTF-8?q?orm=20=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aria/core/download/DownloadEntity.java | 43 ++- .../core/download/DownloadGroupEntity.java | 2 + .../download/DownloadGroupTaskEntity.java | 7 + .../aria/core/download/DownloadTarget.java | 4 +- .../core/download/DownloadTaskEntity.java | 7 + .../core/download/downloader/Downloader.java | 54 ++-- .../arialyy/aria/core/inf/AbsGroupEntity.java | 4 +- .../aria/core/inf/AbsNormalEntity.java | 1 + .../aria/core/inf/AbsNormalTarget.java | 2 - .../arialyy/aria/core/inf/AbsTaskEntity.java | 9 +- .../aria/core/upload/UploadEntity.java | 3 +- .../java/com/arialyy/aria/orm/DBConfig.java | 10 +- .../java/com/arialyy/aria/orm/OneToMany.java | 36 +++ .../java/com/arialyy/aria/orm/OneToOne.java | 38 +++ .../aria/orm/{Id.java => Primary.java} | 2 +- .../java/com/arialyy/aria/orm/SqlHelper.java | 251 ++++++++++++++++-- .../com/arialyy/aria/util/CommonUtil.java | 54 ++++ .../simple/download/DownloadModule.java | 65 ----- .../simple/download/SingleTaskActivity.java | 1 - .../aria/core/upload/UploadTaskEntity.java | 8 +- 20 files changed, 463 insertions(+), 138 deletions(-) create mode 100644 Aria/src/main/java/com/arialyy/aria/orm/OneToMany.java create mode 100644 Aria/src/main/java/com/arialyy/aria/orm/OneToOne.java rename Aria/src/main/java/com/arialyy/aria/orm/{Id.java => Primary.java} (97%) diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java index e1102037..340c91f1 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java @@ -19,24 +19,34 @@ package com.arialyy.aria.core.download; import android.os.Parcel; import android.os.Parcelable; import com.arialyy.aria.core.inf.AbsNormalEntity; -import com.arialyy.aria.orm.Ignore; +import com.arialyy.aria.orm.Primary; /** * Created by lyy on 2015/12/25. * 下载实体 - * !!! 注意:CREATOR要进行@Ignore注解 - * !!!并且需要Parcelable时需要手动填写rowID; */ public class DownloadEntity extends AbsNormalEntity implements Parcelable { - private String downloadUrl = ""; //下载路径 + @Primary private String downloadUrl = ""; //下载路径 private String downloadPath = ""; //保存路径 private boolean isDownloadComplete = false; //是否下载完成 private boolean isRedirect = false; //是否重定向 private String redirectUrl = ""; //重定向链接 + /** + * 所属任务组 + */ + private String groupName = ""; + public DownloadEntity() { } + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } public String getDownloadUrl() { return downloadUrl; @@ -95,6 +105,7 @@ public class DownloadEntity extends AbsNormalEntity implements Parcelable { dest.writeByte(this.isDownloadComplete ? (byte) 1 : (byte) 0); dest.writeByte(this.isRedirect ? (byte) 1 : (byte) 0); dest.writeString(this.redirectUrl); + dest.writeString(this.groupName); } protected DownloadEntity(Parcel in) { @@ -104,9 +115,31 @@ public class DownloadEntity extends AbsNormalEntity implements Parcelable { this.isDownloadComplete = in.readByte() != 0; this.isRedirect = in.readByte() != 0; this.redirectUrl = in.readString(); + this.groupName = in.readString(); } - @Ignore public static final Creator CREATOR = new Creator() { + @Override public String toString() { + return "DownloadEntity{" + + "downloadUrl='" + + downloadUrl + + '\'' + + ", downloadPath='" + + downloadPath + + '\'' + + ", isDownloadComplete=" + + isDownloadComplete + + ", isRedirect=" + + isRedirect + + ", redirectUrl='" + + redirectUrl + + '\'' + + ", groupName='" + + groupName + + '\'' + + '}'; + } + + public static final Creator CREATOR = new Creator() { @Override public DownloadEntity createFromParcel(Parcel source) { return new DownloadEntity(source); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java index 4cfaa7a3..5b82ddfc 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java @@ -17,6 +17,7 @@ package com.arialyy.aria.core.download; import android.os.Parcel; import com.arialyy.aria.core.inf.AbsGroupEntity; +import com.arialyy.aria.orm.OneToMany; import java.util.LinkedList; import java.util.List; @@ -26,6 +27,7 @@ import java.util.List; */ public class DownloadGroupEntity extends AbsGroupEntity { + @OneToMany(table = DownloadEntity.class, key = "groupName") private List mChild = new LinkedList<>(); public List getChild() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTaskEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTaskEntity.java index 94c7cd29..8ef08664 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTaskEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTaskEntity.java @@ -16,13 +16,20 @@ package com.arialyy.aria.core.download; import com.arialyy.aria.core.inf.AbsTaskEntity; +import com.arialyy.aria.orm.OneToOne; /** * Created by AriaL on 2017/7/1. */ public class DownloadGroupTaskEntity extends AbsTaskEntity { + @OneToOne(table = DownloadGroupEntity.class, key = "groupName") public DownloadGroupEntity entity; + public DownloadGroupTaskEntity(DownloadGroupEntity entity) { this.entity = entity; } + + @Override public DownloadGroupEntity getEntity() { + return entity; + } } 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 914c1ff7..e9f4295a 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 @@ -29,8 +29,8 @@ public class DownloadTarget extends AbsNormalTarget { DownloadTarget(DownloadEntity entity, String targetName) { - this.mEntity = entity; - this.mTargetName = targetName; + mEntity = entity; + mTargetName = targetName; mTaskEntity = new DownloadTaskEntity(entity); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java index 70439cba..09e06d7e 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java @@ -16,6 +16,7 @@ package com.arialyy.aria.core.download; import com.arialyy.aria.core.inf.AbsTaskEntity; +import com.arialyy.aria.orm.OneToOne; /** * Created by lyy on 2017/1/23. @@ -23,10 +24,16 @@ import com.arialyy.aria.core.inf.AbsTaskEntity; */ public class DownloadTaskEntity extends AbsTaskEntity { + @OneToOne(table = DownloadEntity.class, key = "downloadUrl") public DownloadEntity entity; + public DownloadTaskEntity() { } public DownloadTaskEntity(DownloadEntity entity) { this.entity = entity; } + + @Override public DownloadEntity getEntity() { + return entity; + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java index dd2f2e40..ad127c1b 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java @@ -76,8 +76,35 @@ class Downloader implements Runnable, IDownloadUtil { } @Override public void run() { + startFlow(); + } + + /** + * 开始下载流程 + */ + private void startFlow(){ checkTask(); - startDownload(); + mConstance.cleanState(); + mConstance.isDownloading = true; + try { + if (!mTaskEntity.isSupportBP) { + mThreadNum = 1; + handleNoSupportBreakpointDownload(); + } else { + mThreadNum = isNewTask ? (mEntity.getFileSize() <= SUB_LEN ? 1 + : AriaManager.getInstance(mContext).getDownloadConfig().getThreadNum()) + : mRealThreadNum; + mFixedThreadPool = Executors.newFixedThreadPool(mThreadNum); + handleBreakpoint(); + } + } catch (IOException e) { + failDownload("下载失败【downloadUrl:" + + mEntity.getDownloadUrl() + + "】\n【filePath:" + + mEntity.getDownloadPath() + + "】\n" + + CommonUtil.getPrintException(e)); + } } @Override public long getFileSize() { @@ -124,28 +151,11 @@ class Downloader implements Runnable, IDownloadUtil { } } + /** + * 直接调用的时候会自动启动线程执行 + */ @Override public void startDownload() { - mConstance.cleanState(); - mConstance.isDownloading = true; - try { - if (!mTaskEntity.isSupportBP) { - mThreadNum = 1; - handleNoSupportBreakpointDownload(); - } else { - mThreadNum = isNewTask ? (mEntity.getFileSize() <= SUB_LEN ? 1 - : AriaManager.getInstance(mContext).getDownloadConfig().getThreadNum()) - : mRealThreadNum; - mFixedThreadPool = Executors.newFixedThreadPool(mThreadNum); - handleBreakpoint(); - } - } catch (IOException e) { - failDownload("下载失败【downloadUrl:" - + mEntity.getDownloadUrl() - + "】\n【filePath:" - + mEntity.getDownloadPath() - + "】\n" - + CommonUtil.getPrintException(e)); - } + new Thread(this).start(); } @Override public void resumeDownload() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupEntity.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupEntity.java index b324fd57..6a708b98 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupEntity.java @@ -17,8 +17,7 @@ package com.arialyy.aria.core.inf; import android.os.Parcel; import android.os.Parcelable; -import com.arialyy.aria.orm.DbEntity; -import com.arialyy.aria.orm.Ignore; +import com.arialyy.aria.orm.Primary; /** * Created by AriaL on 2017/6/3. @@ -27,6 +26,7 @@ public abstract class AbsGroupEntity extends AbsEntity implements Parcelable { /** * 组名 */ + @Primary private String groupName = ""; /** diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalEntity.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalEntity.java index 4c89b6aa..d1425f7f 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalEntity.java @@ -35,6 +35,7 @@ public abstract class AbsNormalEntity extends AbsEntity implements Parcelable { */ private boolean isGroupChild = false; + public boolean isGroupChild() { return isGroupChild; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalTarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalTarget.java index b8351713..31de1c13 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalTarget.java @@ -26,8 +26,6 @@ import com.arialyy.aria.util.CommonUtil; */ public abstract class AbsNormalTarget extends AbsTarget { - protected ENTITY mEntity; - protected TASK_ENTITY mTaskEntity; /** * 将任务设置为最高优先级任务,最高优先级任务有以下特点: diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java index 205eb388..26459feb 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java @@ -17,6 +17,7 @@ package com.arialyy.aria.core.inf; import com.arialyy.aria.core.RequestEnum; import com.arialyy.aria.orm.DbEntity; +import com.arialyy.aria.orm.Ignore; import java.util.HashMap; import java.util.Map; @@ -25,8 +26,6 @@ import java.util.Map; */ public abstract class AbsTaskEntity extends DbEntity { - public ENTITY entity; - /** * Task实体对应的key */ @@ -50,7 +49,7 @@ public abstract class AbsTaskEntity extends DbEntity { /** * 用于判断删除任务时是否需要删除文件{@code true}删除 */ - public boolean removeFile = false; + @Ignore public boolean removeFile = false; /** * 是否支持断点, {@code true} 为支持断点 @@ -62,7 +61,5 @@ public abstract class AbsTaskEntity extends DbEntity { */ public int code; - public ENTITY getEntity() { - return entity; - } + public abstract ENTITY getEntity(); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java index e9105255..39cc014f 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java @@ -19,13 +19,14 @@ import android.os.Parcel; import android.os.Parcelable; import com.arialyy.aria.core.inf.AbsNormalEntity; import com.arialyy.aria.orm.Ignore; +import com.arialyy.aria.orm.Primary; /** * Created by lyy on 2017/2/9. * 上传文件实体 */ public class UploadEntity extends AbsNormalEntity implements Parcelable { - + @Primary private String filePath; //文件路径 private boolean isComplete = false; 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 faf40925..ec9f92eb 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java @@ -17,7 +17,11 @@ package com.arialyy.aria.orm; import android.text.TextUtils; import com.arialyy.aria.core.download.DownloadEntity; +import com.arialyy.aria.core.download.DownloadGroupEntity; +import com.arialyy.aria.core.download.DownloadGroupTaskEntity; +import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.upload.UploadEntity; +import com.arialyy.aria.core.upload.UploadTaskEntity; import java.util.HashMap; import java.util.Map; @@ -28,7 +32,7 @@ import java.util.Map; public class DBConfig { static Map mapping = new HashMap<>(); static String DB_NAME; - static int VERSION = 3; + static int VERSION = 6; static { if (TextUtils.isEmpty(DB_NAME)) { @@ -41,6 +45,10 @@ public class DBConfig { static { mapping.put("DownloadEntity", DownloadEntity.class); + mapping.put("DownloadGroupEntity", DownloadGroupEntity.class); + mapping.put("DownloadTaskEntity", DownloadTaskEntity.class); + mapping.put("DownloadGroupTaskEntity", DownloadGroupTaskEntity.class); mapping.put("UploadEntity", UploadEntity.class); + mapping.put("UploadTaskEntity", UploadTaskEntity.class); } } diff --git a/Aria/src/main/java/com/arialyy/aria/orm/OneToMany.java b/Aria/src/main/java/com/arialyy/aria/orm/OneToMany.java new file mode 100644 index 00000000..8f529e1b --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/orm/OneToMany.java @@ -0,0 +1,36 @@ +/* + * 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 java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Created by AriaL on 2017/7/4. + * 一对多 + */ +@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface OneToMany { + /** + * 关联的表 + */ + Class table(); + /** + * 关联的主键 + */ + String key(); +} diff --git a/Aria/src/main/java/com/arialyy/aria/orm/OneToOne.java b/Aria/src/main/java/com/arialyy/aria/orm/OneToOne.java new file mode 100644 index 00000000..7641fd55 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/orm/OneToOne.java @@ -0,0 +1,38 @@ +/* + * 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 java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Created by AriaL on 2017/7/4. + * 一对一 + */ +@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface OneToOne { + + /** + * 关联的表 + */ + Class table(); + + /** + * 关联的主键 + */ + String key(); +} diff --git a/Aria/src/main/java/com/arialyy/aria/orm/Id.java b/Aria/src/main/java/com/arialyy/aria/orm/Primary.java similarity index 97% rename from Aria/src/main/java/com/arialyy/aria/orm/Id.java rename to Aria/src/main/java/com/arialyy/aria/orm/Primary.java index a59b85d9..365f1713 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/Id.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/Primary.java @@ -25,6 +25,6 @@ import java.lang.annotation.Target; * Created by lyy on 2015/11/2. * 表ID字段指定 */ -@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Id { +@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Primary { int value() default -1; } \ No newline at end of file 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 4920bef0..46541a94 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java @@ -28,9 +28,13 @@ 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.lang.reflect.TypeVariable; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -47,6 +51,10 @@ final class SqlHelper extends SQLiteOpenHelper { private static final int FIND_ALL_DATA = 5; private static final int DEL_DATA = 6; + private static final String MAP_FIELD = "map$$"; + private static final String LIST_FIELD = "list$$"; + private static final String GENERIC_FIELD = "Generic$$"; + private static volatile SqlHelper INSTANCE = null; static SqlHelper init(Context context) { @@ -186,12 +194,26 @@ final class SqlHelper extends SQLiteOpenHelper { sql = String.format(sql, params); print(FIND_DATA, sql); Cursor cursor = db.rawQuery(sql, null); - List data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null; + List data = cursor.getCount() > 0 ? newInstanceEntity(db, clazz, cursor) : null; cursor.close(); close(db); return data; } + /** + * 条件查寻数据 + */ + static synchronized List findData(SQLiteDatabase db, String tableName, + String... expression) { + Class clazz = null; + try { + clazz = (Class) Class.forName(tableName); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + return findData(db, clazz, expression); + } + /** * 条件查寻数据 */ @@ -215,7 +237,7 @@ final class SqlHelper extends SQLiteOpenHelper { } print(FIND_DATA, sb.toString()); Cursor cursor = db.rawQuery(sb.toString(), null); - List data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null; + List data = cursor.getCount() > 0 ? newInstanceEntity(db, clazz, cursor) : null; cursor.close(); close(db); return data; @@ -230,7 +252,7 @@ final class SqlHelper extends SQLiteOpenHelper { sb.append("SELECT rowid, * FROM ").append(CommonUtil.getClassName(clazz)); print(FIND_ALL_DATA, sb.toString()); Cursor cursor = db.rawQuery(sb.toString(), null); - List data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null; + List data = cursor.getCount() > 0 ? newInstanceEntity(db, clazz, cursor) : null; cursor.close(); close(db); return data; @@ -273,11 +295,22 @@ final class SqlHelper extends SQLiteOpenHelper { } sb.append(i > 0 ? ", " : ""); try { - Object value = field.get(dbEntity); - sb.append(field.getName()) - .append("='") - .append(value == null ? "" : value.toString()) - .append("'"); + String value; + sb.append(field.getName()).append("='"); + Type type = field.getType(); + if (type == Map.class) { + value = map2Str((Map) field.get(dbEntity)); + } else if (type == List.class) { + value = getListElementParams(field); + } else if (isOneToOne(field)) { + value = getOneToOneParams(field); + } else { + Object obj = field.get(dbEntity); + value = obj == null ? "" : obj.toString(); + } + + sb.append(value == null ? "" : value); + sb.append("'"); } catch (IllegalAccessException e) { e.printStackTrace(); } @@ -307,24 +340,35 @@ final class SqlHelper extends SQLiteOpenHelper { continue; } sb.append(i > 0 ? ", " : ""); + //sb.append(getFieldName(field.getType(), field)); sb.append(field.getName()); i++; } sb.append(") VALUES ("); i = 0; - for (Field field : fields) { - field.setAccessible(true); - if (ignoreField(field)) { - continue; + try { + for (Field field : fields) { + field.setAccessible(true); + if (ignoreField(field)) { + continue; + } + sb.append(i > 0 ? ", " : ""); + sb.append("'"); + Type type = field.getType(); + if (type == Map.class) { + sb.append(map2Str((Map) field.get(dbEntity))); + } else if (type == List.class) { + sb.append(getListElementParams(field)); + } else if (isOneToOne(field)) { + sb.append(getOneToOneParams(field)); + } else { + sb.append(field.get(dbEntity)); + } + sb.append("'"); + i++; } - sb.append(i > 0 ? ", " : ""); - sb.append("'"); - try { - sb.append(field.get(dbEntity)).append("'"); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - i++; + } catch (IllegalAccessException e) { + e.printStackTrace(); } sb.append(")"); print(INSERT_DATA, sb.toString()); @@ -333,6 +377,47 @@ final class SqlHelper extends SQLiteOpenHelper { close(db); } + /** + * 获取一对一参数 + */ + private 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反射字段 + */ + private static String getListElementParams(Field field) { + OneToMany oneToMany = field.getAnnotation(OneToMany.class); + if (oneToMany == null) { + throw new IllegalArgumentException("List中元素必须被@OneToMany注解"); + } + //关联的表名 + String tableName = oneToMany.table().getName(); + //关联的字段 + String key = oneToMany.key(); + return tableName + "$$" + key; + } + + /** + * 查找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; + } + /** * 查找表是否存在 * @@ -383,9 +468,13 @@ final class SqlHelper extends SQLiteOpenHelper { if (ignoreField(field)) { continue; } - sb.append(field.getName()); Class type = field.getType(); - if (type == String.class) { + sb.append(field.getName()); + if (type == String.class + || type == Map.class + || type == List.class + || isOneToOne(field) + || type.isEnum()) { sb.append(" varchar"); } else if (type == int.class || type == Integer.class) { sb.append(" interger"); @@ -404,6 +493,9 @@ final class SqlHelper extends SQLiteOpenHelper { } else { continue; } + if (isPrimary(field)) { + sb.append(" PRIMARY KEY"); + } sb.append(","); } String str = sb.toString(); @@ -414,15 +506,32 @@ final class SqlHelper extends SQLiteOpenHelper { close(db); } + ///** + // * 通过字段类型和获取保存在数据库表字段名 + // */ + //private static String getFieldName(Class type, Field field) { + // String fieldName; + // if (type == Map.class) { + // fieldName = MAP_FIELD + field.getName(); + // } else if (type == List.class) { + // fieldName = LIST_FIELD + field.getName(); + // } else if (isGeneric(field)) { + // fieldName = GENERIC_FIELD + field.getName(); + // } else { + // fieldName = field.getName(); + // } + // return fieldName; + //} + /** * 打印数据库日志 * * @param type {@link DbUtil} */ static void print(int type, String sql) { - if (true) { - return; - } + //if (true) { + // return; + //} String str = ""; switch (type) { case CREATE_TABLE: @@ -450,8 +559,8 @@ final class SqlHelper extends SQLiteOpenHelper { /** * 根据数据游标创建一个具体的对象 */ - static synchronized List newInstanceEntity(Class clazz, - Cursor cursor) { + private static synchronized List newInstanceEntity(SQLiteDatabase db, + Class clazz, Cursor cursor) { List fields = CommonUtil.getAllFields(clazz); List entitys = new ArrayList<>(); if (fields != null && fields.size() > 0) { @@ -482,8 +591,24 @@ final class SqlHelper extends SQLiteOpenHelper { field.set(entity, new Date(cursor.getString(column))); } else if (type == byte[].class) { field.set(entity, cursor.getBlob(column)); - } else { - continue; + } else if (type == Map.class) { + field.set(entity, str2Map(cursor.getString(column))); + } else if (type == List.class) { + //主键字段 + String primaryKey = getPrimaryName(clazz); + if (TextUtils.isEmpty(primaryKey)) { + throw new IllegalArgumentException("List中的元素对象必须需要@Primary注解的字段"); + } + //list字段保存的数据 + String params = cursor.getString(column); + field.set(entity, findForeignData(db, primaryKey, params)); + } else if (isOneToOne(field)) { + String primaryKey = getPrimaryName(clazz); + if (TextUtils.isEmpty(primaryKey)) { + throw new IllegalArgumentException("@OneToOne的注解对象必须需要@Primary注解的字段"); + } + String params = cursor.getString(column); + field.set(entity, findForeignData(db, primaryKey, params).get(0)); } } entity.rowID = cursor.getInt(cursor.getColumnIndex("rowid")); @@ -499,6 +624,50 @@ final class SqlHelper extends SQLiteOpenHelper { return entitys; } + /** + * 查找一对多、一对一的关联数据 + * + * @param primary 当前表的主键 + * @param childParams 当前表关联数据的类名 $$ 主键名 + */ + private static List findForeignData(SQLiteDatabase db, String primary, + String childParams) { + String[] params = childParams.split("$$"); + return findData(db, params[0], params[1] + "=?", primary); + } + + /** + * 字符串转Map,只支持 + *
+   *   {@code Map}
+   * 
+ */ + private static Map str2Map(String str) { + String[] element = str.split(","); + Map map = new HashMap<>(); + for (String data : element) { + String[] s = data.split("$"); + map.put(s[0], s[1]); + } + return map; + } + + /** + * Map转字符串,只支持 + *
+   *   {@code Map}
+   * 
+ */ + private 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(); } @@ -523,4 +692,28 @@ final class SqlHelper extends SQLiteOpenHelper { || Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers); } + + /** + * 判断是否一对多注解 + */ + private static boolean isOneToMany(Field field) { + OneToMany oneToMany = field.getAnnotation(OneToMany.class); + return oneToMany != null; + } + + /** + * 判断是否是一对一注解 + */ + private static boolean isOneToOne(Field field) { + OneToOne oneToOne = field.getAnnotation(OneToOne.class); + return oneToOne != null; + } + + /** + * 判断是否是主键 + */ + private 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/util/CommonUtil.java b/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java index 443daf8d..bceff11e 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java @@ -45,6 +45,11 @@ import java.util.Collections; import java.util.List; import java.util.Properties; import java.util.regex.Pattern; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.lang.reflect.WildcardType; /** * Created by lyy on 2016/1/22. @@ -52,6 +57,55 @@ import java.util.regex.Pattern; public class CommonUtil { private static final String TAG = "CommonUtil"; + /** + * 实例化泛型的实际类型参数 + * + * @throws Exception + */ + public static void typeCheck(Type type) throws Exception { + System.out.println("该类型是" + type); + // 参数化类型 + if (type instanceof ParameterizedType) { + Type[] typeArguments = ((ParameterizedType) type).getActualTypeArguments(); + for (int i = 0; i < typeArguments.length; i++) { + // 类型变量 + if (typeArguments[i] instanceof TypeVariable) { + System.out.println("第" + (i + 1) + "个泛型参数类型是类型变量" + typeArguments[i] + ",无法实例化。"); + } + // 通配符表达式 + else if (typeArguments[i] instanceof WildcardType) { + System.out.println("第" + (i + 1) + "个泛型参数类型是通配符表达式" + typeArguments[i] + ",无法实例化。"); + } + // 泛型的实际类型,即实际存在的类型 + else if (typeArguments[i] instanceof Class) { + System.out.println("第" + (i + 1) + "个泛型参数类型是:" + typeArguments[i] + ",可以直接实例化对象"); + } + } + // 参数化类型数组或类型变量数组 + } else if (type instanceof GenericArrayType) { + System.out.println("该泛型类型是参数化类型数组或类型变量数组,可以获取其原始类型。"); + Type componentType = ((GenericArrayType) type).getGenericComponentType(); + // 类型变量 + if (componentType instanceof TypeVariable) { + System.out.println("该类型变量数组的原始类型是类型变量" + componentType + ",无法实例化。"); + } + // 参数化类型,参数化类型数组或类型变量数组 + // 参数化类型数组或类型变量数组也可以是多维的数组,getGenericComponentType()方法仅仅是去掉最右边的[] + else { + // 递归调用方法自身 + typeCheck(componentType); + } + } else if (type instanceof TypeVariable) { + System.out.println("该类型是类型变量"); + } else if (type instanceof WildcardType) { + System.out.println("该类型是通配符表达式"); + } else if (type instanceof Class) { + System.out.println("该类型不是泛型类型"); + } else { + throw new Exception(); + } + } + /** * 根据下载任务组的url创建key * diff --git a/app/src/main/java/com/arialyy/simple/download/DownloadModule.java b/app/src/main/java/com/arialyy/simple/download/DownloadModule.java index f4c2e831..56ad3738 100644 --- a/app/src/main/java/com/arialyy/simple/download/DownloadModule.java +++ b/app/src/main/java/com/arialyy/simple/download/DownloadModule.java @@ -92,69 +92,4 @@ public class DownloadModule extends BaseModule { return entity; } - /** - * 下载广播过滤器 - */ - public IntentFilter getDownloadFilter() { - IntentFilter filter = new IntentFilter(); - filter.addDataScheme(getContext().getPackageName()); - filter.addAction(Aria.ACTION_PRE); - filter.addAction(Aria.ACTION_POST_PRE); - filter.addAction(Aria.ACTION_RESUME); - filter.addAction(Aria.ACTION_START); - filter.addAction(Aria.ACTION_RUNNING); - filter.addAction(Aria.ACTION_STOP); - filter.addAction(Aria.ACTION_CANCEL); - filter.addAction(Aria.ACTION_COMPLETE); - filter.addAction(Aria.ACTION_FAIL); - return filter; - } - - /** - * 创建Receiver - */ - public BroadcastReceiver createReceiver(final Handler handler) { - - return new BroadcastReceiver() { - long len = 0; - - @Override public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - switch (action) { - case Aria.ACTION_POST_PRE: - DownloadEntity entity = intent.getParcelableExtra(Aria.DOWNLOAD_ENTITY); - len = entity.getFileSize(); - L.d(TAG, "download onPre"); - handler.obtainMessage(SingleTaskActivity.DOWNLOAD_PRE, len).sendToTarget(); - break; - case Aria.ACTION_START: - L.d(TAG, "download start"); - break; - case Aria.ACTION_RESUME: - L.d(TAG, "download resume"); - long location = intent.getLongExtra(Aria.CURRENT_LOCATION, 1); - handler.obtainMessage(SingleTaskActivity.DOWNLOAD_RESUME, location).sendToTarget(); - break; - case Aria.ACTION_RUNNING: - long current = intent.getLongExtra(Aria.CURRENT_LOCATION, 0); - int progress = len == 0 ? 0 : (int) ((current * 100) / len); - handler.obtainMessage(SingleTaskActivity.DOWNLOAD_RUNNING, progress).sendToTarget(); - break; - case Aria.ACTION_STOP: - L.d(TAG, "download stop"); - handler.sendEmptyMessage(SingleTaskActivity.DOWNLOAD_STOP); - break; - case Aria.ACTION_COMPLETE: - handler.sendEmptyMessage(SingleTaskActivity.DOWNLOAD_COMPLETE); - break; - case Aria.ACTION_CANCEL: - handler.sendEmptyMessage(SingleTaskActivity.DOWNLOAD_CANCEL); - break; - case Aria.ACTION_FAIL: - handler.sendEmptyMessage(SingleTaskActivity.DOWNLOAD_FAILE); - break; - } - } - }; - } } \ No newline at end of file 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 aecbb8cf..8deb1624 100644 --- a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java @@ -246,7 +246,6 @@ public class SingleTaskActivity extends BaseActivity { setBtState(false); } mSize.setText(target.getConvertFileSize()); - Aria.get(this).getDownloadConfig().setOpenBreadCast(true); } public void onClick(View view) { diff --git a/aria/src/main/java/com/arialyy/aria/core/upload/UploadTaskEntity.java b/aria/src/main/java/com/arialyy/aria/core/upload/UploadTaskEntity.java index 5200e761..48f17ee7 100644 --- a/aria/src/main/java/com/arialyy/aria/core/upload/UploadTaskEntity.java +++ b/aria/src/main/java/com/arialyy/aria/core/upload/UploadTaskEntity.java @@ -15,7 +15,9 @@ */ package com.arialyy.aria.core.upload; +import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.inf.AbsTaskEntity; +import com.arialyy.aria.orm.OneToOne; import java.util.HashMap; import java.util.Map; @@ -29,7 +31,8 @@ public class UploadTaskEntity extends AbsTaskEntity { public String contentType = "multipart/form-data"; //上传的文件类型 public String userAgent = "User-Agent"; public String charset = "utf-8"; - + @OneToOne(table = UploadEntity.class, key = "filePath") public UploadEntity entity; + /** * 文件上传表单 */ @@ -39,4 +42,7 @@ public class UploadTaskEntity extends AbsTaskEntity { this.entity = entity; } + @Override public UploadEntity getEntity() { + return entity; + } }