From d5ccb3c8f60d22c032eb35d6422f70206e93c52b Mon Sep 17 00:00:00 2001 From: liuyuchuan Date: Wed, 12 Jun 2019 16:55:18 +0800 Subject: [PATCH] 1. new api: error translator set and do 2. use errorCode instead errorMessage 3. remove customer headers 4. update readme --- README.md | 9 +- config.gradle | 2 +- .../java/com/lyc/downloader/DBTest.java | 32 --- .../com/lyc/downloader/IDownloadCallback.aidl | 2 +- .../com/lyc/downloader/IDownloadService.aidl | 2 +- .../lyc/downloader/BaseServiceManager.java | 5 +- .../lyc/downloader/DownloadController.java | 4 +- .../com/lyc/downloader/DownloadError.java | 4 +- .../com/lyc/downloader/DownloadListener.java | 2 +- .../DownloadListenerDispatcher.java | 11 +- .../com/lyc/downloader/DownloadManager.java | 45 +-- .../java/com/lyc/downloader/DownloadTask.java | 45 +-- .../lyc/downloader/LocalDownloadService.java | 10 +- .../java/com/lyc/downloader/PersistUtil.java | 54 +--- .../lyc/downloader/RemoteDownloadService.java | 10 +- .../java/com/lyc/downloader/YCDownloader.java | 35 ++- .../com/lyc/downloader/db/CustomerHeader.java | 80 ------ .../com/lyc/downloader/db/DownloadInfo.java | 269 +++++++----------- .../lyc/yuchuan_downloader/DownloadItem.kt | 2 +- .../DownloadItemViewBinder.kt | 3 +- .../lyc/yuchuan_downloader/MainViewModel.kt | 8 +- 21 files changed, 209 insertions(+), 425 deletions(-) delete mode 100644 downloader/src/main/java/com/lyc/downloader/db/CustomerHeader.java diff --git a/README.md b/README.md index 2a2b373..3804980 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ allprojects { ``` dependencies { - implementation 'com.github.SirLYC:Yuchuan-Downloader:latest.release' + implementation 'com.github.SirLYC:Yuchuan-Downloader:latest.release' } ``` @@ -104,18 +104,17 @@ private SubmitListener submitListener = new SubmitListener() { }; // path: parent directory to store your file // filename: can be null; if not null, downloader will use it to save your file -// customerHeaders: Map -YCDownloader.submit(url, path, filename, customerHeaders, submitListener); +YCDownloader.submit(url, path, filename, submitListener); ``` **listen to download progress or state change** ``` DownloadListener downloadListener = ...; -YCDownloader.register(downloadListener); +YCDownloader.registerDownloadListener(downloadListener); // you should unregister it to avoid memory leak // such as Activity.OnDestroy -YCDownloader.unregister(downloadListener); +YCDownloader.unregisterDownloadListener(downloadListener); ``` **query download info** diff --git a/config.gradle b/config.gradle index 4616d84..6921eb8 100644 --- a/config.gradle +++ b/config.gradle @@ -7,7 +7,7 @@ ext { 'targetSdkVersion' : 28, 'minSdkVersion' : 19, 'versionCode' : 1, - 'versionName' : '0.1.0-beta' + 'versionName' : '0.2.0-beta' ] deps = [ 'kotlin-stdlib' : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version", diff --git a/downloader/src/androidTest/java/com/lyc/downloader/DBTest.java b/downloader/src/androidTest/java/com/lyc/downloader/DBTest.java index ecc01a2..1f7e69e 100644 --- a/downloader/src/androidTest/java/com/lyc/downloader/DBTest.java +++ b/downloader/src/androidTest/java/com/lyc/downloader/DBTest.java @@ -4,8 +4,6 @@ import android.database.sqlite.SQLiteDatabase; import androidx.test.core.app.ApplicationProvider; import androidx.test.runner.AndroidJUnit4; -import com.lyc.downloader.db.CustomerHeader; -import com.lyc.downloader.db.CustomerHeaderDao; import com.lyc.downloader.db.DaoMaster; import com.lyc.downloader.db.DaoMaster.DevOpenHelper; import com.lyc.downloader.db.DaoSession; @@ -58,36 +56,11 @@ public void testDB() { DownloadInfoDao downloadInfoDao = daoSession.getDownloadInfoDao(); DownloadInfo downloadInfo = new DownloadInfo(null, "http", "file", "name", true, 0, 0, 0, null, new Date(), null, null); - List customerHeaders = new ArrayList<>(); - customerHeaders.add(new CustomerHeader(null, 0, "A", "A")); - customerHeaders.add(new CustomerHeader(null, 0, "B", "A")); - customerHeaders.add(new CustomerHeader(null, 0, "C", "A")); - customerHeaders.add(new CustomerHeader(null, 0, "D", "A")); long id = downloadInfoDao.insert(downloadInfo); Assert.assertEquals(new Long(id), downloadInfo.getId()); Assert.assertEquals(1, downloadInfoDao.loadAll().size()); - Assert.assertEquals(0, downloadInfo.getCustomerHeaders().size()); Assert.assertEquals(0, downloadInfo.getDownloadThreadInfos().size()); - for (CustomerHeader customerHeader : customerHeaders) { - customerHeader.setDownloadInfoId(id); - } - - CustomerHeaderDao customerHeaderDao = daoSession.getCustomerHeaderDao(); - customerHeaderDao.saveInTx(customerHeaders); - Assert.assertEquals(customerHeaders.size(), customerHeaderDao.loadAll().size()); - - for (CustomerHeader customerHeader : customerHeaders) { - Assert.assertNotEquals(null, customerHeader.getDownloadInfoId()); - } - - for (int i = 1; i < customerHeaders.size(); i++) { - Assert.assertNotEquals(customerHeaders.get(i - 1).getId(), customerHeaders.get(i).getId()); - } - - Assert.assertEquals(0, downloadInfo.getCustomerHeaders().size()); - downloadInfo.resetCustomerHeaders(); - Assert.assertEquals(downloadInfo.getCustomerHeaders().size(), customerHeaders.size()); List downloadThreadInfoList = new ArrayList<>(); for (int i = 0; i < 4; i++) { @@ -95,7 +68,6 @@ public void testDB() { } DownloadThreadInfoDao downloadThreadInfoDao = daoSession.getDownloadThreadInfoDao(); downloadThreadInfoDao.saveInTx(downloadThreadInfoList); - Assert.assertEquals(downloadThreadInfoList.size(), customerHeaderDao.loadAll().size()); for (int i = 1; i < downloadThreadInfoList.size(); i++) { Assert.assertNotEquals(downloadThreadInfoList.get(i - 1), downloadThreadInfoList.get(i)); @@ -106,9 +78,6 @@ public void testDB() { Assert.assertEquals(downloadThreadInfoList.size(), downloadInfo.getDownloadThreadInfos().size()); daoSession.runInTx(() -> { - for (CustomerHeader customerHeader : downloadInfo.getCustomerHeaders()) { - customerHeaderDao.delete(customerHeader); - } downloadThreadInfoDao.deleteInTx(downloadThreadInfoList); for (DownloadThreadInfo downloadThreadInfo : downloadInfo.getDownloadThreadInfos()) { @@ -120,6 +89,5 @@ public void testDB() { Assert.assertEquals(downloadInfoDao.loadAll().size(), 0); Assert.assertEquals(downloadThreadInfoDao.loadAll().size(), 0); - Assert.assertEquals(customerHeaderDao.loadAll().size(), 0); } } diff --git a/downloader/src/main/aidl/com/lyc/downloader/IDownloadCallback.aidl b/downloader/src/main/aidl/com/lyc/downloader/IDownloadCallback.aidl index 3af6170..109687c 100644 --- a/downloader/src/main/aidl/com/lyc/downloader/IDownloadCallback.aidl +++ b/downloader/src/main/aidl/com/lyc/downloader/IDownloadCallback.aidl @@ -11,7 +11,7 @@ interface IDownloadCallback { void onUpdateInfo(inout DownloadInfo downloadInfo); - void onDownloadError(long id, String reason, boolean fatal); + void onDownloadError(long id, int code, boolean fatal); void onDownloadStart(inout DownloadInfo downloadInfo); diff --git a/downloader/src/main/aidl/com/lyc/downloader/IDownloadService.aidl b/downloader/src/main/aidl/com/lyc/downloader/IDownloadService.aidl index 30e0f5f..8067f60 100644 --- a/downloader/src/main/aidl/com/lyc/downloader/IDownloadService.aidl +++ b/downloader/src/main/aidl/com/lyc/downloader/IDownloadService.aidl @@ -11,7 +11,7 @@ interface IDownloadService { void removeDownloadCallback(IDownloadCallback callback); - void submit(String url, String path, String filename, in Map customerHeaders, ISubmitCallback callback); + void submit(String url, String path, String filename, ISubmitCallback callback); DownloadInfo queryDownloadInfo(long id); diff --git a/downloader/src/main/java/com/lyc/downloader/BaseServiceManager.java b/downloader/src/main/java/com/lyc/downloader/BaseServiceManager.java index 1ccffdc..d18b5ea 100644 --- a/downloader/src/main/java/com/lyc/downloader/BaseServiceManager.java +++ b/downloader/src/main/java/com/lyc/downloader/BaseServiceManager.java @@ -11,7 +11,6 @@ import com.lyc.downloader.utils.Logger; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -152,11 +151,11 @@ public void cancel(long id) { } @Override - public void submit(String url, String path, String filename, Map customerHeaders, SubmitListener listener) { + public void submit(String url, String path, String filename, SubmitListener listener) { DownloadExecutors.command.execute(() -> { waitingForConnection(); try { - downloadService.submit(url, path, filename, customerHeaders, new Stub() { + downloadService.submit(url, path, filename, new Stub() { @Override public void submitSuccess(DownloadInfo downloadInfo) { DownloadExecutors.androidMain.execute(() -> listener.submitSuccess(downloadInfo)); diff --git a/downloader/src/main/java/com/lyc/downloader/DownloadController.java b/downloader/src/main/java/com/lyc/downloader/DownloadController.java index 7d80071..bc11362 100644 --- a/downloader/src/main/java/com/lyc/downloader/DownloadController.java +++ b/downloader/src/main/java/com/lyc/downloader/DownloadController.java @@ -1,7 +1,5 @@ package com.lyc.downloader; -import java.util.Map; - /** * Created by Liu Yuchuan on 2019/5/18. */ @@ -17,7 +15,7 @@ public interface DownloadController { void cancel(long id); - void submit(String url, String path, String filename, Map customerHeaders, SubmitListener listener); + void submit(String url, String path, String filename, SubmitListener listener); void delete(long id, boolean deleteFile); diff --git a/downloader/src/main/java/com/lyc/downloader/DownloadError.java b/downloader/src/main/java/com/lyc/downloader/DownloadError.java index 779cd74..59d1a65 100644 --- a/downloader/src/main/java/com/lyc/downloader/DownloadError.java +++ b/downloader/src/main/java/com/lyc/downloader/DownloadError.java @@ -33,7 +33,7 @@ public class DownloadError { private DownloadError() { } - public static DownloadError instance() { + static DownloadError instance() { return instance; } @@ -41,7 +41,7 @@ boolean isFatal(int code) { return code >= 100; } - public void setTranslator(Translator translator) { + void setTranslator(Translator translator) { if (translator == null) { throw new NullPointerException("DownloadError#translator cannot be null"); } diff --git a/downloader/src/main/java/com/lyc/downloader/DownloadListener.java b/downloader/src/main/java/com/lyc/downloader/DownloadListener.java index f7adfc8..17030fb 100644 --- a/downloader/src/main/java/com/lyc/downloader/DownloadListener.java +++ b/downloader/src/main/java/com/lyc/downloader/DownloadListener.java @@ -16,7 +16,7 @@ public interface DownloadListener { void onUpdateInfo(DownloadInfo downloadInfo); - void onDownloadError(long id, String reason, boolean fatal); + void onDownloadError(long id, int code, boolean fatal); void onDownloadStart(DownloadInfo downloadInfo); diff --git a/downloader/src/main/java/com/lyc/downloader/DownloadListenerDispatcher.java b/downloader/src/main/java/com/lyc/downloader/DownloadListenerDispatcher.java index 7a64fd6..c6b3b33 100644 --- a/downloader/src/main/java/com/lyc/downloader/DownloadListenerDispatcher.java +++ b/downloader/src/main/java/com/lyc/downloader/DownloadListenerDispatcher.java @@ -3,7 +3,12 @@ import android.annotation.SuppressLint; import com.lyc.downloader.db.DownloadInfo; -import java.util.*; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; /** * @author liuyuchuan @@ -123,14 +128,14 @@ public void onUpdateInfo(DownloadInfo downloadInfo) { } @Override - public void onDownloadError(long id, String reason, boolean fatal) { + public void onDownloadError(long id, int code, boolean fatal) { Collection downloadListeners = getDispatchListeners(id); if (downloadListeners.isEmpty()) { return; } DownloadExecutors.androidMain.execute(() -> { for (DownloadListener downloadListener : downloadListeners) { - downloadListener.onDownloadError(id, reason, fatal); + downloadListener.onDownloadError(id, code, fatal); } }); } diff --git a/downloader/src/main/java/com/lyc/downloader/DownloadManager.java b/downloader/src/main/java/com/lyc/downloader/DownloadManager.java index 65059d3..436e706 100644 --- a/downloader/src/main/java/com/lyc/downloader/DownloadManager.java +++ b/downloader/src/main/java/com/lyc/downloader/DownloadManager.java @@ -5,8 +5,11 @@ import android.database.sqlite.SQLiteDatabase; import androidx.annotation.WorkerThread; import androidx.collection.LongSparseArray; -import com.lyc.downloader.db.*; +import com.lyc.downloader.db.DaoMaster; import com.lyc.downloader.db.DaoMaster.DevOpenHelper; +import com.lyc.downloader.db.DaoSession; +import com.lyc.downloader.db.DownloadInfo; +import com.lyc.downloader.db.DownloadInfoDao; import com.lyc.downloader.utils.Logger; import com.lyc.downloader.utils.UniqueDequeue; import okhttp3.OkHttpClient; @@ -15,7 +18,11 @@ import okhttp3.logging.HttpLoggingInterceptor.Level; import java.lang.ref.WeakReference; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.Deque; +import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -81,12 +88,6 @@ static DownloadManager instance() { return instance; } - void registerTask(DownloadTask downloadTask) { - Long id = downloadTask.downloadInfo.getId(); - taskTable.put(id, downloadTask); - infoTable.put(id, downloadTask.downloadInfo); - } - private void pauseAllInner() { for (Long aLong : waitingTasksId) { DownloadTask downloadTask = taskTable.get(aLong); @@ -254,7 +255,7 @@ public void onUpdateInfo(DownloadInfo downloadInfo) { } @Override - public void onDownloadError(long id, String reason, boolean fatal) { + public void onDownloadError(long id, int code, boolean fatal) { DownloadExecutors.message.execute(() -> { lastSendMessageTime.remove(id); DownloadTask downloadTask = taskTable.get(id); @@ -265,7 +266,7 @@ public void onDownloadError(long id, String reason, boolean fatal) { if (userDownloadListener != null) { DownloadListener downloadListener = userDownloadListener.get(); if (downloadListener != null) { - downloadListener.onDownloadError(id, reason, fatal); + downloadListener.onDownloadError(id, code, fatal); } } }); @@ -391,11 +392,11 @@ public void onDownloadFinished(DownloadInfo downloadInfo) { } @WorkerThread - private void submitInner(String url, String path, String filename, List customerHeaders, SubmitListener listener) { + private void submitInner(String url, String path, String filename, SubmitListener listener) { DownloadInfo downloadInfo = new DownloadInfo(null, url, path, filename, true, WAITING, 0, 0, null, new Date(), null, null); try { - Long insertId = PersistUtil.persistDownloadInfo(daoSession, downloadInfo, null, customerHeaders); + Long insertId = PersistUtil.persistDownloadInfo(daoSession, downloadInfo, null); DownloadExecutors.message.execute(() -> { if (insertId != null) { infoTable.put(insertId, downloadInfo); @@ -425,13 +426,6 @@ public void startAll() { DownloadExecutors.message.execute(this::startAllInner); } - public void end() { - DownloadExecutors.message.execute(() -> { - instance = null; - pauseAll(); - }); - } - // include re-download @Override public void startOrResume(long id, boolean restart) { @@ -480,24 +474,15 @@ public void cancel(long id) { * @param url download url; must started with http/https * @param path nonnull; parent directory of the file * @param filename self-defined filename; if null, it will be parsed by url or a pivot request by downloadManager - * @param customerHeaders customer header (`Range` will be removed) * @param listener listener to inform submit success or fail */ @Override - public void submit(String url, String path, String filename, Map customerHeaders, SubmitListener listener) { + public void submit(String url, String path, String filename, SubmitListener listener) { waitForRecovering(); - List headers = new ArrayList<>(); - if (customerHeaders != null) { - for (String s : customerHeaders.keySet()) { - if (s != null && !s.equalsIgnoreCase("range")) { - headers.add(new CustomerHeader(null, 0, s, customerHeaders.get(s))); - } - } - } if (path == null) { throw new NullPointerException("path cannot be null"); } - DownloadExecutors.io.execute(() -> submitInner(url, path, filename, headers, listener)); + DownloadExecutors.io.execute(() -> submitInner(url, path, filename, listener)); } @Override diff --git a/downloader/src/main/java/com/lyc/downloader/DownloadTask.java b/downloader/src/main/java/com/lyc/downloader/DownloadTask.java index d127c47..74c09f6 100644 --- a/downloader/src/main/java/com/lyc/downloader/DownloadTask.java +++ b/downloader/src/main/java/com/lyc/downloader/DownloadTask.java @@ -3,18 +3,29 @@ import android.util.SparseArray; import androidx.annotation.IntDef; import androidx.annotation.WorkerThread; -import com.lyc.downloader.db.CustomerHeader; import com.lyc.downloader.db.DownloadInfo; import com.lyc.downloader.db.DownloadThreadInfo; import com.lyc.downloader.utils.DownloadStringUtil; import com.lyc.downloader.utils.Logger; -import okhttp3.*; +import okhttp3.Call; +import okhttp3.OkHttpClient; +import okhttp3.Request; import okhttp3.Request.Builder; - -import java.io.*; +import okhttp3.Response; +import okhttp3.ResponseBody; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.*; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.Set; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -126,11 +137,6 @@ int getState() { private boolean buildBaseRequest() { Builder builder = new Builder(); - for (CustomerHeader customerHeader : downloadInfo.getCustomerHeaders()) { - if (customerHeader.getKey() != null && customerHeader.getValue() != null) { - builder.header(customerHeader.getKey(), customerHeader.getValue()); - } - } try { builder.url(downloadInfo.getUrl()); } catch (Exception e) { @@ -260,7 +266,6 @@ private boolean doPivotCall() { PersistUtil.persistDownloadInfoQuietly( downloadManager.daoSession, downloadInfo, - null, null ); downloadListener.onUpdateInfo(downloadInfo); @@ -447,7 +452,6 @@ private void stateChange() { PersistUtil.persistDownloadInfoQuietly( downloadManager.daoSession, downloadInfo, - null, null ); } @@ -469,7 +473,7 @@ void toWait(boolean restart) { downloadInfo.getCreatedTime().setTime(System.currentTimeMillis()); downloadInfo.setDownloadedSize(0); DownloadExecutors.io.execute(() -> { - PersistUtil.persistDownloadInfoQuietly(downloadManager.daoSession, downloadInfo, new SparseArray<>(0), Collections.emptyList()); + PersistUtil.persistDownloadInfoQuietly(downloadManager.daoSession, downloadInfo, new SparseArray<>(0)); PersistUtil.deleteFile(downloadInfo, true); stateChange(); downloadListener.onDownloadTaskWait(downloadInfo.getId()); @@ -608,7 +612,7 @@ private boolean initDownloadInfo() { downloadBuffer); } if (!deleted.get()) { - PersistUtil.persistDownloadInfoQuietly(downloadManager.daoSession, downloadInfo, downloadThreadInfos, null); + PersistUtil.persistDownloadInfoQuietly(downloadManager.daoSession, downloadInfo, downloadThreadInfos); } return true; } @@ -742,8 +746,7 @@ private void reportError(int code) { boolean fatal = downloadError.isFatal(code); Logger.e(TAG, "error: " + downloadError.translate(code) + "; isFatal: " + fatal + "; task is\n" + downloadInfo); - String errorMessage = downloadError.translate(code); - downloadInfo.setErrorMsg(errorMessage); + downloadInfo.setErrorCode(code); if (fatal) { state = FATAL_ERROR; if (downloadFile != null && downloadFile.exists() && !downloadFile.delete()) { @@ -753,12 +756,12 @@ private void reportError(int code) { .getDownloadThreadInfoDao().deleteInTx(downloadInfo.getDownloadThreadInfos()); downloadInfo.getDownloadThreadInfos().clear(); stateChange(); - downloadListener.onDownloadError(downloadInfo.getId(), errorMessage, true); + downloadListener.onDownloadError(downloadInfo.getId(), code, true); } else { state = ERROR; preparedForResuming(); stateChange(); - downloadListener.onDownloadError(downloadInfo.getId(), errorMessage, false); + downloadListener.onDownloadError(downloadInfo.getId(), code, false); } } finally { stateLock.unlock(); @@ -814,8 +817,7 @@ private boolean checkEnd() { PersistUtil.persistDownloadInfoQuietly( downloadManager.daoSession, downloadInfo, - downloadThreadInfos, - null + downloadThreadInfos ); } return result; @@ -1178,8 +1180,7 @@ public void run() { PersistUtil.persistDownloadInfoQuietly( downloadManager.daoSession, downloadInfo, - downloadThreadInfos, - null + downloadThreadInfos ); } downloadListener.onProgressUpdate(downloadInfo.getId(), downloadInfo.getTotalSize(), current, bps); diff --git a/downloader/src/main/java/com/lyc/downloader/LocalDownloadService.java b/downloader/src/main/java/com/lyc/downloader/LocalDownloadService.java index a9f1dfe..185ff0f 100644 --- a/downloader/src/main/java/com/lyc/downloader/LocalDownloadService.java +++ b/downloader/src/main/java/com/lyc/downloader/LocalDownloadService.java @@ -10,7 +10,6 @@ import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; /** @@ -84,11 +83,11 @@ public void onUpdateInfo(DownloadInfo downloadInfo) { } @Override - public void onDownloadError(long id, String reason, boolean fatal) { + public void onDownloadError(long id, int code, boolean fatal) { synchronized (downloadCallbacks) { for (IDownloadCallback downloadCallback : downloadCallbacks) { try { - downloadCallback.onDownloadError(id, reason, fatal); + downloadCallback.onDownloadError(id, code, fatal); } catch (RemoteException e) { // do nothing } @@ -196,9 +195,8 @@ public void removeDownloadCallback(IDownloadCallback callback) { } @Override - public void submit(String url, String path, String filename, Map customerHeaders, ISubmitCallback callback) { - //noinspection unchecked - downloadManager.submit(url, path, filename, customerHeaders, new SubmitListener() { + public void submit(String url, String path, String filename, ISubmitCallback callback) { + downloadManager.submit(url, path, filename, new SubmitListener() { @Override public void submitSuccess(DownloadInfo downloadInfo) { try { diff --git a/downloader/src/main/java/com/lyc/downloader/PersistUtil.java b/downloader/src/main/java/com/lyc/downloader/PersistUtil.java index e30c6f3..ee6c9fc 100644 --- a/downloader/src/main/java/com/lyc/downloader/PersistUtil.java +++ b/downloader/src/main/java/com/lyc/downloader/PersistUtil.java @@ -1,8 +1,6 @@ package com.lyc.downloader; import android.util.SparseArray; -import com.lyc.downloader.db.CustomerHeader; -import com.lyc.downloader.db.CustomerHeaderDao; import com.lyc.downloader.db.DaoSession; import com.lyc.downloader.db.DownloadInfo; import com.lyc.downloader.db.DownloadInfoDao; @@ -21,28 +19,6 @@ */ class PersistUtil { - private static final Comparator HEADER_COMPARATOR = (o1, o2) -> { - if (o1 == null) { - return o2 == null ? 0 : -1; - } - - if (o2 == null) { - return 1; - } - - Long id1 = o1.getId(); - Long id2 = o2.getId(); - if (id1 == null) { - return id2 == null ? 0 : -1; - } - - if (id2 == null) { - return 1; - } - - return Long.compare(id1, id2); - }; - private static final Comparator THREAD_INFO_COMPARATOR = (o1, o2) -> { if (o1 == null) { return o2 == null ? 0 : -1; @@ -66,24 +42,21 @@ class PersistUtil { }; static void persistDownloadInfoQuietly(DaoSession daoSession, DownloadInfo downloadInfo, - SparseArray downloadThreadInfos, - List customerHeaderList) { + SparseArray downloadThreadInfos) { try { - persistDownloadInfo(daoSession, downloadInfo, downloadThreadInfos, customerHeaderList); + persistDownloadInfo(daoSession, downloadInfo, downloadThreadInfos); } catch (Exception e) { Logger.e("PersistUtil", "cannot persist downloadInfo", e); } } static Long persistDownloadInfo(DaoSession daoSession, DownloadInfo downloadInfo, - SparseArray downloadThreadInfos, - List customerHeaderList) throws Exception { + SparseArray downloadThreadInfos) throws Exception { if (downloadInfo == null) { return null; } DownloadInfoDao downloadInfoDao = daoSession.getDownloadInfoDao(); DownloadThreadInfoDao downloadThreadInfoDao = daoSession.getDownloadThreadInfoDao(); - CustomerHeaderDao customerHeaderDao = daoSession.getCustomerHeaderDao(); return daoSession.callInTx(() -> { downloadInfoDao.save(downloadInfo); Long infoId = downloadInfo.getId(); @@ -91,21 +64,6 @@ static Long persistDownloadInfo(DaoSession daoSession, DownloadInfo downloadInfo return null; } - if (customerHeaderList != null) { - downloadInfo.resetCustomerHeaders(); - List oldHeaders = downloadInfo.getCustomerHeaders(); - Collections.sort(oldHeaders, HEADER_COMPARATOR); - Collections.sort(customerHeaderList, HEADER_COMPARATOR); - if (!oldHeaders.equals(customerHeaderList)) { - for (CustomerHeader oldHeader : oldHeaders) { - customerHeaderDao.delete(oldHeader); - } - for (CustomerHeader customerHeader : customerHeaderList) { - customerHeader.setDownloadInfoId(infoId); - customerHeaderDao.save(customerHeader); - } - } - } if (downloadThreadInfos != null) { downloadInfo.resetDownloadThreadInfos(); List oldDownloadThreadInfos = downloadInfo.getDownloadThreadInfos(); @@ -142,10 +100,8 @@ static void deleteDownloadInfo(DaoSession daoSession, DownloadInfo downloadInfo) } downloadInfo.resetDownloadThreadInfos(); - downloadInfo.resetCustomerHeaders(); DownloadInfoDao downloadInfoDao = daoSession.getDownloadInfoDao(); DownloadThreadInfoDao downloadThreadInfoDao = daoSession.getDownloadThreadInfoDao(); - CustomerHeaderDao customerHeaderDao = daoSession.getCustomerHeaderDao(); try { daoSession.callInTx(() -> { downloadInfoDao.delete(downloadInfo); @@ -153,10 +109,6 @@ static void deleteDownloadInfo(DaoSession daoSession, DownloadInfo downloadInfo) .where(DownloadThreadInfoDao.Properties.DownloadInfoId.eq(downloadInfo.getId())) .buildDelete() .executeDeleteWithoutDetachingEntities(); - customerHeaderDao.queryBuilder() - .where(CustomerHeaderDao.Properties.DownloadInfoId.eq(downloadInfo.getId())) - .buildDelete() - .executeDeleteWithoutDetachingEntities(); return null; }); } catch (Exception e) { diff --git a/downloader/src/main/java/com/lyc/downloader/RemoteDownloadService.java b/downloader/src/main/java/com/lyc/downloader/RemoteDownloadService.java index a8e2a44..09f8d79 100644 --- a/downloader/src/main/java/com/lyc/downloader/RemoteDownloadService.java +++ b/downloader/src/main/java/com/lyc/downloader/RemoteDownloadService.java @@ -10,7 +10,6 @@ import com.lyc.downloader.utils.Logger; import java.util.List; -import java.util.Map; /** * @author liuyuchuan @@ -34,10 +33,9 @@ public void removeDownloadCallback(IDownloadCallback callback) { } @Override - public void submit(String url, String path, String filename, Map customerHeaders, ISubmitCallback callback) { + public void submit(String url, String path, String filename, ISubmitCallback callback) { Logger.d("RemoteDownloadService", "submit " + url); - //noinspection unchecked - downloadManager.submit(url, path, filename, customerHeaders, new SubmitListener() { + downloadManager.submit(url, path, filename, new SubmitListener() { @Override public void submitSuccess(DownloadInfo downloadInfo) { try { @@ -201,12 +199,12 @@ public void onUpdateInfo(DownloadInfo downloadInfo) { } @Override - public void onDownloadError(long id, String reason, boolean fatal) { + public void onDownloadError(long id, int code, boolean fatal) { int n = downloadCallbackList.beginBroadcast(); for (int i = 0; i < n; i++) { IDownloadCallback broadcastItem = downloadCallbackList.getBroadcastItem(i); try { - broadcastItem.onDownloadError(id, reason, fatal); + broadcastItem.onDownloadError(id, code, fatal); } catch (RemoteException e) { Logger.e(TAG, "send downloadError event for task#" + id + " failed.", e); } diff --git a/downloader/src/main/java/com/lyc/downloader/YCDownloader.java b/downloader/src/main/java/com/lyc/downloader/YCDownloader.java index c59b9a9..f6cdd19 100644 --- a/downloader/src/main/java/com/lyc/downloader/YCDownloader.java +++ b/downloader/src/main/java/com/lyc/downloader/YCDownloader.java @@ -6,7 +6,6 @@ import com.lyc.downloader.db.DownloadInfo; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -149,16 +148,14 @@ public static void cancel(long id) { /** * submit a task to downloader service * - * @param url Download url, only HTTP or HTTPS supported for now. - * @param path Parent directory to save the downloaded file - * @param filename Downloaded filename, nullable. If it's null, the name will be decided by downloader - * service and inform caller by {@link DownloadListener} - * @param customerHeaders CustomerHeaders in HTTP. Note that key `range` will be remove from it because - * the downloader need it. - * @param listener the listener inform caller the result of this commit. + * @param url Download url, only HTTP or HTTPS supported for now. + * @param path Parent directory to save the downloaded file + * @param filename Downloaded filename, nullable. If it's null, the name will be decided by downloader + * service and inform caller by {@link DownloadListener} + * @param listener the listener inform caller the result of this commit. */ - public static void submit(String url, String path, String filename, Map customerHeaders, SubmitListener listener) { - serviceManager.submit(url, path, filename, customerHeaders, listener); + public static void submit(String url, String path, String filename, SubmitListener listener) { + serviceManager.submit(url, path, filename, listener); } /** @@ -251,4 +248,22 @@ public static long getSendMessageIntervalNanos() { public static void postOnConnection(Runnable runnable) { serviceManager.postOnConnection(runnable); } + + /** + * @see DownloadError#translator + * This function is not an IPC call. + * If you install downloader in multi-process mode + * and want your translator to get work, call this method in the place where all + * the process will called (suck as static block, Application's methods, singleInstance's methods...). + * For default Translator implementation + * @see DownloadError + */ + public static void setErrorTranslator(DownloadError.Translator translator) { + if (translator == null) return; + DownloadError.instance().setTranslator(translator); + } + + public static String translateErrorCode(int code) { + return DownloadError.instance().translate(code); + } } diff --git a/downloader/src/main/java/com/lyc/downloader/db/CustomerHeader.java b/downloader/src/main/java/com/lyc/downloader/db/CustomerHeader.java deleted file mode 100644 index 5c3d1b7..0000000 --- a/downloader/src/main/java/com/lyc/downloader/db/CustomerHeader.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.lyc.downloader.db; - -import org.greenrobot.greendao.annotation.Entity; -import org.greenrobot.greendao.annotation.Generated; -import org.greenrobot.greendao.annotation.Id; -import org.greenrobot.greendao.annotation.Property; - -import java.util.Objects; - -/** - * Created by Liu Yuchuan on 2019/4/22. - */ -@Entity -public class CustomerHeader { - @Id(autoincrement = true) - private Long id; - @Property(nameInDb = "download_info_id") - private long downloadInfoId; - private String key; - private String value; - - @Generated(hash = 1588940521) - public CustomerHeader(Long id, long downloadInfoId, String key, String value) { - this.id = id; - this.downloadInfoId = downloadInfoId; - this.key = key; - this.value = value; - } - - @Generated(hash = 1511092188) - public CustomerHeader() { - } - - public Long getId() { - return this.id; - } - - public void setId(Long id) { - this.id = id; - } - - public long getDownloadInfoId() { - return this.downloadInfoId; - } - - public void setDownloadInfoId(long downloadInfoId) { - this.downloadInfoId = downloadInfoId; - } - - public String getKey() { - return this.key; - } - - public void setKey(String key) { - this.key = key; - } - - public String getValue() { - return this.value; - } - - public void setValue(String value) { - this.value = value; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - CustomerHeader that = (CustomerHeader) o; - - return Objects.equals(id, that.id); - } - - @Override - public int hashCode() { - return id != null ? id.hashCode() : 0; - } -} diff --git a/downloader/src/main/java/com/lyc/downloader/db/DownloadInfo.java b/downloader/src/main/java/com/lyc/downloader/db/DownloadInfo.java index a8b396d..8de5987 100644 --- a/downloader/src/main/java/com/lyc/downloader/db/DownloadInfo.java +++ b/downloader/src/main/java/com/lyc/downloader/db/DownloadInfo.java @@ -22,7 +22,7 @@ @org.greenrobot.greendao.annotation.Index(value = "url DESC") } ) -public class DownloadInfo implements Comparable, Parcelable { +public class DownloadInfo implements Parcelable { @Id(autoincrement = true) private Long id; @NotNull @@ -43,12 +43,21 @@ public class DownloadInfo implements Comparable, Parcelable { private Date createdTime; @Property(nameInDb = "finished_time") private Date finishedTime; - @Property(nameInDb = "error_msg") - private String errorMsg; - @ToMany(referencedJoinProperty = "downloadInfoId") - private List customerHeaders; + public static final Creator CREATOR = new Creator() { + @Override + public DownloadInfo createFromParcel(Parcel in) { + return new DownloadInfo(in); + } + + @Override + public DownloadInfo[] newArray(int size) { + return new DownloadInfo[size]; + } + }; @ToMany(referencedJoinProperty = "downloadInfoId") private List downloadThreadInfos; + @Property(nameInDb = "error_msg") + private Integer errorCode; /** * Used to resolve relations */ @@ -60,26 +69,14 @@ public class DownloadInfo implements Comparable, Parcelable { @Generated(hash = 1465593784) private transient DownloadInfoDao myDao; - public static final Creator CREATOR = new Creator() { - @Override - public DownloadInfo createFromParcel(Parcel in) { - return new DownloadInfo(in); - } - - @Override - public DownloadInfo[] newArray(int size) { - return new DownloadInfo[size]; - } - }; - - @Generated(hash = 327086747) - public DownloadInfo() { + protected DownloadInfo(Parcel in) { + readFromParcel(in); } - @Generated(hash = 9671916) + @Generated(hash = 459431950) public DownloadInfo(Long id, @NotNull String url, @NotNull String path, String filename, boolean resumable, int downloadItemState, long downloadedSize, long totalSize, - String lastModified, Date createdTime, Date finishedTime, String errorMsg) { + String lastModified, Date createdTime, Date finishedTime, Integer errorCode) { this.id = id; this.url = url; this.path = path; @@ -91,7 +88,7 @@ public DownloadInfo(Long id, @NotNull String url, @NotNull String path, String f this.lastModified = lastModified; this.createdTime = createdTime; this.finishedTime = finishedTime; - this.errorMsg = errorMsg; + this.errorCode = errorCode; } public Long getId() { @@ -118,6 +115,43 @@ public void setPath(String path) { this.path = path; } + @Generated(hash = 327086747) + public DownloadInfo() { + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + if (id == null) { + dest.writeByte((byte) 0); + } else { + dest.writeByte((byte) 1); + dest.writeLong(id); + } + dest.writeString(url); + dest.writeString(path); + dest.writeString(filename); + dest.writeByte((byte) (resumable ? 1 : 0)); + dest.writeInt(downloadItemState); + dest.writeLong(downloadedSize); + dest.writeLong(totalSize); + dest.writeString(lastModified); + if (errorCode == null) { + dest.writeByte((byte) 0); + } else { + dest.writeByte((byte) 1); + dest.writeInt(errorCode); + } + } + + @Override + public int describeContents() { + return 0; + } + + public String getFilename() { + return this.filename; + } + public int getDownloadItemState() { return this.downloadItemState; } @@ -126,35 +160,52 @@ public void setDownloadItemState(int downloadItemState) { this.downloadItemState = downloadItemState; } - /** - * To-many relationship, resolved on first access (and after reset). - * Changes to to-many relations are not persisted, make changes to the target entity. - */ - @Generated(hash = 1083281654) - public List getCustomerHeaders() { - if (customerHeaders == null) { - final DaoSession daoSession = this.daoSession; - if (daoSession == null) { - throw new DaoException("Entity is detached from DAO context"); - } - CustomerHeaderDao targetDao = daoSession.getCustomerHeaderDao(); - List customerHeadersNew = targetDao - ._queryDownloadInfo_CustomerHeaders(id); - synchronized (this) { - if (customerHeaders == null) { - customerHeaders = customerHeadersNew; - } - } - } - return customerHeaders; + public void setFilename(String filename) { + this.filename = filename; } - /** - * Resets a to-many relationship, making the next get call to query for a fresh result. - */ - @Generated(hash = 433013855) - public synchronized void resetCustomerHeaders() { - customerHeaders = null; + public boolean getResumable() { + return this.resumable; + } + + public void setResumable(boolean resumable) { + this.resumable = resumable; + } + + public long getDownloadedSize() { + return this.downloadedSize; + } + + public void setDownloadedSize(long downloadedSize) { + this.downloadedSize = downloadedSize; + } + + public long getTotalSize() { + return this.totalSize; + } + + public void setTotalSize(long totalSize) { + this.totalSize = totalSize; + } + + public String getLastModified() { + return this.lastModified; + } + + public void setLastModified(String lastModified) { + this.lastModified = lastModified; + } + + public Date getCreatedTime() { + return this.createdTime; + } + + public void setCreatedTime(Date createdTime) { + this.createdTime = createdTime; + } + + public Date getFinishedTime() { + return this.finishedTime; } /** @@ -224,105 +275,16 @@ public void update() { myDao.update(this); } - public boolean getResumable() { - return this.resumable; - } - - public void setResumable(boolean resumable) { - this.resumable = resumable; - } - - public long getDownloadedSize() { - return this.downloadedSize; - } - - public void setDownloadedSize(long downloadedSize) { - this.downloadedSize = downloadedSize; - } - - public long getTotalSize() { - return this.totalSize; - } - - public void setTotalSize(long totalSize) { - this.totalSize = totalSize; - } - - public String getErrorMsg() { - return this.errorMsg; - } - - public void setErrorMsg(String errorMsg) { - this.errorMsg = errorMsg; - } - - public Date getCreatedTime() { - return this.createdTime; - } - - public void setCreatedTime(Date createdTime) { - this.createdTime = createdTime; - } - - public Date getFinishedTime() { - return this.finishedTime; - } - public void setFinishedTime(Date finishedTime) { this.finishedTime = finishedTime; } - @Override - public int compareTo(DownloadInfo o) { - if (o == null) return 1; - return this.createdTime.compareTo(o.createdTime); - } - - public String getFilename() { - return this.filename; - } - - public void setFilename(String filename) { - this.filename = filename; - } - - public String getLastModified() { - return this.lastModified; - } - - public void setLastModified(String lastModified) { - this.lastModified = lastModified; - } - - @Override - public String toString() { - return "DownloadInfo{" + - "id=" + id + - ", url='" + url + '\'' + - ", path='" + path + '\'' + - ", filename='" + filename + '\'' + - ", resumable=" + resumable + - ", downloadItemState=" + downloadItemState + - ", downloadedSize=" + downloadedSize + - ", totalSize=" + totalSize + - ", lastModified='" + lastModified + '\'' + - ", createdTime=" + createdTime + - ", finishedTime=" + finishedTime + - ", errorMsg='" + errorMsg + '\'' + - ", customerHeaders=" + customerHeaders + - ", downloadThreadInfos=" + downloadThreadInfos + - ", daoSession=" + daoSession + - ", myDao=" + myDao + - '}'; - } - - protected DownloadInfo(Parcel in) { - readFromParcel(in); + public Integer getErrorCode() { + return this.errorCode; } - @Override - public int describeContents() { - return 0; + public void setErrorCode(Integer errorCode) { + this.errorCode = errorCode; } public void readFromParcel(Parcel in) { @@ -339,26 +301,11 @@ public void readFromParcel(Parcel in) { downloadedSize = in.readLong(); totalSize = in.readLong(); lastModified = in.readString(); - errorMsg = in.readString(); - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - if (id == null) { - dest.writeByte((byte) 0); + if (in.readByte() == 0) { + errorCode = null; } else { - dest.writeByte((byte) 1); - dest.writeLong(id); + errorCode = in.readInt(); } - dest.writeString(url); - dest.writeString(path); - dest.writeString(filename); - dest.writeByte((byte) (resumable ? 1 : 0)); - dest.writeInt(downloadItemState); - dest.writeLong(downloadedSize); - dest.writeLong(totalSize); - dest.writeString(lastModified); - dest.writeString(errorMsg); } /** called by internal mechanisms, do not call yourself. */ @@ -367,6 +314,4 @@ public void __setDaoSession(DaoSession daoSession) { this.daoSession = daoSession; myDao = daoSession != null ? daoSession.getDownloadInfoDao() : null; } - - } diff --git a/sample/src/main/java/com/lyc/yuchuan_downloader/DownloadItem.kt b/sample/src/main/java/com/lyc/yuchuan_downloader/DownloadItem.kt index 75692dc..fdafff0 100644 --- a/sample/src/main/java/com/lyc/yuchuan_downloader/DownloadItem.kt +++ b/sample/src/main/java/com/lyc/yuchuan_downloader/DownloadItem.kt @@ -18,7 +18,7 @@ data class DownloadItem( var createdTime: Date? = null, var finishedTime: Date? = null, var downloadState: Int = 0, - var errorMessage: String? = null + var errorCode: Int? = null ) { override fun equals(other: Any?): Boolean { return this.id == (other as? DownloadItem)?.id diff --git a/sample/src/main/java/com/lyc/yuchuan_downloader/DownloadItemViewBinder.kt b/sample/src/main/java/com/lyc/yuchuan_downloader/DownloadItemViewBinder.kt index facab29..cba08cf 100644 --- a/sample/src/main/java/com/lyc/yuchuan_downloader/DownloadItemViewBinder.kt +++ b/sample/src/main/java/com/lyc/yuchuan_downloader/DownloadItemViewBinder.kt @@ -6,6 +6,7 @@ import android.view.ViewGroup import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.lyc.downloader.DownloadTask.* +import com.lyc.downloader.YCDownloader import com.lyc.downloader.utils.DownloadStringUtil import kotlinx.android.synthetic.main.item_download.view.* import me.drakeet.multitype.ItemViewBinder @@ -78,7 +79,7 @@ class DownloadItemViewBinder( WAITING -> stateString = "$stateString | 等待中" CANCELED -> stateString = "已取消" ERROR, FATAL_ERROR -> { - var errorMessage: String? = item.errorMessage + var errorMessage: String? = YCDownloader.translateErrorCode(item.errorCode!!) if (errorMessage == null) { errorMessage = "下载失败" } diff --git a/sample/src/main/java/com/lyc/yuchuan_downloader/MainViewModel.kt b/sample/src/main/java/com/lyc/yuchuan_downloader/MainViewModel.kt index b0c4700..8daf13b 100644 --- a/sample/src/main/java/com/lyc/yuchuan_downloader/MainViewModel.kt +++ b/sample/src/main/java/com/lyc/yuchuan_downloader/MainViewModel.kt @@ -155,7 +155,7 @@ class MainViewModel : ViewModel(), SubmitListener, DownloadListener { } internal fun submit(url: String) { - YCDownloader.submit(url, path, null, null, this) + YCDownloader.submit(url, path, null, this) } private fun doUpdateCallback(id: Long, updateCallback: (item: DownloadItem) -> DownloadItem) { @@ -193,10 +193,10 @@ class MainViewModel : ViewModel(), SubmitListener, DownloadListener { } } - override fun onDownloadError(id: Long, reason: String, fatal: Boolean) { + override fun onDownloadError(id: Long, reason: Int, fatal: Boolean) { doUpdateCallback(id) { item -> item.downloadState = ERROR - item.errorMessage = reason + item.errorCode = reason item } } @@ -270,7 +270,7 @@ class MainViewModel : ViewModel(), SubmitListener, DownloadListener { info.createdTime, info.finishedTime, info.downloadItemState, - info.errorMsg + info.errorCode ) }