优化书源校验

pull/414/head
gedoor 4 years ago
parent 9eb3c895b0
commit e351cafdf3
  1. 8
      app/build.gradle
  2. 6
      app/src/main/java/io/legado/app/constant/EventBus.kt
  3. 3
      app/src/main/java/io/legado/app/help/AppConfig.kt
  4. 22
      app/src/main/java/io/legado/app/service/CheckSourceService.kt
  5. 106
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt
  6. 1
      app/src/main/res/layout/activity_book_source.xml
  7. 1
      app/src/main/res/values/pref_key_value.xml
  8. 7
      app/src/main/res/xml/pref_config_other.xml

@ -121,15 +121,15 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
//fireBase //fireBase
implementation 'com.google.firebase:firebase-analytics-ktx:17.5.0' implementation 'com.google.firebase:firebase-analytics-ktx:17.6.0'
implementation 'com.google.firebase:firebase-crashlytics-ktx:17.2.1' implementation 'com.google.firebase:firebase-crashlytics-ktx:17.2.2'
//androidX //androidX
implementation 'androidx.core:core-ktx:1.3.1' implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.media:media:1.2.0' implementation 'androidx.media:media:1.2.0'
implementation 'androidx.preference:preference:1.1.1' implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1' implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'androidx.viewpager2:viewpager2:1.0.0' implementation 'androidx.viewpager2:viewpager2:1.0.0'
implementation 'com.google.android.material:material:1.2.1' implementation 'com.google.android.material:material:1.2.1'

@ -20,8 +20,6 @@ object EventBus {
const val WEB_SERVICE = "webService" const val WEB_SERVICE = "webService"
const val UP_DOWNLOAD = "upDownload" const val UP_DOWNLOAD = "upDownload"
const val SAVE_CONTENT = "saveContent" const val SAVE_CONTENT = "saveContent"
const val CHECK_INIT = "checkInit" const val CHECK_SOURCE = "checkSource"
const val CHECK_UP_PROGRESS = "checkProgress" const val CHECK_SOURCE_DONE = "checkSourceDone"
const val CHECK_UP_PROGRESS_STRING = "checkProgressTxt"
const val CHECK_DONE = "checkDone"
} }

@ -58,9 +58,6 @@ object AppConfig {
App.INSTANCE.putPrefBoolean(PreferKey.showRss, value) App.INSTANCE.putPrefBoolean(PreferKey.showRss, value)
} }
val backgroundVerification: Boolean
get() = App.INSTANCE.getPrefBoolean(R.string.pk_background_verification, true)
val autoRefreshBook: Boolean val autoRefreshBook: Boolean
get() = App.INSTANCE.getPrefBoolean(R.string.pk_auto_refresh) get() = App.INSTANCE.getPrefBoolean(R.string.pk_auto_refresh)

@ -9,7 +9,6 @@ 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.constant.IntentAction
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.help.AppConfig.backgroundVerification
import io.legado.app.help.IntentHelp import io.legado.app.help.IntentHelp
import io.legado.app.help.coroutine.CompositeCoroutine import io.legado.app.help.coroutine.CompositeCoroutine
import io.legado.app.service.help.CheckSource import io.legado.app.service.help.CheckSource
@ -45,9 +44,7 @@ class CheckSourceService : BaseService() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
if (backgroundVerification) { updateNotification(0, getString(R.string.start))
updateNotification(0, getString(R.string.start))
}
} }
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
@ -64,7 +61,7 @@ class CheckSourceService : BaseService() {
super.onDestroy() super.onDestroy()
tasks.clear() tasks.clear()
searchPool.close() searchPool.close()
postEvent(EventBus.CHECK_DONE, 0) postEvent(EventBus.CHECK_SOURCE_DONE, 0)
} }
private fun check(ids: List<String>) { private fun check(ids: List<String>) {
@ -78,7 +75,6 @@ class CheckSourceService : BaseService() {
allIds.addAll(ids) allIds.addAll(ids)
processIndex = 0 processIndex = 0
threadCount = min(allIds.size, threadCount) threadCount = min(allIds.size, threadCount)
postEvent(EventBus.CHECK_INIT, allIds.size)
updateNotification(0, getString(R.string.progress_show, "", 0, allIds.size)) updateNotification(0, getString(R.string.progress_show, "", 0, allIds.size))
for (i in 0 until threadCount) { for (i in 0 until threadCount) {
check() check()
@ -113,15 +109,10 @@ class CheckSourceService : BaseService() {
synchronized(this) { synchronized(this) {
check() check()
checkedIds.add(sourceUrl) checkedIds.add(sourceUrl)
if (backgroundVerification) { updateNotification(
updateNotification( checkedIds.size,
checkedIds.size, getString(R.string.progress_show, sourceName, checkedIds.size, allIds.size)
getString(R.string.progress_show, sourceName, checkedIds.size, allIds.size) )
)
} else {
postEvent(EventBus.CHECK_UP_PROGRESS, checkedIds.size)
postEvent(EventBus.CHECK_UP_PROGRESS_STRING, getString(R.string.progress_show, sourceName, checkedIds.size, allIds.size))
}
if (processIndex >= allIds.size + threadCount - 1) { if (processIndex >= allIds.size + threadCount - 1) {
stopSelf() stopSelf()
} }
@ -134,6 +125,7 @@ class CheckSourceService : BaseService() {
private fun updateNotification(state: Int, msg: String) { private fun updateNotification(state: Int, msg: String) {
notificationBuilder.setContentText(msg) notificationBuilder.setContentText(msg)
notificationBuilder.setProgress(allIds.size, state, false) notificationBuilder.setProgress(allIds.size, state, false)
postEvent(EventBus.CHECK_SOURCE, msg)
startForeground(112202, notificationBuilder.build()) startForeground(112202, notificationBuilder.build())
} }

@ -5,8 +5,9 @@ import android.app.Activity
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.DisplayMetrics import android.view.Menu
import android.view.* import android.view.MenuItem
import android.view.SubMenu
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
@ -15,15 +16,14 @@ import androidx.lifecycle.LiveData
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
import io.legado.app.App import io.legado.app.App
import io.legado.app.BuildConfig import io.legado.app.BuildConfig
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseDialogFragment
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.AppPattern import io.legado.app.constant.AppPattern
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.help.AppConfig
import io.legado.app.help.IntentDataHelp import io.legado.app.help.IntentDataHelp
import io.legado.app.lib.dialogs.* import io.legado.app.lib.dialogs.*
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
@ -42,9 +42,7 @@ import io.legado.app.ui.widget.text.AutoCompleteTextView
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.activity_book_source.* import kotlinx.android.synthetic.main.activity_book_source.*
import kotlinx.android.synthetic.main.dialog_edit_text.view.* import kotlinx.android.synthetic.main.dialog_edit_text.view.*
import kotlinx.android.synthetic.main.dialog_progressbar_view.*
import kotlinx.android.synthetic.main.view_search.* import kotlinx.android.synthetic.main.view_search.*
import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.startActivity import org.jetbrains.anko.startActivity
import org.jetbrains.anko.startActivityForResult import org.jetbrains.anko.startActivityForResult
import org.jetbrains.anko.toast import org.jetbrains.anko.toast
@ -68,6 +66,7 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
private var groupMenu: SubMenu? = null private var groupMenu: SubMenu? = null
private var sort = 0 private var sort = 0
private var sortAscending = 0 private var sortAscending = 0
private var snackBar: Snackbar? = null
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
initRecyclerView() initRecyclerView()
@ -100,11 +99,20 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
val intent = Intent(Intent.ACTION_SEND) val intent = Intent(Intent.ACTION_SEND)
val file = FileUtils.createFileWithReplace("$filesDir/shareBookSource.json") val file = FileUtils.createFileWithReplace("$filesDir/shareBookSource.json")
file.writeText(json) file.writeText(json)
val fileUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileProvider", file) val fileUri = FileProvider.getUriForFile(
this,
BuildConfig.APPLICATION_ID + ".fileProvider",
file
)
intent.type = "text/*" intent.type = "text/*"
intent.putExtra(Intent.EXTRA_STREAM, fileUri) intent.putExtra(Intent.EXTRA_STREAM, fileUri)
intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
startActivity(Intent.createChooser(intent, getString(R.string.share_selected_source))) startActivity(
Intent.createChooser(
intent,
getString(R.string.share_selected_source)
)
)
} catch (e: ActivityNotFoundException) { } catch (e: ActivityNotFoundException) {
e.printStackTrace() e.printStackTrace()
} }
@ -196,19 +204,19 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
} }
} }
bookSourceLiveDate?.observe(this, { data -> bookSourceLiveDate?.observe(this, { data ->
val sourceList = when (sortAscending % 2){ val sourceList = when (sortAscending % 2) {
0 -> when (sort) { 0 -> when (sort) {
1 -> data.sortedBy { it.weight } 1 -> data.sortedBy { it.weight }
2 -> data.sortedBy { it.bookSourceName } 2 -> data.sortedBy { it.bookSourceName }
3 -> data.sortedBy { it.bookSourceUrl } 3 -> data.sortedBy { it.bookSourceUrl }
4 -> data.sortedByDescending { it.lastUpdateTime} 4 -> data.sortedByDescending { it.lastUpdateTime }
else -> data else -> data
} }
else -> when (sort) { else -> when (sort) {
1 -> data.sortedByDescending { it.weight } 1 -> data.sortedByDescending { it.weight }
2 -> data.sortedByDescending { it.bookSourceName } 2 -> data.sortedByDescending { it.bookSourceName }
3 -> data.sortedByDescending { it.bookSourceUrl } 3 -> data.sortedByDescending { it.bookSourceUrl }
4 -> data.sortedBy { it.lastUpdateTime} 4 -> data.sortedBy { it.lastUpdateTime }
else -> data.reversed() else -> data.reversed()
} }
} }
@ -218,11 +226,11 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
upCountView() upCountView()
}) })
} }
private fun sortCheck (sortId: Int){
if (sort == sortId){ private fun sortCheck(sortId: Int) {
sortAscending +=1 if (sort == sortId) {
} sortAscending += 1
else{ } else {
sortAscending = 0 sortAscending = 0
sort = sortId sort = sortId
} }
@ -299,13 +307,6 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
CheckSource.keyword = it CheckSource.keyword = it
} }
} }
if (!AppConfig.backgroundVerification) {
val bundle = Bundle()
bundle.putInt("maxProgress", adapter.getSelection().size)
CheckSourceDialog().apply {
arguments = bundle
}.show(supportFragmentManager, "CheckDialog")
}
CheckSource.start(this@BookSourceActivity, adapter.getSelection()) CheckSource.start(this@BookSourceActivity, adapter.getSelection())
} }
noButton { } noButton { }
@ -396,8 +397,21 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
} }
override fun observeLiveBus() { override fun observeLiveBus() {
observeEvent<Int>(EventBus.CHECK_DONE) { observeEvent<String>(EventBus.CHECK_SOURCE) { msg ->
groups.map { group-> snackBar?.setText(msg) ?: let {
snackBar = Snackbar
.make(root_view, msg, Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.cancel) {
CheckSource.stop(this)
}.apply { show() }
}
}
observeEvent<Int>(EventBus.CHECK_SOURCE_DONE) {
snackBar?.let {
it.dismiss()
snackBar = null
}
groups.map { group ->
if (group.contains("失效")) { if (group.contains("失效")) {
search_view.setQuery("失效", true) search_view.setQuery("失效", true)
toast("发现有失效书源,已为您自动筛选!") toast("发现有失效书源,已为您自动筛选!")
@ -501,46 +515,4 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
} }
} }
class CheckSourceDialog : BaseDialogFragment() {
override fun onStart() {
super.onStart()
val dm = DisplayMetrics()
activity?.windowManager?.defaultDisplay?.getMetrics(dm)
dialog?.window?.setLayout(
(dm.widthPixels * 0.9).toInt(),
(dm.heightPixels * 0.14).toInt()
)
dialog?.setCancelable(false)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.dialog_progressbar_view, container)
}
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
arguments?.let { bundle ->
val maxProgress = bundle.getInt("maxProgress")
ck_progress_text.text = getString(R.string.progress_show, "", 0, maxProgress)
ck_progress.max = maxProgress
observeEvent<Int>(EventBus.CHECK_UP_PROGRESS) { progress->
ck_progress.progress = progress
}
observeEvent<String>(EventBus.CHECK_UP_PROGRESS_STRING) {
ck_progress_text.text = it
}
observeEvent<Int>(EventBus.CHECK_DONE) {
dismiss()
}
tv_footer_left.onClick {
CheckSource.stop(requireContext()).apply {
dismiss()
}
}
}
}
}
} }

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="pk_background_verification" translatable="false">background_verification</string>
<string name="pk_auto_refresh" translatable="false">auto_refresh</string> <string name="pk_auto_refresh" translatable="false">auto_refresh</string>
<string name="pk_requested_direction" translatable="false">list_screen_direction</string> <string name="pk_requested_direction" translatable="false">list_screen_direction</string>
<string name="pk_full_screen" translatable="false">full_screen</string> <string name="pk_full_screen" translatable="false">full_screen</string>

@ -51,13 +51,6 @@
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
app:layout="@layout/view_preference_category"> app:layout="@layout/view_preference_category">
<io.legado.app.ui.widget.prefs.SwitchPreference
android:defaultValue="true"
android:key="@string/pk_background_verification"
android:summary="@string/ps_background_verification"
android:title="@string/pt_background_verification"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.SwitchPreference <io.legado.app.ui.widget.prefs.SwitchPreference
android:defaultValue="true" android:defaultValue="true"
android:key="replaceEnableDefault" android:key="replaceEnableDefault"

Loading…
Cancel
Save