feat: 优化代码

pull/105/head
kunfei 5 years ago
parent 3bf5f95c59
commit 7b62b64178
  1. 3
      app/src/main/java/io/legado/app/data/dao/BookChapterDao.kt
  2. 11
      app/src/main/java/io/legado/app/data/entities/BookChapter.kt
  3. 77
      app/src/main/java/io/legado/app/service/DownloadService.kt

@ -19,6 +19,9 @@ interface BookChapterDao {
@Query("select * from chapters where bookUrl = :bookUrl") @Query("select * from chapters where bookUrl = :bookUrl")
fun getChapterList(bookUrl: String): List<BookChapter> fun getChapterList(bookUrl: String): List<BookChapter>
@Query("select * from chapters where bookUrl = :bookUrl and `index` >= :start and `index` <= :end")
fun getChapterList(bookUrl: String, start: Int, end: Int): List<BookChapter>
@Query("select * from chapters where bookUrl = :bookUrl and `index` = :index") @Query("select * from chapters where bookUrl = :bookUrl and `index` = :index")
fun getChapter(bookUrl: String, index: Int): BookChapter? fun getChapter(bookUrl: String, index: Int): BookChapter?

@ -52,5 +52,16 @@ data class BookChapter(
variable = GSON.toJson(variableMap) variable = GSON.toJson(variableMap)
} }
override fun hashCode(): Int {
return url.hashCode()
}
override fun equals(other: Any?): Boolean {
if (other is BookChapter) {
return other.url == url
}
return false
}
} }

@ -6,9 +6,10 @@ import androidx.core.app.NotificationCompat
import io.legado.app.App import io.legado.app.App
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseService import io.legado.app.base.BaseService
import io.legado.app.constant.IntentAction
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.constant.IntentAction
import io.legado.app.data.entities.BookChapter
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.help.IntentHelp import io.legado.app.help.IntentHelp
@ -17,6 +18,7 @@ import io.legado.app.model.WebBook
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.asCoroutineDispatcher
import org.jetbrains.anko.toast
import java.util.concurrent.Executors import java.util.concurrent.Executors
class DownloadService : BaseService() { class DownloadService : BaseService() {
@ -25,6 +27,8 @@ class DownloadService : BaseService() {
private var tasks: ArrayList<Coroutine<*>> = arrayListOf() private var tasks: ArrayList<Coroutine<*>> = arrayListOf()
private val handler = Handler() private val handler = Handler()
private var runnable: Runnable = Runnable { upDownload() } private var runnable: Runnable = Runnable { upDownload() }
private val downloadMap = hashMapOf<String, LinkedHashSet<BookChapter>>()
private val finalMap = hashMapOf<String, LinkedHashSet<BookChapter>>()
private var notificationContent = "正在启动下载" private var notificationContent = "正在启动下载"
private val notificationBuilder by lazy { private val notificationBuilder by lazy {
val builder = NotificationCompat.Builder(this, AppConst.channelIdDownload) val builder = NotificationCompat.Builder(this, AppConst.channelIdDownload)
@ -48,7 +52,7 @@ class DownloadService : BaseService() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
intent?.action?.let { action -> intent?.action?.let { action ->
when (action) { when (action) {
IntentAction.start -> download( IntentAction.start -> addDownloadData(
intent.getStringExtra("bookUrl"), intent.getStringExtra("bookUrl"),
intent.getIntExtra("start", 0), intent.getIntExtra("start", 0),
intent.getIntExtra("end", 0) intent.getIntExtra("end", 0)
@ -67,28 +71,63 @@ class DownloadService : BaseService() {
postEvent(EventBus.UP_DOWNLOAD, false) postEvent(EventBus.UP_DOWNLOAD, false)
} }
private fun download(bookUrl: String?, start: Int, end: Int) { private fun addDownloadData(bookUrl: String?, start: Int, end: Int) {
if (bookUrl == null) return bookUrl ?: return
val task = Coroutine.async(this) { if (downloadMap.containsKey(bookUrl)) {
val book = App.db.bookDao().getBook(bookUrl) ?: return@async toast("该书已在下载列表")
val bookSource = App.db.bookSourceDao().getBookSource(book.origin) ?: return@async return
val webBook = WebBook(bookSource) }
for (index in start..end) { execute {
App.db.bookChapterDao().getChapter(bookUrl, index)?.let { chapter -> val chapterMap = downloadMap[bookUrl] ?: linkedSetOf<BookChapter>().apply {
if (!BookHelp.hasContent(book, chapter)) { downloadMap[bookUrl] = this
webBook.getContent(book, chapter, scope = this, context = searchPool) }
.onStart { App.db.bookChapterDao().getChapterList(bookUrl, start, end).let {
notificationContent = chapter.title chapterMap.addAll(it)
} }
.onSuccess(IO) { content -> download()
content?.let { }
BookHelp.saveContent(book, chapter, content) }
private fun download() {
val task = Coroutine.async(this, context = searchPool) {
downloadMap.forEach { entry ->
if (!finalMap.containsKey(entry.key)) {
val book = App.db.bookDao().getBook(entry.key) ?: return@async
val bookSource =
App.db.bookSourceDao().getBookSource(book.origin) ?: return@async
val webBook = WebBook(bookSource)
entry.value.forEach { chapter ->
if (!BookHelp.hasContent(book, chapter)) {
webBook.getContent(book, chapter, scope = this, context = searchPool)
.onStart {
notificationContent = chapter.title
}
.onSuccess(IO) { content ->
content?.let {
BookHelp.saveContent(book, chapter, content)
}
} }
} .onFinally(IO) {
synchronized(this@DownloadService) {
val chapterMap =
finalMap[book.bookUrl]
?: linkedSetOf<BookChapter>().apply {
finalMap[book.bookUrl] = this
}
chapterMap.add(chapter)
if (chapterMap.size == entry.value.size) {
downloadMap.remove(book.bookUrl)
finalMap.remove(book.bookUrl)
}
}
}
}
} }
} }
} }
} }
tasks.add(task) tasks.add(task)
task.invokeOnCompletion { task.invokeOnCompletion {
tasks.remove(task) tasks.remove(task)

Loading…
Cancel
Save