Allow download multiple galleries concurrently
This commit is contained in:
@@ -19,8 +19,8 @@ android {
|
|||||||
applicationId "xyz.quaver.pupil"
|
applicationId "xyz.quaver.pupil"
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 41
|
versionCode 42
|
||||||
versionName "4.5"
|
versionName "4.6-beta1"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
|||||||
@@ -145,25 +145,21 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
|||||||
|
|
||||||
private val loop = loop()
|
private val loop = loop()
|
||||||
private val worker = SparseArray<Job?>()
|
private val worker = SparseArray<Job?>()
|
||||||
@Volatile var nRunners = 0
|
val clients = SparseArray<OkHttpClient>()
|
||||||
|
|
||||||
private val client = OkHttpClient.Builder()
|
val interceptor = Interceptor { chain ->
|
||||||
.addInterceptor { chain ->
|
val request = chain.request()
|
||||||
val request = chain.request()
|
val response = chain.proceed(request)
|
||||||
var response = chain.proceed(request)
|
|
||||||
|
|
||||||
var retry = preferences.getInt("retry", 3)
|
response.newBuilder()
|
||||||
while (!response.isSuccessful && retry > 0) {
|
.body(ProgressResponseBody(request.tag(), response.body(), progressListener))
|
||||||
response = chain.proceed(request)
|
|
||||||
retry--
|
|
||||||
}
|
|
||||||
|
|
||||||
response.newBuilder()
|
|
||||||
.body(ProgressResponseBody(request.tag(), response.body(), progressListener))
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
.dispatcher(Dispatcher(Executors.newFixedThreadPool(4)))
|
|
||||||
.build()
|
.build()
|
||||||
|
}
|
||||||
|
fun buildClient() =
|
||||||
|
OkHttpClient.Builder()
|
||||||
|
.addInterceptor(interceptor)
|
||||||
|
.dispatcher(Dispatcher(Executors.newFixedThreadPool(4)))
|
||||||
|
.build()
|
||||||
|
|
||||||
fun stop() {
|
fun stop() {
|
||||||
queue.clear()
|
queue.clear()
|
||||||
@@ -176,29 +172,30 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
|||||||
worker[galleryID]?.cancel()
|
worker[galleryID]?.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
client.dispatcher().cancelAll()
|
for (i in 0 until clients.size()) {
|
||||||
|
clients.valueAt(i).dispatcher().cancelAll()
|
||||||
|
}
|
||||||
|
clients.clear()
|
||||||
|
|
||||||
progress.clear()
|
progress.clear()
|
||||||
exception.clear()
|
exception.clear()
|
||||||
notification.clear()
|
notification.clear()
|
||||||
notificationManager.cancelAll()
|
notificationManager.cancelAll()
|
||||||
|
|
||||||
nRunners = 0
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun cancel(galleryID: Int) {
|
fun cancel(galleryID: Int) {
|
||||||
queue.remove(galleryID)
|
queue.remove(galleryID)
|
||||||
worker[galleryID]?.cancel()
|
worker[galleryID]?.cancel()
|
||||||
|
|
||||||
client.dispatcher().queuedCalls()
|
clients[galleryID]?.dispatcher()?.queuedCalls()
|
||||||
.filter {
|
?.filter {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
(it.request().tag() as? Pair<Int, Int>)?.first == galleryID
|
(it.request().tag() as? Pair<Int, Int>)?.first == galleryID
|
||||||
}
|
}
|
||||||
.forEach {
|
?.forEach {
|
||||||
it.cancel()
|
it.cancel()
|
||||||
}
|
}
|
||||||
|
clients.remove(galleryID)
|
||||||
|
|
||||||
progress.remove(galleryID)
|
progress.remove(galleryID)
|
||||||
exception.remove(galleryID)
|
exception.remove(galleryID)
|
||||||
@@ -207,7 +204,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
|||||||
|
|
||||||
if (progress.indexOfKey(galleryID) >= 0) {
|
if (progress.indexOfKey(galleryID) >= 0) {
|
||||||
Cache(this@DownloadWorker).setDownloading(galleryID, false)
|
Cache(this@DownloadWorker).setDownloading(galleryID, false)
|
||||||
nRunners--
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +236,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
|||||||
tag(galleryID to index)
|
tag(galleryID to index)
|
||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
client.newCall(request).enqueue(callback)
|
clients[galleryID].newCall(request).enqueue(callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun download(galleryID: Int) = CoroutineScope(Dispatchers.IO).launch {
|
private fun download(galleryID: Int) = CoroutineScope(Dispatchers.IO).launch {
|
||||||
@@ -252,7 +248,6 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
|||||||
exception.put(galleryID, null)
|
exception.put(galleryID, null)
|
||||||
|
|
||||||
Cache(this@DownloadWorker).setDownloading(galleryID, false)
|
Cache(this@DownloadWorker).setDownloading(galleryID, false)
|
||||||
nRunners--
|
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,11 +274,12 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
|||||||
setDownloading(galleryID, false)
|
setDownloading(galleryID, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nRunners--
|
|
||||||
|
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clients.put(galleryID, buildClient())
|
||||||
|
|
||||||
for (i in reader.galleryInfo.indices) {
|
for (i in reader.galleryInfo.indices) {
|
||||||
val callback = object : Callback {
|
val callback = object : Callback {
|
||||||
override fun onFailure(call: Call, e: IOException) {
|
override fun onFailure(call: Call, e: IOException) {
|
||||||
@@ -302,7 +298,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
|||||||
setDownloading(galleryID, false)
|
setDownloading(galleryID, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nRunners--
|
clients.remove(galleryID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,7 +321,7 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
|||||||
setDownloading(galleryID, false)
|
setDownloading(galleryID, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nRunners--
|
clients.remove(galleryID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -374,19 +370,18 @@ class DownloadWorker private constructor(context: Context) : ContextWrapper(cont
|
|||||||
|
|
||||||
private fun loop() = CoroutineScope(Dispatchers.Default).launch {
|
private fun loop() = CoroutineScope(Dispatchers.Default).launch {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (queue.isEmpty() || nRunners > preferences.getInt("max_download", 4))
|
if (queue.isEmpty() || clients.size() > preferences.getInt("max_download", 4))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
val galleryID = queue.poll() ?: continue
|
val galleryID = queue.poll() ?: continue
|
||||||
|
|
||||||
if (progress.indexOfKey(galleryID) >= 0) // Gallery already downloading!
|
if (clients.indexOfKey(galleryID) >= 0) // Gallery already downloading!
|
||||||
continue
|
continue
|
||||||
|
|
||||||
initNotification(galleryID)
|
initNotification(galleryID)
|
||||||
if (Cache(this@DownloadWorker).isDownloading(galleryID))
|
if (Cache(this@DownloadWorker).isDownloading(galleryID))
|
||||||
notificationManager.notify(galleryID, notification[galleryID].build())
|
notificationManager.notify(galleryID, notification[galleryID].build())
|
||||||
worker.put(galleryID, download(galleryID))
|
worker.put(galleryID, download(galleryID))
|
||||||
nRunners++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user