@@ -2,30 +2,24 @@ package io.legado.app.help.coroutine
|
|||||||
|
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.sync.Mutex
|
|
||||||
import kotlinx.coroutines.sync.withLock
|
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue
|
|
||||||
import java.util.concurrent.PriorityBlockingQueue
|
import java.util.concurrent.PriorityBlockingQueue
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
|
||||||
class OrderCoroutine<T>(val threadCount: Int) {
|
class OrderCoroutine<T>(val threadCount: Int) {
|
||||||
private val taskList = ConcurrentLinkedQueue<suspend CoroutineScope.() -> T>()
|
private val taskList = ArrayList<suspend CoroutineScope.() -> T>()
|
||||||
private val taskResultMap = ConcurrentHashMap<Int, T>()
|
private val taskResultMap = ConcurrentHashMap<Int, T>()
|
||||||
private val finishTaskIndex = PriorityBlockingQueue<Int>()
|
private val finishTaskIndex = PriorityBlockingQueue<Int>()
|
||||||
private val mutex = Mutex()
|
|
||||||
|
|
||||||
private suspend fun start() = coroutineScope {
|
private suspend fun start() = coroutineScope {
|
||||||
var taskIndex = 0
|
val taskIndex = AtomicInteger(0)
|
||||||
|
val tasks = taskList.toList()
|
||||||
for (i in 1..threadCount) {
|
for (i in 1..threadCount) {
|
||||||
launch {
|
launch {
|
||||||
while (true) {
|
while (true) {
|
||||||
ensureActive()
|
ensureActive()
|
||||||
val task: suspend CoroutineScope.() -> T
|
val curIndex = taskIndex.getAndIncrement()
|
||||||
val curIndex: Int
|
val task = tasks.getOrNull(curIndex) ?: return@launch
|
||||||
mutex.withLock {
|
|
||||||
task = taskList.poll() ?: return@launch
|
|
||||||
curIndex = taskIndex++
|
|
||||||
}
|
|
||||||
taskResultMap[curIndex] = task.invoke(this)
|
taskResultMap[curIndex] = task.invoke(this)
|
||||||
finishTaskIndex.add(curIndex)
|
finishTaskIndex.add(curIndex)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,11 @@ class GroupEditDialog() : BaseDialogFragment(R.layout.dialog_book_group_edit) {
|
|||||||
val selectImage = registerForActivityResult(SelectImageContract()) {
|
val selectImage = registerForActivityResult(SelectImageContract()) {
|
||||||
readUri(it?.uri) { fileDoc, inputStream ->
|
readUri(it?.uri) { fileDoc, inputStream ->
|
||||||
var file = requireContext().externalFiles
|
var file = requireContext().externalFiles
|
||||||
file = FileUtils.createFileIfNotExist(file, "covers", fileDoc.name)
|
val suffix = fileDoc.name.substringAfterLast(".")
|
||||||
|
val fileName = it.uri!!.inputStream(requireContext())!!.use {
|
||||||
|
MD5Utils.md5Encode(it) + ".$suffix"
|
||||||
|
}
|
||||||
|
file = FileUtils.createFileIfNotExist(file, "covers", fileName)
|
||||||
FileOutputStream(file).use { outputStream ->
|
FileOutputStream(file).use { outputStream ->
|
||||||
inputStream.copyTo(outputStream)
|
inputStream.copyTo(outputStream)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,11 @@ class BookInfoEditActivity :
|
|||||||
readUri(uri) { fileDoc, inputStream ->
|
readUri(uri) { fileDoc, inputStream ->
|
||||||
inputStream.use {
|
inputStream.use {
|
||||||
var file = this.externalFiles
|
var file = this.externalFiles
|
||||||
file = FileUtils.createFileIfNotExist(file, "covers", fileDoc.name)
|
val suffix = fileDoc.name.substringAfterLast(".")
|
||||||
|
val fileName = uri.inputStream(this)!!.use {
|
||||||
|
MD5Utils.md5Encode(it) + ".$suffix"
|
||||||
|
}
|
||||||
|
file = FileUtils.createFileIfNotExist(file, "covers", fileName)
|
||||||
FileOutputStream(file).use { outputStream ->
|
FileOutputStream(file).use { outputStream ->
|
||||||
inputStream.copyTo(outputStream)
|
inputStream.copyTo(outputStream)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,11 @@ class CoverConfigFragment : PreferenceFragment(),
|
|||||||
private fun setCoverFromUri(preferenceKey: String, uri: Uri) {
|
private fun setCoverFromUri(preferenceKey: String, uri: Uri) {
|
||||||
readUri(uri) { fileDoc, inputStream ->
|
readUri(uri) { fileDoc, inputStream ->
|
||||||
var file = requireContext().externalFiles
|
var file = requireContext().externalFiles
|
||||||
file = FileUtils.createFileIfNotExist(file, "covers", fileDoc.name)
|
val suffix = fileDoc.name.substringAfterLast(".")
|
||||||
|
val fileName = uri.inputStream(requireContext())!!.use {
|
||||||
|
MD5Utils.md5Encode(it) + ".$suffix"
|
||||||
|
}
|
||||||
|
file = FileUtils.createFileIfNotExist(file, "covers", fileName)
|
||||||
FileOutputStream(file).use {
|
FileOutputStream(file).use {
|
||||||
inputStream.copyTo(it)
|
inputStream.copyTo(it)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -304,7 +304,11 @@ class ThemeConfigFragment : PreferenceFragment(),
|
|||||||
private fun setBgFromUri(uri: Uri, preferenceKey: String, success: () -> Unit) {
|
private fun setBgFromUri(uri: Uri, preferenceKey: String, success: () -> Unit) {
|
||||||
readUri(uri) { fileDoc, inputStream ->
|
readUri(uri) { fileDoc, inputStream ->
|
||||||
var file = requireContext().externalFiles
|
var file = requireContext().externalFiles
|
||||||
file = FileUtils.createFileIfNotExist(file, preferenceKey, fileDoc.name)
|
val suffix = fileDoc.name.substringAfterLast(".")
|
||||||
|
val fileName = uri.inputStream(requireContext())!!.use {
|
||||||
|
MD5Utils.md5Encode(it) + ".$suffix"
|
||||||
|
}
|
||||||
|
file = FileUtils.createFileIfNotExist(file, preferenceKey, fileName)
|
||||||
FileOutputStream(file).use {
|
FileOutputStream(file).use {
|
||||||
inputStream.copyTo(it)
|
inputStream.copyTo(it)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,11 @@ class WelcomeConfigFragment : PreferenceFragment(),
|
|||||||
private fun setCoverFromUri(preferenceKey: String, uri: Uri) {
|
private fun setCoverFromUri(preferenceKey: String, uri: Uri) {
|
||||||
readUri(uri) { fileDoc, inputStream ->
|
readUri(uri) { fileDoc, inputStream ->
|
||||||
var file = requireContext().externalFiles
|
var file = requireContext().externalFiles
|
||||||
file = FileUtils.createFileIfNotExist(file, "covers", fileDoc.name)
|
val suffix = fileDoc.name.substringAfterLast(".")
|
||||||
|
val fileName = uri.inputStream(requireContext())!!.use {
|
||||||
|
MD5Utils.md5Encode(it) + ".$suffix"
|
||||||
|
}
|
||||||
|
file = FileUtils.createFileIfNotExist(file, "covers", fileName)
|
||||||
FileOutputStream(file).use {
|
FileOutputStream(file).use {
|
||||||
inputStream.copyTo(it)
|
inputStream.copyTo(it)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ fun AppCompatActivity.readUri(
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printOnDebug()
|
e.printOnDebug()
|
||||||
toastOnUi(e.localizedMessage ?: "read uri error")
|
toastOnUi(e.localizedMessage ?: "read uri error")
|
||||||
|
if (e is SecurityException) {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user