修复,文件长度放在header中,Aria不识别的问题;修复单任务下载时有可能出现的进度条错误问题

pull/330/head
AriaLyy 7 years ago
parent f483f4d43f
commit 4514272f06
  1. 6
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java
  2. 11
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java
  3. 6
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FileInfoThread.java
  4. 2
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java
  5. 18
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/SingleThreadTask.java
  6. 61
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsDownloadTarget.java
  7. 14
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java
  8. 11
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java
  9. 2
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsUploadTarget.java
  10. 5
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java
  11. 4
      Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java
  12. 14
      Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java
  13. 257
      Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java
  14. 208
      Aria/src/main/java/com/arialyy/aria/orm/SqlUtil.java
  15. 3
      app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.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<DownloadGroupTarget, DownloadGroupEntity, DownloadGroupTaskEntity> {
extends AbsDownloadTarget<DownloadGroupTarget, DownloadGroupEntity, DownloadGroupTaskEntity> {
private List<String> mUrls = new ArrayList<>();
private final String TAG = "DownloadGroupTarget";
/**

@ -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<DownloadTarget, DownloadEntity, DownloadTaskEntity> {
extends AbsDownloadTarget<DownloadTarget, DownloadEntity, DownloadTaskEntity> {
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;
}
/**
* 下载任务是否存在

@ -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<String, List<String>> headers = conn.getHeaderFields();
if (!TextUtils.isEmpty(disposition)) {
mEntity.setDisposition(disposition);
if (disposition.contains(mTaskEntity.dispositionFileKey)) {

@ -98,7 +98,7 @@ public class SimpleDownloadUtil implements IDownloadUtil, Runnable {
}
})).start();
} else {
new Downloader(mListener, mTaskEntity).startDownload();
mDT.startDownload();
}
}
}

@ -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, "任务【"

@ -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<TARGET extends AbsTarget, ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity>
public abstract class AbsDownloadTarget<TARGET extends AbsTarget, ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity>
extends AbsTarget<TARGET, ENTITY, TASK_ENTITY> {
/**
* 如果你的下载链接的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<TARGET extends AbsTarget, ENTITY extends A
/**
* 重定向后新url的key默认为location
*/
protected void _setRedirectUrlKey(String redirectUrlKey) {
public void setRedirectUrlKey(String redirectUrlKey) {
if (TextUtils.isEmpty(redirectUrlKey)) {
Log.w("AbsNormalTarget", "重定向后,新url的key不能为null");
Log.w("AbsDownloadTarget", "重定向后,新url的key不能为null");
return;
}
mTaskEntity.redirectUrlKey = redirectUrlKey;
}
/**
* 删除记录
*/
public void removeRecord() {
mEntity.deleteData();
}
/**
* 获取任务文件大小
*
@ -70,7 +103,6 @@ public abstract class AbsNormalTarget<TARGET extends AbsTarget, ENTITY extends A
return getSize();
}
/**
* 获取单位转换后的文件大小
*
@ -80,13 +112,6 @@ public abstract class AbsNormalTarget<TARGET extends AbsTarget, ENTITY extends A
return getConvertSize();
}
/**
* 下载任务是否存在
*/
public boolean taskExists() {
return false;
}
/**
* 添加任务
*/

@ -34,6 +34,20 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
protected TASK_ENTITY mTaskEntity;
protected String mTargetName;
/**
* 删除记录
*/
public void removeRecord() {
mEntity.deleteData();
}
/**
* 任务是否存在
*/
public boolean taskExists() {
return false;
}
/**
* 获取任务进度如果任务存在则返回当前进度
*

@ -43,17 +43,17 @@ public abstract class AbsTaskEntity<ENTITY extends AbsEntity> 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<ENTITY extends AbsEntity> extends DbEntity {
*/
public String dispositionFileKey = "attachment;filename";
/**
* 从header中含有的文件长度信息所需要的key
*/
public String contentLength = "Content-Length";
/**
* 重定向链接
*/

@ -19,7 +19,7 @@ package com.arialyy.aria.core.inf;
* Created by AriaL on 2017/6/29.
* 任务组超类
*/
public abstract class AbsGroupTarget<TARGET extends AbsGroupTarget, ENTITY extends AbsGroupEntity, TASK_ENTITY extends AbsTaskEntity>
public abstract class AbsUploadTarget<TARGET extends AbsUploadTarget, ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity>
extends AbsTarget<TARGET, ENTITY, TASK_ENTITY> {

@ -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<UploadTarget, UploadEntity, UploadTaskEntity> {
public class UploadTarget extends AbsUploadTarget<UploadTarget, UploadEntity, UploadTaskEntity> {
UploadTarget(String filePath, String targetName) {
this.mTargetName = targetName;

@ -29,10 +29,10 @@ import java.util.Map;
* Created by lyy on 2017/4/6.
* 数据库配置信息
*/
public class DBConfig {
class DBConfig {
static Map<String, Class> mapping = new HashMap<>();
static String DB_NAME;
static int VERSION = 10;
static int VERSION = 11;
static {
if (TextUtils.isEmpty(DB_NAME)) {

@ -170,21 +170,21 @@ public class DbEntity {
List<String> 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<String, String>) field.get(this)));
values.add(SqlUtil.map2Str((Map<String, String>) field.get(this)));
} else {
values.add(field.get(this) + "");
}

@ -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<String> 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<String> 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<String, String>) field.get(dbEntity));
value = SqlUtil.map2Str((Map<String, String>) 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<String, String>) field.get(dbEntity)));
sb.append(SqlUtil.map2Str((Map<String, String>) 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<? extends DbEntity> clazz) {
List<Field> 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只支持
* <pre>
* {@code Map<String, String>}
* </pre>
*/
private static Map<String, String> str2Map(String str) {
Map<String, String> 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转字符串只支持
* <pre>
* {@code Map<String, String>}
* </pre>
*/
static String map2Str(Map<String, String> map) {
StringBuilder sb = new StringBuilder();
Set<String> 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;
}
}

@ -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只支持
* <pre>
* {@code Map<String, String>}
* </pre>
*/
static Map<String, String> str2Map(String str) {
Map<String, String> 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转字符串只支持
* <pre>
* {@code Map<String, String>}
* </pre>
*/
static String map2Str(Map<String, String> map) {
StringBuilder sb = new StringBuilder();
Set<String> 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<? extends DbEntity> clazz) {
List<Field> fields = CommonUtil.getAllFields(clazz);
for (Field field : fields) {
if (isPrimary(field)) return field.getName();
}
return null;
}
}

@ -41,7 +41,8 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
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";

Loading…
Cancel
Save