| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -17,7 +17,6 @@ import kotlinx.coroutines.CoroutineScope | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import java.text.SimpleDateFormat | 
					 | 
					 | 
					 | 
					import java.text.SimpleDateFormat | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import java.util.* | 
					 | 
					 | 
					 | 
					import java.util.* | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import java.util.concurrent.ConcurrentHashMap | 
					 | 
					 | 
					 | 
					import java.util.concurrent.ConcurrentHashMap | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import java.util.concurrent.CopyOnWriteArraySet | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import kotlin.coroutines.CoroutineContext | 
					 | 
					 | 
					 | 
					import kotlin.coroutines.CoroutineContext | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class CacheBook(val bookSource: BookSource, val book: Book) { | 
					 | 
					 | 
					 | 
					class CacheBook(val bookSource: BookSource, val book: Book) { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -117,22 +116,40 @@ class CacheBook(val bookSource: BookSource, val book: Book) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    val waitDownloadSet = CopyOnWriteArraySet<Int>() | 
					 | 
					 | 
					 | 
					    val waitDownloadSet = hashSetOf<Int>() | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    val onDownloadSet = CopyOnWriteArraySet<Int>() | 
					 | 
					 | 
					 | 
					    val onDownloadSet = hashSetOf<Int>() | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    val successDownloadSet = CopyOnWriteArraySet<Int>() | 
					 | 
					 | 
					 | 
					    val successDownloadSet = hashSetOf<Int>() | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    fun addDownload(start: Int, end: Int) { | 
					 | 
					 | 
					 | 
					    fun addDownload(start: Int, end: Int) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        synchronized(this) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            for (i in start..end) { | 
					 | 
					 | 
					 | 
					            for (i in start..end) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                waitDownloadSet.add(i) | 
					 | 
					 | 
					 | 
					                waitDownloadSet.add(i) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    fun isRun(): Boolean { | 
					 | 
					 | 
					 | 
					    fun isRun(): Boolean { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return waitDownloadSet.size > 0 || onDownloadSet.size > 0 | 
					 | 
					 | 
					 | 
					        return synchronized(this) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            waitDownloadSet.size > 0 || onDownloadSet.size > 0 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    private fun onSuccess(index: Int) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        synchronized(this) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            onDownloadSet.remove(index) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            successDownloadSet.add(index) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    private fun onErrorOrCancel(index: Int) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        synchronized(this) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            onDownloadSet.remove(index) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            waitDownloadSet.add(index) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    @Synchronized | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    fun download(scope: CoroutineScope, context: CoroutineContext): Boolean { | 
					 | 
					 | 
					 | 
					    fun download(scope: CoroutineScope, context: CoroutineContext): Boolean { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        synchronized(this) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            val chapterIndex = waitDownloadSet.firstOrNull() ?: return false | 
					 | 
					 | 
					 | 
					            val chapterIndex = waitDownloadSet.firstOrNull() ?: return false | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            if (onDownloadSet.contains(chapterIndex)) { | 
					 | 
					 | 
					 | 
					            if (onDownloadSet.contains(chapterIndex)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                waitDownloadSet.remove(chapterIndex) | 
					 | 
					 | 
					 | 
					                waitDownloadSet.remove(chapterIndex) | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -155,19 +172,16 @@ class CacheBook(val bookSource: BookSource, val book: Book) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                chapter, | 
					 | 
					 | 
					 | 
					                chapter, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                context = context | 
					 | 
					 | 
					 | 
					                context = context | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            ).onSuccess { content -> | 
					 | 
					 | 
					 | 
					            ).onSuccess { content -> | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            onDownloadSet.remove(chapterIndex) | 
					 | 
					 | 
					 | 
					                onSuccess(chapterIndex) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            successDownloadSet.add(chapterIndex) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                addLog("${book.name}-${chapter.title} getContentSuccess") | 
					 | 
					 | 
					 | 
					                addLog("${book.name}-${chapter.title} getContentSuccess") | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                downloadFinish(chapter, content.ifBlank { "No content" }) | 
					 | 
					 | 
					 | 
					                downloadFinish(chapter, content.ifBlank { "No content" }) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            }.onError { | 
					 | 
					 | 
					 | 
					            }.onError { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            onDownloadSet.remove(chapterIndex) | 
					 | 
					 | 
					 | 
					                onErrorOrCancel(chapterIndex) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            waitDownloadSet.add(chapterIndex) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                print(it.localizedMessage) | 
					 | 
					 | 
					 | 
					                print(it.localizedMessage) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                addLog("${book.name}-${chapter.title} getContentError${it.localizedMessage}") | 
					 | 
					 | 
					 | 
					                addLog("${book.name}-${chapter.title} getContentError${it.localizedMessage}") | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                downloadFinish(chapter, it.localizedMessage ?: "download error") | 
					 | 
					 | 
					 | 
					                downloadFinish(chapter, it.localizedMessage ?: "download error") | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            }.onCancel { | 
					 | 
					 | 
					 | 
					            }.onCancel { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            onDownloadSet.remove(chapterIndex) | 
					 | 
					 | 
					 | 
					                onErrorOrCancel(chapterIndex) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            waitDownloadSet.add(chapterIndex) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            }.onFinally { | 
					 | 
					 | 
					 | 
					            }.onFinally { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                if (waitDownloadSet.isEmpty() && onDownloadSet.isEmpty()) { | 
					 | 
					 | 
					 | 
					                if (waitDownloadSet.isEmpty() && onDownloadSet.isEmpty()) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    postEvent(EventBus.UP_DOWNLOAD, "") | 
					 | 
					 | 
					 | 
					                    postEvent(EventBus.UP_DOWNLOAD, "") | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -175,6 +189,7 @@ class CacheBook(val bookSource: BookSource, val book: Book) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            return true | 
					 | 
					 | 
					 | 
					            return true | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    @Synchronized | 
					 | 
					 | 
					 | 
					    @Synchronized | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    fun download( | 
					 | 
					 | 
					 | 
					    fun download( | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -182,6 +197,7 @@ class CacheBook(val bookSource: BookSource, val book: Book) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        chapter: BookChapter, | 
					 | 
					 | 
					 | 
					        chapter: BookChapter, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        resetPageOffset: Boolean = false | 
					 | 
					 | 
					 | 
					        resetPageOffset: Boolean = false | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    ) { | 
					 | 
					 | 
					 | 
					    ) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        synchronized(this) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            if (onDownloadSet.contains(chapter.index)) { | 
					 | 
					 | 
					 | 
					            if (onDownloadSet.contains(chapter.index)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                return | 
					 | 
					 | 
					 | 
					                return | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            } | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -190,12 +206,19 @@ class CacheBook(val bookSource: BookSource, val book: Book) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                .onSuccess { content -> | 
					 | 
					 | 
					 | 
					                .onSuccess { content -> | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    downloadFinish(chapter, content.ifBlank { "No content" }, resetPageOffset) | 
					 | 
					 | 
					 | 
					                    downloadFinish(chapter, content.ifBlank { "No content" }, resetPageOffset) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                }.onError { | 
					 | 
					 | 
					 | 
					                }.onError { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                downloadFinish(chapter, it.localizedMessage ?: "download error", resetPageOffset) | 
					 | 
					 | 
					 | 
					                    downloadFinish( | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        chapter, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        it.localizedMessage ?: "download error", | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                        resetPageOffset | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    ) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                }.onFinally { | 
					 | 
					 | 
					 | 
					                }.onFinally { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    synchronized(this) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                        onDownloadSet.remove(chapter.index) | 
					 | 
					 | 
					 | 
					                        onDownloadSet.remove(chapter.index) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    ReadBook.removeLoading(chapter.index) | 
					 | 
					 | 
					 | 
					                    ReadBook.removeLoading(chapter.index) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                } | 
					 | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        } | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    private fun downloadFinish( | 
					 | 
					 | 
					 | 
					    private fun downloadFinish( | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        chapter: BookChapter, | 
					 | 
					 | 
					 | 
					        chapter: BookChapter, | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |