mirror of
https://github.com/gedoor/legado.git
synced 2024-07-06 23:47:49 +08:00
优化
This commit is contained in:
parent
c9d07d08c4
commit
3882904f1d
@ -31,7 +31,12 @@ abstract class BaseService : LifecycleService() {
|
||||
super.onCreate()
|
||||
LifecycleHelp.onServiceCreate(this)
|
||||
checkNotificationPermission()
|
||||
upNotification()
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
startForegroundNotification()
|
||||
return super.onStartCommand(intent, flags, startId)
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
@ -52,9 +57,9 @@ abstract class BaseService : LifecycleService() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新通知
|
||||
* 开启前台服务并发送通知
|
||||
*/
|
||||
open fun upNotification() {
|
||||
open fun startForegroundNotification() {
|
||||
|
||||
}
|
||||
|
||||
@ -67,7 +72,7 @@ abstract class BaseService : LifecycleService() {
|
||||
.rationale(R.string.notification_permission_rationale)
|
||||
.onGranted {
|
||||
if (lifecycleScope.isActive) {
|
||||
upNotification()
|
||||
startForegroundNotification()
|
||||
}
|
||||
}
|
||||
.request()
|
||||
|
@ -14,7 +14,13 @@ import io.legado.app.help.RuleBigDataHelp
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.model.analyzeRule.AnalyzeUrl
|
||||
import io.legado.app.model.analyzeRule.RuleDataInterface
|
||||
import io.legado.app.utils.*
|
||||
import io.legado.app.utils.ChineseUtils
|
||||
import io.legado.app.utils.GSON
|
||||
import io.legado.app.utils.MD5Utils
|
||||
import io.legado.app.utils.NetworkUtils
|
||||
import io.legado.app.utils.fromJsonObject
|
||||
import io.legado.app.utils.replace
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.parcelize.IgnoredOnParcel
|
||||
import kotlinx.parcelize.Parcelize
|
||||
@ -110,7 +116,7 @@ data class BookChapter(
|
||||
try {
|
||||
val mDisplayTitle = if (item.isRegex) {
|
||||
displayTitle.replace(
|
||||
item.pattern.toRegex(),
|
||||
item.regex,
|
||||
item.replacement,
|
||||
item.getValidTimeoutMillisecond()
|
||||
)
|
||||
|
@ -4,11 +4,13 @@ import android.os.Parcelable
|
||||
import android.text.TextUtils
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Ignore
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
import io.legado.app.R
|
||||
import io.legado.app.constant.AppLog
|
||||
import io.legado.app.exception.NoStackTraceException
|
||||
import kotlinx.parcelize.IgnoredOnParcel
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import splitties.init.appCtx
|
||||
import java.util.regex.Pattern
|
||||
@ -68,6 +70,12 @@ data class ReplaceRule(
|
||||
return id.hashCode()
|
||||
}
|
||||
|
||||
@delegate:Ignore
|
||||
@IgnoredOnParcel
|
||||
val regex: Regex by lazy {
|
||||
pattern.toRegex()
|
||||
}
|
||||
|
||||
fun getDisplayNameGroup(): String {
|
||||
return if (group.isNullOrBlank()) {
|
||||
name
|
||||
|
@ -152,7 +152,7 @@ class ContentProcessor private constructor(
|
||||
try {
|
||||
val tmp = if (item.isRegex) {
|
||||
mContent.replace(
|
||||
item.pattern.toRegex(),
|
||||
item.regex,
|
||||
item.replacement,
|
||||
item.getValidTimeoutMillisecond()
|
||||
)
|
||||
|
@ -1,48 +0,0 @@
|
||||
package io.legado.app.help.coroutine
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.PriorityBlockingQueue
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
class OrderCoroutine<T>(val threadCount: Int) {
|
||||
private val taskList = ArrayList<suspend CoroutineScope.() -> T>()
|
||||
private val taskResultMap = ConcurrentHashMap<Int, T>()
|
||||
private val finishTaskIndex = PriorityBlockingQueue<Int>()
|
||||
|
||||
private suspend fun start() = coroutineScope {
|
||||
val taskIndex = AtomicInteger(0)
|
||||
val tasks = taskList.toList()
|
||||
for (i in 1..threadCount) {
|
||||
launch {
|
||||
while (true) {
|
||||
ensureActive()
|
||||
val curIndex = taskIndex.getAndIncrement()
|
||||
val task = tasks.getOrNull(curIndex) ?: return@launch
|
||||
taskResultMap[curIndex] = task.invoke(this)
|
||||
finishTaskIndex.add(curIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun submit(block: suspend CoroutineScope.() -> T) {
|
||||
taskList.add(block)
|
||||
}
|
||||
|
||||
suspend fun collect(block: (index: Int, result: T) -> Unit) = withContext(IO) {
|
||||
var index = 0
|
||||
val taskSize = taskList.size
|
||||
launch { start() }
|
||||
while (index < taskSize) {
|
||||
ensureActive()
|
||||
if (finishTaskIndex.peek() == index) {
|
||||
finishTaskIndex.poll()
|
||||
block.invoke(index, taskResultMap.remove(index)!!)
|
||||
index++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -83,6 +83,17 @@ object CacheBook {
|
||||
}
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
successDownloadSet.clear()
|
||||
errorDownloadMap.clear()
|
||||
}
|
||||
|
||||
fun close() {
|
||||
cacheBookMap.forEach { it.value.stop() }
|
||||
cacheBookMap.clear()
|
||||
clear()
|
||||
}
|
||||
|
||||
val downloadSummary: String
|
||||
get() {
|
||||
return "正在下载:${onDownloadCount}|等待中:${waitCount}|失败:${errorDownloadMap.count()}|成功:${successDownloadSet.size}"
|
||||
|
@ -55,6 +55,7 @@ import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import splitties.init.appCtx
|
||||
import splitties.systemservices.audioManager
|
||||
import splitties.systemservices.notificationManager
|
||||
import splitties.systemservices.powerManager
|
||||
import splitties.systemservices.wifiManager
|
||||
|
||||
@ -135,7 +136,7 @@ class AudioPlayService : BaseService(),
|
||||
.get()
|
||||
}.onSuccess {
|
||||
cover = it
|
||||
upNotification()
|
||||
upAudioPlayNotification()
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,7 +192,7 @@ class AudioPlayService : BaseService(),
|
||||
wakeLock.acquire()
|
||||
wifiLock?.acquire()
|
||||
}
|
||||
upNotification()
|
||||
upAudioPlayNotification()
|
||||
if (!requestFocus()) {
|
||||
return
|
||||
}
|
||||
@ -235,7 +236,7 @@ class AudioPlayService : BaseService(),
|
||||
upMediaSessionPlaybackState(PlaybackStateCompat.STATE_PAUSED)
|
||||
AudioPlay.status = Status.PAUSE
|
||||
postEvent(EventBus.AUDIO_STATE, Status.PAUSE)
|
||||
upNotification()
|
||||
upAudioPlayNotification()
|
||||
} catch (e: Exception) {
|
||||
e.printOnDebug()
|
||||
}
|
||||
@ -263,7 +264,7 @@ class AudioPlayService : BaseService(),
|
||||
upMediaSessionPlaybackState(PlaybackStateCompat.STATE_PLAYING)
|
||||
AudioPlay.status = Status.PLAY
|
||||
postEvent(EventBus.AUDIO_STATE, Status.PLAY)
|
||||
upNotification()
|
||||
upAudioPlayNotification()
|
||||
} catch (e: Exception) {
|
||||
e.printOnDebug()
|
||||
stopSelf()
|
||||
@ -335,7 +336,7 @@ class AudioPlayService : BaseService(),
|
||||
AudioPlay.next(this)
|
||||
}
|
||||
}
|
||||
upNotification()
|
||||
upAudioPlayNotification()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -370,7 +371,7 @@ class AudioPlayService : BaseService(),
|
||||
*/
|
||||
private fun doDs() {
|
||||
postEvent(EventBus.AUDIO_DS, timeMinute)
|
||||
upNotification()
|
||||
upAudioPlayNotification()
|
||||
dsJob?.cancel()
|
||||
dsJob = lifecycleScope.launch {
|
||||
while (isActive) {
|
||||
@ -384,7 +385,7 @@ class AudioPlayService : BaseService(),
|
||||
}
|
||||
}
|
||||
postEvent(EventBus.AUDIO_DS, timeMinute)
|
||||
upNotification()
|
||||
upAudioPlayNotification()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -583,67 +584,78 @@ class AudioPlayService : BaseService(),
|
||||
}
|
||||
}
|
||||
|
||||
private fun createNotification(): NotificationCompat.Builder {
|
||||
var nTitle: String = when {
|
||||
pause -> getString(R.string.audio_pause)
|
||||
timeMinute in 1..60 -> getString(
|
||||
R.string.playing_timer,
|
||||
timeMinute
|
||||
)
|
||||
|
||||
else -> getString(R.string.audio_play_t)
|
||||
}
|
||||
nTitle += ": ${AudioPlay.book?.name}"
|
||||
var nSubtitle = AudioPlay.durChapter?.title
|
||||
if (nSubtitle.isNullOrEmpty()) {
|
||||
nSubtitle = getString(R.string.audio_play_s)
|
||||
}
|
||||
val builder = NotificationCompat
|
||||
.Builder(this@AudioPlayService, AppConst.channelIdReadAloud)
|
||||
.setSmallIcon(R.drawable.ic_volume_up)
|
||||
.setSubText(getString(R.string.audio))
|
||||
.setOngoing(true)
|
||||
.setContentTitle(nTitle)
|
||||
.setContentText(nSubtitle)
|
||||
.setContentIntent(
|
||||
activityPendingIntent<AudioPlayActivity>("activity")
|
||||
)
|
||||
builder.setLargeIcon(cover)
|
||||
if (pause) {
|
||||
builder.addAction(
|
||||
R.drawable.ic_play_24dp,
|
||||
getString(R.string.resume),
|
||||
servicePendingIntent<AudioPlayService>(IntentAction.resume)
|
||||
)
|
||||
} else {
|
||||
builder.addAction(
|
||||
R.drawable.ic_pause_24dp,
|
||||
getString(R.string.pause),
|
||||
servicePendingIntent<AudioPlayService>(IntentAction.pause)
|
||||
)
|
||||
}
|
||||
builder.addAction(
|
||||
R.drawable.ic_stop_black_24dp,
|
||||
getString(R.string.stop),
|
||||
servicePendingIntent<AudioPlayService>(IntentAction.stop)
|
||||
)
|
||||
builder.addAction(
|
||||
R.drawable.ic_time_add_24dp,
|
||||
getString(R.string.set_timer),
|
||||
servicePendingIntent<AudioPlayService>(IntentAction.addTimer)
|
||||
)
|
||||
builder.setStyle(
|
||||
androidx.media.app.NotificationCompat.MediaStyle()
|
||||
.setShowActionsInCompactView(0, 1, 2)
|
||||
.setMediaSession(mediaSessionCompat?.sessionToken)
|
||||
)
|
||||
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
return builder
|
||||
}
|
||||
|
||||
private fun upAudioPlayNotification() {
|
||||
execute {
|
||||
createNotification()
|
||||
}.onSuccess {
|
||||
notificationManager.notify(NotificationId.AudioPlayService, it.build())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新通知
|
||||
*/
|
||||
override fun upNotification() {
|
||||
override fun startForegroundNotification() {
|
||||
execute {
|
||||
var nTitle: String = when {
|
||||
pause -> getString(R.string.audio_pause)
|
||||
timeMinute in 1..60 -> getString(
|
||||
R.string.playing_timer,
|
||||
timeMinute
|
||||
)
|
||||
|
||||
else -> getString(R.string.audio_play_t)
|
||||
}
|
||||
nTitle += ": ${AudioPlay.book?.name}"
|
||||
var nSubtitle = AudioPlay.durChapter?.title
|
||||
if (nSubtitle.isNullOrEmpty()) {
|
||||
nSubtitle = getString(R.string.audio_play_s)
|
||||
}
|
||||
val builder = NotificationCompat
|
||||
.Builder(this@AudioPlayService, AppConst.channelIdReadAloud)
|
||||
.setSmallIcon(R.drawable.ic_volume_up)
|
||||
.setSubText(getString(R.string.audio))
|
||||
.setOngoing(true)
|
||||
.setContentTitle(nTitle)
|
||||
.setContentText(nSubtitle)
|
||||
.setContentIntent(
|
||||
activityPendingIntent<AudioPlayActivity>("activity")
|
||||
)
|
||||
builder.setLargeIcon(cover)
|
||||
if (pause) {
|
||||
builder.addAction(
|
||||
R.drawable.ic_play_24dp,
|
||||
getString(R.string.resume),
|
||||
servicePendingIntent<AudioPlayService>(IntentAction.resume)
|
||||
)
|
||||
} else {
|
||||
builder.addAction(
|
||||
R.drawable.ic_pause_24dp,
|
||||
getString(R.string.pause),
|
||||
servicePendingIntent<AudioPlayService>(IntentAction.pause)
|
||||
)
|
||||
}
|
||||
builder.addAction(
|
||||
R.drawable.ic_stop_black_24dp,
|
||||
getString(R.string.stop),
|
||||
servicePendingIntent<AudioPlayService>(IntentAction.stop)
|
||||
)
|
||||
builder.addAction(
|
||||
R.drawable.ic_time_add_24dp,
|
||||
getString(R.string.set_timer),
|
||||
servicePendingIntent<AudioPlayService>(IntentAction.addTimer)
|
||||
)
|
||||
builder.setStyle(
|
||||
androidx.media.app.NotificationCompat.MediaStyle()
|
||||
.setShowActionsInCompactView(0, 1, 2)
|
||||
.setMediaSession(mediaSessionCompat?.sessionToken)
|
||||
)
|
||||
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
builder
|
||||
createNotification()
|
||||
}.onSuccess {
|
||||
startForeground(NotificationId.AudioPlayService, it.build())
|
||||
}
|
||||
|
@ -21,7 +21,13 @@ import androidx.media.AudioFocusRequestCompat
|
||||
import androidx.media.AudioManagerCompat
|
||||
import io.legado.app.R
|
||||
import io.legado.app.base.BaseService
|
||||
import io.legado.app.constant.*
|
||||
import io.legado.app.constant.AppConst
|
||||
import io.legado.app.constant.AppLog
|
||||
import io.legado.app.constant.EventBus
|
||||
import io.legado.app.constant.IntentAction
|
||||
import io.legado.app.constant.NotificationId
|
||||
import io.legado.app.constant.PreferKey
|
||||
import io.legado.app.constant.Status
|
||||
import io.legado.app.help.MediaHelp
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.help.glide.ImageLoader
|
||||
@ -30,10 +36,18 @@ import io.legado.app.model.ReadBook
|
||||
import io.legado.app.receiver.MediaButtonReceiver
|
||||
import io.legado.app.ui.book.read.ReadBookActivity
|
||||
import io.legado.app.ui.book.read.page.entities.TextChapter
|
||||
import io.legado.app.utils.*
|
||||
import kotlinx.coroutines.*
|
||||
import io.legado.app.utils.activityPendingIntent
|
||||
import io.legado.app.utils.broadcastPendingIntent
|
||||
import io.legado.app.utils.getPrefBoolean
|
||||
import io.legado.app.utils.observeEvent
|
||||
import io.legado.app.utils.postEvent
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import splitties.init.appCtx
|
||||
import splitties.systemservices.audioManager
|
||||
import splitties.systemservices.notificationManager
|
||||
@ -158,7 +172,6 @@ abstract class BaseReadAloudService : BaseService(),
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
upNotification()
|
||||
when (intent?.action) {
|
||||
IntentAction.play -> newReadAloud(
|
||||
intent.getBooleanExtra("play", true),
|
||||
@ -516,7 +529,7 @@ abstract class BaseReadAloudService : BaseService(),
|
||||
/**
|
||||
* 更新通知
|
||||
*/
|
||||
override fun upNotification() {
|
||||
override fun startForegroundNotification() {
|
||||
execute {
|
||||
createNotification()
|
||||
}.onSuccess {
|
||||
|
@ -24,6 +24,7 @@ import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import splitties.init.appCtx
|
||||
import splitties.systemservices.notificationManager
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.math.min
|
||||
|
||||
@ -59,13 +60,12 @@ class CacheBookService : BaseService() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
isRun = true
|
||||
CacheBook.successDownloadSet.clear()
|
||||
CacheBook.errorDownloadMap.clear()
|
||||
CacheBook.clear()
|
||||
lifecycleScope.launch {
|
||||
while (isActive) {
|
||||
delay(1000)
|
||||
notificationContent = CacheBook.downloadSummary
|
||||
upNotification()
|
||||
upCacheBookNotification()
|
||||
postEvent(EventBus.UP_DOWNLOAD, "")
|
||||
}
|
||||
}
|
||||
@ -90,10 +90,7 @@ class CacheBookService : BaseService() {
|
||||
override fun onDestroy() {
|
||||
isRun = false
|
||||
cachePool.close()
|
||||
CacheBook.cacheBookMap.forEach { it.value.stop() }
|
||||
CacheBook.cacheBookMap.clear()
|
||||
CacheBook.successDownloadSet.clear()
|
||||
CacheBook.errorDownloadMap.clear()
|
||||
CacheBook.close()
|
||||
super.onDestroy()
|
||||
postEvent(EventBus.UP_DOWNLOAD, "")
|
||||
}
|
||||
@ -134,7 +131,7 @@ class CacheBookService : BaseService() {
|
||||
}
|
||||
cacheBook.addDownload(start, end2)
|
||||
notificationContent = CacheBook.downloadSummary
|
||||
upNotification()
|
||||
upCacheBookNotification()
|
||||
if (downloadJob == null) {
|
||||
download()
|
||||
}
|
||||
@ -175,10 +172,16 @@ class CacheBookService : BaseService() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun upCacheBookNotification() {
|
||||
notificationBuilder.setContentText(notificationContent)
|
||||
val notification = notificationBuilder.build()
|
||||
notificationManager.notify(NotificationId.CacheBookService, notification)
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新通知
|
||||
*/
|
||||
override fun upNotification() {
|
||||
override fun startForegroundNotification() {
|
||||
notificationBuilder.setContentText(notificationContent)
|
||||
val notification = notificationBuilder.build()
|
||||
startForeground(NotificationId.CacheBookService, notification)
|
||||
|
@ -72,7 +72,7 @@ class CheckSourceService : BaseService() {
|
||||
check(it)
|
||||
}
|
||||
|
||||
IntentAction.resume -> upNotification()
|
||||
IntentAction.resume -> startForegroundNotification()
|
||||
IntentAction.stop -> stopSelf()
|
||||
}
|
||||
return super.onStartCommand(intent, flags, startId)
|
||||
@ -96,7 +96,7 @@ class CheckSourceService : BaseService() {
|
||||
processIndex = 0
|
||||
threadCount = min(allIds.size, threadCount)
|
||||
notificationMsg = getString(R.string.progress_show, "", 0, allIds.size)
|
||||
upNotification()
|
||||
startForegroundNotification()
|
||||
for (i in 0 until threadCount) {
|
||||
check()
|
||||
}
|
||||
@ -252,7 +252,7 @@ class CheckSourceService : BaseService() {
|
||||
checkedIds.add(sourceUrl)
|
||||
notificationMsg =
|
||||
getString(R.string.progress_show, sourceName, checkedIds.size, allIds.size)
|
||||
upNotification()
|
||||
startForegroundNotification()
|
||||
if (processIndex > allIds.size + threadCount - 1) {
|
||||
stopSelf()
|
||||
}
|
||||
@ -262,7 +262,7 @@ class CheckSourceService : BaseService() {
|
||||
/**
|
||||
* 更新通知
|
||||
*/
|
||||
override fun upNotification() {
|
||||
override fun startForegroundNotification() {
|
||||
notificationBuilder.setContentText(notificationMsg)
|
||||
notificationBuilder.setProgress(allIds.size, checkedIds.size, false)
|
||||
postEvent(EventBus.CHECK_SOURCE, notificationMsg)
|
||||
|
@ -223,7 +223,7 @@ class DownloadService : BaseService() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun upNotification() {
|
||||
override fun startForegroundNotification() {
|
||||
val notification = NotificationCompat.Builder(this, AppConst.channelIdDownload)
|
||||
.setSmallIcon(R.drawable.ic_download)
|
||||
.setSubText(getString(R.string.action_download))
|
||||
|
@ -50,12 +50,19 @@ import io.legado.app.utils.readText
|
||||
import io.legado.app.utils.servicePendingIntent
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import io.legado.app.utils.writeBytes
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers.Default
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.flow.buffer
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.withIndex
|
||||
import kotlinx.coroutines.launch
|
||||
import me.ag2s.epublib.domain.Author
|
||||
import me.ag2s.epublib.domain.Date
|
||||
@ -133,7 +140,7 @@ class ExportBookService : BaseService() {
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun upNotification() {
|
||||
override fun startForegroundNotification() {
|
||||
val notification = NotificationCompat.Builder(this, AppConst.channelIdDownload)
|
||||
.setSmallIcon(R.drawable.ic_export)
|
||||
.setSubText(getString(R.string.export_book))
|
||||
@ -322,15 +329,23 @@ class ExportBookService : BaseService() {
|
||||
}"
|
||||
append(qy, null)
|
||||
if (AppConfig.parallelExportBook) {
|
||||
val oc =
|
||||
OrderCoroutine<Pair<String, ArrayList<SrcData>?>>(AppConfig.threadCount)
|
||||
appDb.bookChapterDao.getChapterList(book.bookUrl).forEach { chapter ->
|
||||
oc.submit { getExportData(book, chapter, contentProcessor, useReplace) }
|
||||
}
|
||||
oc.collect { index, result ->
|
||||
postEvent(EventBus.EXPORT_BOOK, book.bookUrl)
|
||||
exportProgress[book.bookUrl] = index
|
||||
append.invoke(result.first, result.second)
|
||||
coroutineScope {
|
||||
flow {
|
||||
appDb.bookChapterDao.getChapterList(book.bookUrl).forEach { chapter ->
|
||||
val task = async(Default, start = CoroutineStart.LAZY) {
|
||||
getExportData(book, chapter, contentProcessor, useReplace)
|
||||
}
|
||||
emit(task)
|
||||
}
|
||||
}.onEach { it.start() }
|
||||
.buffer(AppConfig.threadCount)
|
||||
.map { it.await() }
|
||||
.withIndex()
|
||||
.collect { (index, result) ->
|
||||
postEvent(EventBus.EXPORT_BOOK, book.bookUrl)
|
||||
exportProgress[book.bookUrl] = index
|
||||
append.invoke(result.first, result.second)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
appDb.bookChapterDao.getChapterList(book.bookUrl).forEachIndexed { index, chapter ->
|
||||
|
@ -80,11 +80,11 @@ class WebService : BaseService() {
|
||||
if (address == null) {
|
||||
hostAddress = getString(R.string.network_connection_unavailable)
|
||||
notificationContent = hostAddress
|
||||
upNotification()
|
||||
startForegroundNotification()
|
||||
} else {
|
||||
hostAddress = getString(R.string.http_ip, address.hostAddress, getPort())
|
||||
notificationContent = hostAddress
|
||||
upNotification()
|
||||
startForegroundNotification()
|
||||
}
|
||||
postEvent(EventBus.WEB_SERVICE, hostAddress)
|
||||
}
|
||||
@ -142,7 +142,7 @@ class WebService : BaseService() {
|
||||
isRun = true
|
||||
postEvent(EventBus.WEB_SERVICE, hostAddress)
|
||||
notificationContent = hostAddress
|
||||
upNotification()
|
||||
startForegroundNotification()
|
||||
} catch (e: IOException) {
|
||||
toastOnUi(e.localizedMessage ?: "")
|
||||
e.printOnDebug()
|
||||
@ -165,7 +165,7 @@ class WebService : BaseService() {
|
||||
/**
|
||||
* 更新通知
|
||||
*/
|
||||
override fun upNotification() {
|
||||
override fun startForegroundNotification() {
|
||||
val builder = NotificationCompat.Builder(this, AppConst.channelIdWeb)
|
||||
.setSmallIcon(R.drawable.ic_web_service_noti)
|
||||
.setOngoing(true)
|
||||
|
Loading…
Reference in New Issue
Block a user