pull/1652/head
kunfei 3 years ago
parent 8712a58ed4
commit 8dcb62c984
  1. 5
      app/build.gradle
  2. 4
      app/src/main/java/io/legado/app/App.kt
  3. 7
      app/src/main/java/io/legado/app/constant/AppLog.kt
  4. 6
      app/src/main/java/io/legado/app/data/entities/BaseSource.kt
  5. 3
      app/src/main/java/io/legado/app/data/entities/BookSource.kt
  6. 3
      app/src/main/java/io/legado/app/help/BookHelp.kt
  7. 21
      app/src/main/java/io/legado/app/help/JsExtensions.kt
  8. 10
      app/src/main/java/io/legado/app/help/ReadBookConfig.kt
  9. 4
      app/src/main/java/io/legado/app/help/SourceAnalyzer.kt
  10. 4
      app/src/main/java/io/legado/app/help/ThemeConfig.kt
  11. 5
      app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt
  12. 11
      app/src/main/java/io/legado/app/help/http/SSLHelper.kt
  13. 6
      app/src/main/java/io/legado/app/help/http/cronet/CronetHelper.kt
  14. 5
      app/src/main/java/io/legado/app/help/http/cronet/CronetInterceptor.kt
  15. 56
      app/src/main/java/io/legado/app/help/http/cronet/CronetLoader.kt
  16. 11
      app/src/main/java/io/legado/app/help/http/cronet/CronetRequestCallback.kt
  17. 4
      app/src/main/java/io/legado/app/help/storage/OldBook.kt
  18. 11
      app/src/main/java/io/legado/app/help/storage/Preferences.kt
  19. 12
      app/src/main/java/io/legado/app/help/storage/Restore.kt
  20. 7
      app/src/main/java/io/legado/app/lib/webdav/WebDav.kt
  21. 3
      app/src/main/java/io/legado/app/model/CacheBook.kt
  22. 4
      app/src/main/java/io/legado/app/model/ReadBook.kt
  23. 9
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSonPath.kt
  24. 4
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt
  25. 11
      app/src/main/java/io/legado/app/model/localBook/EpubFile.kt
  26. 4
      app/src/main/java/io/legado/app/model/localBook/LocalBook.kt
  27. 10
      app/src/main/java/io/legado/app/model/localBook/UmdFile.kt
  28. 13
      app/src/main/java/io/legado/app/model/webBook/BookInfo.kt
  29. 9
      app/src/main/java/io/legado/app/service/AudioPlayService.kt
  30. 8
      app/src/main/java/io/legado/app/service/HttpReadAloudService.kt
  31. 4
      app/src/main/java/io/legado/app/service/WebService.kt
  32. 4
      app/src/main/java/io/legado/app/service/WebTileService.kt
  33. 9
      app/src/main/java/io/legado/app/ui/about/DonateFragment.kt
  34. 5
      app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt
  35. 5
      app/src/main/java/io/legado/app/ui/association/FileAssociationViewModel.kt
  36. 4
      app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt
  37. 6
      app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt
  38. 7
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceViewModel.kt
  39. 7
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeChapterSourceViewModel.kt
  40. 5
      app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt
  41. 4
      app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt
  42. 8
      app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt
  43. 6
      app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt
  44. 4
      app/src/main/java/io/legado/app/ui/browser/WebViewModel.kt
  45. 10
      app/src/main/java/io/legado/app/ui/document/HandleFileViewModel.kt
  46. 4
      app/src/main/java/io/legado/app/ui/font/FontAdapter.kt
  47. 4
      app/src/main/java/io/legado/app/ui/login/SourceLoginDialog.kt
  48. 3
      app/src/main/java/io/legado/app/ui/main/MainViewModel.kt
  49. 8
      app/src/main/java/io/legado/app/ui/rss/article/RssArticlesViewModel.kt
  50. 5
      app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditViewModel.kt
  51. 4
      app/src/main/java/io/legado/app/ui/widget/SearchView.kt
  52. 7
      app/src/main/java/io/legado/app/ui/widget/anima/explosion_field/ExplosionView.kt
  53. 5
      app/src/main/java/io/legado/app/ui/widget/anima/explosion_field/Utils.kt
  54. 9
      app/src/main/java/io/legado/app/ui/widget/image/CircleImageView.kt
  55. 8
      app/src/main/java/io/legado/app/ui/widget/recycler/DividerNoLast.kt
  56. 9
      app/src/main/java/io/legado/app/ui/widget/recycler/DragSelectTouchHelper.kt
  57. 32
      app/src/main/java/io/legado/app/utils/ACache.kt
  58. 6
      app/src/main/java/io/legado/app/utils/ContextExtensions.kt
  59. 54
      app/src/main/java/io/legado/app/utils/DebugLog.kt
  60. 6
      app/src/main/java/io/legado/app/utils/FileUtils.kt
  61. 8
      app/src/main/java/io/legado/app/utils/GsonExtensions.kt
  62. 7
      app/src/main/java/io/legado/app/utils/LogUtils.kt
  63. 4
      app/src/main/java/io/legado/app/utils/MD5Utils.kt
  64. 9
      app/src/main/java/io/legado/app/utils/NetworkUtils.kt
  65. 8
      app/src/main/java/io/legado/app/utils/RealPathUtil.kt
  66. 4
      app/src/main/java/io/legado/app/utils/StringUtils.kt
  67. 6
      app/src/main/java/io/legado/app/utils/UriExtensions.kt
  68. 4
      app/src/main/java/io/legado/app/utils/ViewExtensions.kt
  69. 10
      app/src/main/java/io/legado/app/utils/ZipUtils.kt
  70. 9
      app/src/main/java/io/legado/app/web/socket/BookSourceDebugWebSocket.kt
  71. 9
      app/src/main/java/io/legado/app/web/socket/RssSourceDebugWebSocket.kt
  72. 1
      build.gradle

@ -3,6 +3,7 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize' apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply plugin: 'de.timfreiheit.resourceplaceholders' apply plugin: 'de.timfreiheit.resourceplaceholders'
apply plugin: 'com.google.gms.google-services'
apply from: 'download.gradle' apply from: 'download.gradle'
static def releaseTime() { static def releaseTime() {
@ -150,7 +151,9 @@ dependencies {
implementation('com.google.code.gson:gson:2.8.9') implementation('com.google.code.gson:gson:2.8.9')
implementation('androidx.webkit:webkit:1.4.0') implementation('androidx.webkit:webkit:1.4.0')
implementation('com.jakewharton.timber:timber:5.0.1') //firebase
implementation platform('com.google.firebase:firebase-bom:29.1.0')
implementation 'com.google.firebase:firebase-analytics-ktx'
//media //media
implementation("androidx.media:media:1.5.0") implementation("androidx.media:media:1.5.0")

@ -18,16 +18,12 @@ import io.legado.app.help.ThemeConfig.applyDayNight
import io.legado.app.help.http.cronet.CronetLoader import io.legado.app.help.http.cronet.CronetLoader
import io.legado.app.utils.defaultSharedPreferences import io.legado.app.utils.defaultSharedPreferences
import splitties.systemservices.notificationManager import splitties.systemservices.notificationManager
import timber.log.Timber
class App : MultiDexApplication() { class App : MultiDexApplication() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
CrashHandler(this) CrashHandler(this)
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
}
//预下载Cronet so //预下载Cronet so
CronetLoader.preDownload() CronetLoader.preDownload()
createNotificationChannels() createNotificationChannels()

@ -1,5 +1,7 @@
package io.legado.app.constant package io.legado.app.constant
import android.util.Log
import io.legado.app.BuildConfig
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
object AppLog { object AppLog {
@ -15,6 +17,11 @@ object AppLog {
mLogs.removeLastOrNull() mLogs.removeLastOrNull()
} }
mLogs.add(0, Triple(System.currentTimeMillis(), message, throwable)) mLogs.add(0, Triple(System.currentTimeMillis(), message, throwable))
if (throwable != null) {
if (BuildConfig.DEBUG) {
Log.e(message, throwable.stackTraceToString())
}
}
} }
@Synchronized @Synchronized

@ -2,6 +2,7 @@ package io.legado.app.data.entities
import android.util.Base64 import android.util.Base64
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
import io.legado.app.constant.AppLog
import io.legado.app.data.entities.rule.RowUi import io.legado.app.data.entities.rule.RowUi
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.help.CacheManager import io.legado.app.help.CacheManager
@ -11,7 +12,6 @@ import io.legado.app.utils.EncoderUtils
import io.legado.app.utils.GSON import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonArray import io.legado.app.utils.fromJsonArray
import io.legado.app.utils.fromJsonObject import io.legado.app.utils.fromJsonObject
import timber.log.Timber
import javax.script.SimpleBindings import javax.script.SimpleBindings
/** /**
@ -111,7 +111,7 @@ interface BaseSource : JsExtensions {
?: return null ?: return null
return String(decodeBytes) return String(decodeBytes)
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) AppLog.put("获取登陆信息出错", e)
return null return null
} }
} }
@ -131,7 +131,7 @@ interface BaseSource : JsExtensions {
CacheManager.put("userInfo_${getKey()}", encodeStr) CacheManager.put("userInfo_${getKey()}", encodeStr)
true true
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) AppLog.put("保存登陆信息出错", e)
false false
} }
} }

@ -11,7 +11,6 @@ import io.legado.app.utils.*
import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
@Parcelize @Parcelize
@TypeConverters(BookSource.Converters::class) @TypeConverters(BookSource.Converters::class)
@ -120,7 +119,7 @@ data class BookSource(
} }
}.onFailure { }.onFailure {
kinds.add(ExploreKind("ERROR:${it.localizedMessage}", it.stackTraceToString())) kinds.add(ExploreKind("ERROR:${it.localizedMessage}", it.stackTraceToString()))
Timber.e(it) it.printOnDebug()
} }
} }
return@lazy kinds return@lazy kinds

@ -16,7 +16,6 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import org.apache.commons.text.similarity.JaccardSimilarity import org.apache.commons.text.similarity.JaccardSimilarity
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.io.File import java.io.File
import java.util.concurrent.CopyOnWriteArraySet import java.util.concurrent.CopyOnWriteArraySet
import java.util.regex.Pattern import java.util.regex.Pattern
@ -131,7 +130,7 @@ object BookHelp {
).writeBytes(it) ).writeBytes(it)
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} finally { } finally {
downloadImages.remove(src) downloadImages.remove(src)
} }

@ -6,7 +6,6 @@ import androidx.annotation.Keep
import cn.hutool.crypto.digest.DigestUtil import cn.hutool.crypto.digest.DigestUtil
import cn.hutool.crypto.symmetric.AES import cn.hutool.crypto.symmetric.AES
import cn.hutool.crypto.symmetric.DESede import cn.hutool.crypto.symmetric.DESede
import io.legado.app.BuildConfig
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
import io.legado.app.constant.AppConst.dateFormat import io.legado.app.constant.AppConst.dateFormat
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
@ -22,7 +21,6 @@ import kotlinx.coroutines.runBlocking
import org.jsoup.Connection import org.jsoup.Connection
import org.jsoup.Jsoup import org.jsoup.Jsoup
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.File import java.io.File
@ -54,7 +52,7 @@ interface JsExtensions {
analyzeUrl.getStrResponseAwait().body analyzeUrl.getStrResponseAwait().body
}.onFailure { }.onFailure {
log("ajax(${urlStr}) error\n${it.stackTraceToString()}") log("ajax(${urlStr}) error\n${it.stackTraceToString()}")
Timber.e(it) it.printOnDebug()
}.getOrElse { }.getOrElse {
it.msg it.msg
} }
@ -90,7 +88,7 @@ interface JsExtensions {
analyzeUrl.getStrResponseAwait() analyzeUrl.getStrResponseAwait()
}.onFailure { }.onFailure {
log("connect(${urlStr}) error\n${it.stackTraceToString()}") log("connect(${urlStr}) error\n${it.stackTraceToString()}")
Timber.e(it) it.printOnDebug()
}.getOrElse { }.getOrElse {
StrResponse(analyzeUrl.url, it.localizedMessage) StrResponse(analyzeUrl.url, it.localizedMessage)
} }
@ -105,7 +103,7 @@ interface JsExtensions {
analyzeUrl.getStrResponseAwait() analyzeUrl.getStrResponseAwait()
}.onFailure { }.onFailure {
log("ajax($urlStr,$header) error\n${it.stackTraceToString()}") log("ajax($urlStr,$header) error\n${it.stackTraceToString()}")
Timber.e(it) it.printOnDebug()
}.getOrElse { }.getOrElse {
StrResponse(analyzeUrl.url, it.localizedMessage) StrResponse(analyzeUrl.url, it.localizedMessage)
} }
@ -481,7 +479,7 @@ interface JsExtensions {
CacheManager.put(key, qTTF) CacheManager.put(key, qTTF)
return qTTF return qTTF
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "获取字体处理类出错") AppLog.put("获取字体处理类出错", e)
throw e throw e
} }
} }
@ -518,9 +516,6 @@ interface JsExtensions {
getSource()?.let { getSource()?.let {
Debug.log(it.getKey(), msg.toString()) Debug.log(it.getKey(), msg.toString())
} ?: Debug.log(msg.toString()) } ?: Debug.log(msg.toString())
if (BuildConfig.DEBUG) {
Timber.d(msg.toString())
}
AppLog.putDebug(msg.toString()) AppLog.putDebug(msg.toString())
return msg return msg
} }
@ -561,7 +556,7 @@ interface JsExtensions {
iv.encodeToByteArray() iv.encodeToByteArray()
) )
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
log(e.localizedMessage ?: "aesDecodeToByteArrayERROR") log(e.localizedMessage ?: "aesDecodeToByteArrayERROR")
null null
} }
@ -600,7 +595,7 @@ interface JsExtensions {
iv.encodeToByteArray() iv.encodeToByteArray()
) )
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
log(e.localizedMessage ?: "aesDecodeToByteArrayERROR") log(e.localizedMessage ?: "aesDecodeToByteArrayERROR")
null null
} }
@ -638,7 +633,7 @@ interface JsExtensions {
iv.encodeToByteArray() iv.encodeToByteArray()
) )
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
log(e.localizedMessage ?: "aesEncodeToByteArrayERROR") log(e.localizedMessage ?: "aesEncodeToByteArrayERROR")
null null
} }
@ -675,7 +670,7 @@ interface JsExtensions {
iv.encodeToByteArray() iv.encodeToByteArray()
) )
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
log(e.localizedMessage ?: "aesEncodeToBase64ByteArrayERROR") log(e.localizedMessage ?: "aesEncodeToBase64ByteArrayERROR")
null null
} }

@ -13,7 +13,7 @@ import io.legado.app.utils.*
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.io.File import java.io.File
/** /**
@ -62,7 +62,7 @@ object ReadBookConfig {
val json = configFile.readText() val json = configFile.readText()
configs = GSON.fromJsonArray(json) configs = GSON.fromJsonArray(json)
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
(configs ?: DefaultData.readConfigs).let { (configs ?: DefaultData.readConfigs).let {
@ -79,7 +79,7 @@ object ReadBookConfig {
val json = configFile.readText() val json = configFile.readText()
c = GSON.fromJsonObject(json) c = GSON.fromJsonObject(json)
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
shareConfig = c ?: configList.getOrNull(5) ?: Config() shareConfig = c ?: configList.getOrNull(5) ?: Config()
@ -580,9 +580,9 @@ object ReadBookConfig {
) )
} }
} catch (e: OutOfMemoryError) { } catch (e: OutOfMemoryError) {
Timber.e(e) e.printOnDebug()
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
return bgDrawable ?: ColorDrawable(appCtx.getCompatColor(R.color.background)) return bgDrawable ?: ColorDrawable(appCtx.getCompatColor(R.color.background))
} }

@ -7,7 +7,7 @@ import io.legado.app.constant.BookType
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.rule.* import io.legado.app.data.entities.rule.*
import io.legado.app.utils.* import io.legado.app.utils.*
import timber.log.Timber
import java.util.regex.Pattern import java.util.regex.Pattern
@Suppress("RegExpRedundantEscape") @Suppress("RegExpRedundantEscape")
@ -159,7 +159,7 @@ object SourceAnalyzer {
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
return source return source
} }

@ -14,7 +14,7 @@ import io.legado.app.lib.theme.ThemeStore
import io.legado.app.model.BookCover import io.legado.app.model.BookCover
import io.legado.app.utils.* import io.legado.app.utils.*
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.io.File import java.io.File
object ThemeConfig { object ThemeConfig {
@ -108,7 +108,7 @@ object ThemeConfig {
val json = configFile.readText() val json = configFile.readText()
return GSON.fromJsonArray(json) return GSON.fromJsonArray(json)
}.onFailure { }.onFailure {
Timber.e(it) it.printOnDebug()
} }
} }
return null return null

@ -1,7 +1,8 @@
package io.legado.app.help.coroutine package io.legado.app.help.coroutine
import io.legado.app.utils.printOnDebug
import kotlinx.coroutines.* import kotlinx.coroutines.*
import timber.log.Timber
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
/** /**
@ -144,7 +145,7 @@ class Coroutine<T>(
ensureActive() ensureActive()
success?.let { dispatchCallback(this, value, it) } success?.let { dispatchCallback(this, value, it) }
} catch (e: Throwable) { } catch (e: Throwable) {
Timber.e(e) e.printOnDebug()
if (e is CancellationException && e !is TimeoutCancellationException) { if (e is CancellationException && e !is TimeoutCancellationException) {
return@launch return@launch
} }

@ -1,8 +1,9 @@
package io.legado.app.help.http package io.legado.app.help.http
import android.annotation.SuppressLint import android.annotation.SuppressLint
import io.legado.app.utils.printOnDebug
import timber.log.Timber
import java.io.IOException import java.io.IOException
import java.io.InputStream import java.io.InputStream
import java.security.KeyManagementException import java.security.KeyManagementException
@ -127,9 +128,9 @@ object SSLHelper {
sslParams.trustManager = manager sslParams.trustManager = manager
return sslParams return sslParams
} catch (e: NoSuchAlgorithmException) { } catch (e: NoSuchAlgorithmException) {
Timber.e(e) e.printOnDebug()
} catch (e: KeyManagementException) { } catch (e: KeyManagementException) {
Timber.e(e) e.printOnDebug()
} }
return null return null
} }
@ -143,7 +144,7 @@ object SSLHelper {
kmf.init(clientKeyStore, password.toCharArray()) kmf.init(clientKeyStore, password.toCharArray())
return kmf.keyManagers return kmf.keyManagers
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
return null return null
} }
@ -162,7 +163,7 @@ object SSLHelper {
try { try {
certStream.close() certStream.close()
} catch (e: IOException) { } catch (e: IOException) {
Timber.e(e) e.printOnDebug()
} }
} }
//我们创建一个默认类型的TrustManagerFactory //我们创建一个默认类型的TrustManagerFactory

@ -2,6 +2,7 @@ package io.legado.app.help.http.cronet
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.utils.DebugLog
import okhttp3.Headers import okhttp3.Headers
import okhttp3.MediaType import okhttp3.MediaType
import okhttp3.Request import okhttp3.Request
@ -11,7 +12,7 @@ import org.chromium.net.ExperimentalCronetEngine
import org.chromium.net.UploadDataProviders import org.chromium.net.UploadDataProviders
import org.chromium.net.UrlRequest import org.chromium.net.UrlRequest
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.util.concurrent.ExecutorService import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors import java.util.concurrent.Executors
@ -35,11 +36,10 @@ val cronetEngine: ExperimentalCronetEngine? by lazy {
} }
try { try {
val engine = builder.build() val engine = builder.build()
Timber.d("Cronet Version:" + engine.versionString) DebugLog.d("Cronet Version:", engine.versionString)
return@lazy engine return@lazy engine
} catch (e: UnsatisfiedLinkError) { } catch (e: UnsatisfiedLinkError) {
AppLog.put("初始化cronetEngine出错", e) AppLog.put("初始化cronetEngine出错", e)
Timber.e(e, "初始化cronetEngine出错")
return@lazy null return@lazy null
} }
} }

@ -1,8 +1,9 @@
package io.legado.app.help.http.cronet package io.legado.app.help.http.cronet
import io.legado.app.help.http.CookieStore import io.legado.app.help.http.CookieStore
import io.legado.app.utils.printOnDebug
import okhttp3.* import okhttp3.*
import timber.log.Timber
class CronetInterceptor(private val cookieJar: CookieJar?) : Interceptor { class CronetInterceptor(private val cookieJar: CookieJar?) : Interceptor {
@ -33,7 +34,7 @@ class CronetInterceptor(private val cookieJar: CookieJar?) : Interceptor {
if (!e.message.toString().contains("ERR_CERT_", true) if (!e.message.toString().contains("ERR_CERT_", true)
&& !e.message.toString().contains("ERR_SSL_", true) && !e.message.toString().contains("ERR_SSL_", true)
) { ) {
Timber.e(e) e.printOnDebug()
} }
chain.proceed(original) chain.proceed(original)
} }

@ -8,11 +8,13 @@ import android.text.TextUtils
import io.legado.app.BuildConfig import io.legado.app.BuildConfig
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.utils.DebugLog
import io.legado.app.utils.printOnDebug
import org.chromium.net.CronetEngine import org.chromium.net.CronetEngine
import org.json.JSONObject import org.json.JSONObject
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.io.* import java.io.*
import java.math.BigInteger import java.math.BigInteger
import java.net.HttpURLConnection import java.net.HttpURLConnection
@ -36,16 +38,16 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
init { init {
soUrl = ("https://storage.googleapis.com/chromium-cronet/android/" soUrl = ("https://storage.googleapis.com/chromium-cronet/android/"
+ soVersion + "/Release/cronet/libs/" + soVersion + "/Release/cronet/libs/"
+ getCpuAbi(appCtx) + "/" + soName) + getCpuAbi(appCtx) + "/" + soName)
md5 = getMd5(appCtx) md5 = getMd5(appCtx)
val dir = appCtx.getDir("cronet", Context.MODE_PRIVATE) val dir = appCtx.getDir("cronet", Context.MODE_PRIVATE)
soFile = File(dir.toString() + "/" + getCpuAbi(appCtx), soName) soFile = File(dir.toString() + "/" + getCpuAbi(appCtx), soName)
downloadFile = File(appCtx.cacheDir.toString() + "/so_download", soName) downloadFile = File(appCtx.cacheDir.toString() + "/so_download", soName)
Timber.d("soName+:$soName") DebugLog.d(javaClass.simpleName, "soName+:$soName")
Timber.d("destSuccessFile:$soFile") DebugLog.d(javaClass.simpleName, "destSuccessFile:$soFile")
Timber.d("tempFile:$downloadFile") DebugLog.d(javaClass.simpleName, "tempFile:$downloadFile")
Timber.d("soUrl:$soUrl") DebugLog.d(javaClass.simpleName, "soUrl:$soUrl")
} }
/** /**
@ -77,11 +79,11 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
Coroutine.async { Coroutine.async {
//md5 = getUrlMd5(md5Url) //md5 = getUrlMd5(md5Url)
if (soFile.exists() && md5 == getFileMD5(soFile)) { if (soFile.exists() && md5 == getFileMD5(soFile)) {
Timber.d("So 库已存在") DebugLog.d(javaClass.simpleName, "So 库已存在")
} else { } else {
download(soUrl, md5, downloadFile, soFile) download(soUrl, md5, downloadFile, soFile)
} }
Timber.d(soName) DebugLog.d(javaClass.simpleName, soName)
} }
} }
@ -108,7 +110,7 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
@SuppressLint("UnsafeDynamicallyLoadedCode") @SuppressLint("UnsafeDynamicallyLoadedCode")
override fun loadLibrary(libName: String) { override fun loadLibrary(libName: String) {
Timber.d("libName:$libName") DebugLog.d(javaClass.simpleName, "libName:$libName")
val start = System.currentTimeMillis() val start = System.currentTimeMillis()
@Suppress("SameParameterValue") @Suppress("SameParameterValue")
try { try {
@ -120,13 +122,13 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
//以下逻辑为cronet加载,优先加载本地,否则从远程加载 //以下逻辑为cronet加载,优先加载本地,否则从远程加载
//首先调用系统行为进行加载 //首先调用系统行为进行加载
System.loadLibrary(libName) System.loadLibrary(libName)
Timber.d("load from system") DebugLog.d(javaClass.simpleName, "load from system")
} catch (e: Throwable) { } catch (e: Throwable) {
//如果找不到,则从远程下载 //如果找不到,则从远程下载
//删除历史文件 //删除历史文件
deleteHistoryFile(Objects.requireNonNull(soFile.parentFile), soFile) deleteHistoryFile(Objects.requireNonNull(soFile.parentFile), soFile)
//md5 = getUrlMd5(md5Url) //md5 = getUrlMd5(md5Url)
Timber.d("soMD5:$md5") DebugLog.d(javaClass.simpleName, "soMD5:$md5")
if (md5.length != 32 || soUrl.isEmpty()) { if (md5.length != 32 || soUrl.isEmpty()) {
//如果md5或下载的url为空,则调用系统行为进行加载 //如果md5或下载的url为空,则调用系统行为进行加载
System.loadLibrary(libName) System.loadLibrary(libName)
@ -145,7 +147,7 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
if (fileMD5 != null && fileMD5.equals(md5, ignoreCase = true)) { if (fileMD5 != null && fileMD5.equals(md5, ignoreCase = true)) {
//md5值一样,则加载 //md5值一样,则加载
System.load(soFile.absolutePath) System.load(soFile.absolutePath)
Timber.d("load from:$soFile") DebugLog.d(javaClass.simpleName, "load from:$soFile")
return return
} }
//md5不一样则删除 //md5不一样则删除
@ -156,7 +158,7 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
//使用系统加载方法 //使用系统加载方法
System.loadLibrary(libName) System.loadLibrary(libName)
} finally { } finally {
Timber.d("time:" + (System.currentTimeMillis() - start)) DebugLog.d(javaClass.simpleName, "time:" + (System.currentTimeMillis() - start))
} }
} }
@ -172,7 +174,7 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
abiField.isAccessible = true abiField.isAccessible = true
cpuAbi = abiField.get(appInfo) as String? cpuAbi = abiField.get(appInfo) as String?
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
if (TextUtils.isEmpty(cpuAbi)) { if (TextUtils.isEmpty(cpuAbi)) {
cpuAbi = Build.SUPPORTED_ABIS[0] cpuAbi = Build.SUPPORTED_ABIS[0]
@ -191,7 +193,7 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
for (f in files) { for (f in files) {
if (f.exists() && (currentFile == null || f.absolutePath != currentFile.absolutePath)) { if (f.exists() && (currentFile == null || f.absolutePath != currentFile.absolutePath)) {
val delete = f.delete() val delete = f.delete()
Timber.d("delete file: $f result: $delete") DebugLog.d(javaClass.simpleName, "delete file: $f result: $delete")
if (!delete) { if (!delete) {
f.deleteOnExit() f.deleteOnExit()
} }
@ -223,7 +225,7 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
} }
return true return true
} catch (e: Throwable) { } catch (e: Throwable) {
Timber.e(e) e.printOnDebug()
if (destFile.exists() && !destFile.delete()) { if (destFile.exists() && !destFile.delete()) {
destFile.deleteOnExit() destFile.deleteOnExit()
} }
@ -232,14 +234,14 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
try { try {
inputStream.close() inputStream.close()
} catch (e: IOException) { } catch (e: IOException) {
Timber.e(e) e.printOnDebug()
} }
} }
if (outputStream != null) { if (outputStream != null) {
try { try {
outputStream.close() outputStream.close()
} catch (e: IOException) { } catch (e: IOException) {
Timber.e(e) e.printOnDebug()
} }
} }
} }
@ -263,7 +265,7 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
download = true download = true
executor.execute { executor.execute {
val result = downloadFileIfNotExist(url, downloadTempFile) val result = downloadFileIfNotExist(url, downloadTempFile)
Timber.d("download result:$result") DebugLog.d(javaClass.simpleName, "download result:$result")
//文件md5再次校验 //文件md5再次校验
val fileMD5 = getFileMD5(downloadTempFile) val fileMD5 = getFileMD5(downloadTempFile)
if (md5 != null && !md5.equals(fileMD5, ignoreCase = true)) { if (md5 != null && !md5.equals(fileMD5, ignoreCase = true)) {
@ -274,7 +276,7 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
download = false download = false
return@execute return@execute
} }
Timber.d("download success, copy to $destSuccessFile") DebugLog.d(javaClass.simpleName, "download success, copy to $destSuccessFile")
//下载成功拷贝文件 //下载成功拷贝文件
copyFile(downloadTempFile, destSuccessFile) copyFile(downloadTempFile, destSuccessFile)
cacheInstall = false cacheInstall = false
@ -313,20 +315,20 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
} }
return true return true
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} finally { } finally {
if (fileInputStream != null) { if (fileInputStream != null) {
try { try {
fileInputStream.close() fileInputStream.close()
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
if (os != null) { if (os != null) {
try { try {
os.close() os.close()
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
} }
@ -348,15 +350,15 @@ object CronetLoader : CronetEngine.Builder.LibraryLoader() {
} }
return String.format("%032x", BigInteger(1, md5.digest())).lowercase() return String.format("%032x", BigInteger(1, md5.digest())).lowercase()
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} catch (e: OutOfMemoryError) { } catch (e: OutOfMemoryError) {
Timber.e(e) e.printOnDebug()
} finally { } finally {
if (fileInputStream != null) { if (fileInputStream != null) {
try { try {
fileInputStream.close() fileInputStream.close()
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
} }

@ -2,6 +2,7 @@ package io.legado.app.help.http.cronet
import android.os.ConditionVariable import android.os.ConditionVariable
import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.okHttpClient
import io.legado.app.utils.DebugLog
import okhttp3.* import okhttp3.*
import okhttp3.EventListener import okhttp3.EventListener
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
@ -10,7 +11,7 @@ import okio.Buffer
import org.chromium.net.CronetException import org.chromium.net.CronetException
import org.chromium.net.UrlRequest import org.chromium.net.UrlRequest
import org.chromium.net.UrlResponseInfo import org.chromium.net.UrlResponseInfo
import timber.log.Timber
import java.io.IOException import java.io.IOException
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.util.* import java.util.*
@ -86,7 +87,7 @@ class CronetRequestCallback @JvmOverloads internal constructor(
// } // }
// Log.e("Cronet", sb.toString()) // Log.e("Cronet", sb.toString())
//打印协议,用于调试 //打印协议,用于调试
Timber.i(info.negotiatedProtocol) DebugLog.i(javaClass.name, info.negotiatedProtocol)
if (eventListener != null) { if (eventListener != null) {
eventListener.responseHeadersEnd(mCall, this.mResponse) eventListener.responseHeadersEnd(mCall, this.mResponse)
eventListener.responseBodyStart(mCall) eventListener.responseBodyStart(mCall)
@ -107,7 +108,7 @@ class CronetRequestCallback @JvmOverloads internal constructor(
try { try {
mBuffer.write(byteBuffer) mBuffer.write(byteBuffer)
} catch (e: IOException) { } catch (e: IOException) {
Timber.i(e, "IOException during ByteBuffer read. Details: ") DebugLog.i(javaClass.name, "IOException during ByteBuffer read. Details: ", e)
throw e throw e
} }
byteBuffer.clear() byteBuffer.clear()
@ -135,7 +136,7 @@ class CronetRequestCallback @JvmOverloads internal constructor(
//UrlResponseInfo可能为null //UrlResponseInfo可能为null
override fun onFailed(request: UrlRequest, info: UrlResponseInfo?, error: CronetException) { override fun onFailed(request: UrlRequest, info: UrlResponseInfo?, error: CronetException) {
Timber.e(error.message.toString()) DebugLog.i(javaClass.name, error.message.toString())
val msg = error.localizedMessage val msg = error.localizedMessage
val e = IOException(msg?.substring(msg.indexOf("net::")), error) val e = IOException(msg?.substring(msg.indexOf("net::")), error)
mException = e mException = e
@ -192,7 +193,7 @@ class CronetRequestCallback @JvmOverloads internal constructor(
} }
add(key, value) add(key, value)
} catch (e: Exception) { } catch (e: Exception) {
Timber.w("Invalid HTTP header/value: $key$value") DebugLog.w(javaClass.name, "Invalid HTTP header/value: $key$value")
// Ignore that header // Ignore that header
} }
} }

@ -3,7 +3,7 @@ package io.legado.app.help.storage
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.utils.* import io.legado.app.utils.*
import timber.log.Timber
object OldBook { object OldBook {
@ -18,7 +18,7 @@ object OldBook {
if (book.bookUrl.isBlank()) continue if (book.bookUrl.isBlank()) continue
book.name = jsonItem.readString("$.bookInfoBean.name") ?: "" book.name = jsonItem.readString("$.bookInfoBean.name") ?: ""
if (book.bookUrl in existingBooks) { if (book.bookUrl in existingBooks) {
Timber.d("Found existing book: " + book.name) DebugLog.d(javaClass.name, "Found existing book: " + book.name)
continue continue
} }
book.origin = jsonItem.readString("$.tag") ?: "" book.origin = jsonItem.readString("$.tag") ?: ""

@ -1,11 +1,13 @@
package io.legado.app.help.storage package io.legado.app.help.storage
import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.ContextWrapper import android.content.ContextWrapper
import android.content.SharedPreferences import android.content.SharedPreferences
import io.legado.app.utils.printOnDebug
import timber.log.Timber
import java.io.File import java.io.File
object Preferences { object Preferences {
@ -17,6 +19,7 @@ object Preferences {
* @param fileName 文件名,不需要 '.xml' 后缀 * @param fileName 文件名,不需要 '.xml' 后缀
* @return * @return
*/ */
@SuppressLint("DiscouragedPrivateApi")
fun getSharedPreferences( fun getSharedPreferences(
context: Context, context: Context,
dir: String, dir: String,
@ -38,11 +41,11 @@ object Preferences {
// 返回修改路径以后的 SharedPreferences :%FILE_PATH%/%fileName%.xml // 返回修改路径以后的 SharedPreferences :%FILE_PATH%/%fileName%.xml
return context.getSharedPreferences(fileName, Activity.MODE_PRIVATE) return context.getSharedPreferences(fileName, Activity.MODE_PRIVATE)
} catch (e: NoSuchFieldException) { } catch (e: NoSuchFieldException) {
Timber.e(e) e.printOnDebug()
} catch (e: IllegalArgumentException) { } catch (e: IllegalArgumentException) {
Timber.e(e) e.printOnDebug()
} catch (e: IllegalAccessException) { } catch (e: IllegalAccessException) {
Timber.e(e) e.printOnDebug()
} }
return null return null
} }

@ -20,7 +20,7 @@ import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.io.File import java.io.File
@ -53,7 +53,7 @@ object Restore : BackupRestore() {
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
} }
@ -129,7 +129,7 @@ object Restore : BackupRestore() {
ThemeConfig.upConfig() ThemeConfig.upConfig()
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
if (!ignoreReadConfig) { if (!ignoreReadConfig) {
//恢复阅读界面配置 //恢复阅读界面配置
@ -142,7 +142,7 @@ object Restore : BackupRestore() {
ReadBookConfig.initConfigs() ReadBookConfig.initConfigs()
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
try { try {
val file = val file =
@ -153,7 +153,7 @@ object Restore : BackupRestore() {
ReadBookConfig.initShareConfig() ReadBookConfig.initShareConfig()
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
Preferences.getSharedPreferences(appCtx, path, "config")?.all?.let { map -> Preferences.getSharedPreferences(appCtx, path, "config")?.all?.let { map ->
@ -195,7 +195,7 @@ object Restore : BackupRestore() {
val json = file.readText() val json = file.readText()
return GSON.fromJsonArray(json) return GSON.fromJsonArray(json)
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
return null return null
} }

@ -3,13 +3,14 @@ package io.legado.app.lib.webdav
import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.newCallResponseBody
import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.okHttpClient
import io.legado.app.help.http.text import io.legado.app.help.http.text
import io.legado.app.utils.printOnDebug
import okhttp3.Credentials import okhttp3.Credentials
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import org.intellij.lang.annotations.Language import org.intellij.lang.annotations.Language
import org.jsoup.Jsoup import org.jsoup.Jsoup
import timber.log.Timber
import java.io.File import java.io.File
import java.io.InputStream import java.io.InputStream
import java.net.MalformedURLException import java.net.MalformedURLException
@ -100,7 +101,7 @@ class WebDav(urlStr: String) {
method("PROPFIND", requestBody) method("PROPFIND", requestBody)
}.text() }.text()
}.onFailure { e -> }.onFailure { e ->
Timber.e(e) e.printOnDebug()
}.getOrNull() }.getOrNull()
} }
return null return null
@ -132,7 +133,7 @@ class WebDav(urlStr: String) {
} }
list.add(webDavFile) list.add(webDavFile)
} catch (e: MalformedURLException) { } catch (e: MalformedURLException) {
Timber.e(e) e.printOnDebug()
} }
} }
} }

@ -16,7 +16,7 @@ import io.legado.app.utils.postEvent
import io.legado.app.utils.startService import io.legado.app.utils.startService
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import timber.log.Timber
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@ -180,7 +180,6 @@ object CacheBook {
"下载${book.name}-${chapterTitle}失败\n${error.localizedMessage}", "下载${book.name}-${chapterTitle}失败\n${error.localizedMessage}",
error error
) )
Timber.e(error)
} }
} }

@ -23,7 +23,7 @@ import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
@ -378,7 +378,7 @@ object ReadBook : CoroutineScope by MainScope() {
} }
} }
}.onError { }.onError {
Timber.e(it) AppLog.put("ChapterProvider ERROR", it)
appCtx.toastOnUi("ChapterProvider ERROR:\n${it.msg}") appCtx.toastOnUi("ChapterProvider ERROR:\n${it.msg}")
}.onSuccess { }.onSuccess {
success?.invoke() success?.invoke()

@ -3,7 +3,8 @@ package io.legado.app.model.analyzeRule
import androidx.annotation.Keep import androidx.annotation.Keep
import com.jayway.jsonpath.JsonPath import com.jayway.jsonpath.JsonPath
import com.jayway.jsonpath.ReadContext import com.jayway.jsonpath.ReadContext
import timber.log.Timber import io.legado.app.utils.printOnDebug
@Suppress("RegExpRedundantEscape") @Suppress("RegExpRedundantEscape")
@Keep @Keep
@ -48,7 +49,7 @@ class AnalyzeByJSonPath(json: Any) {
ob.toString() ob.toString()
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
return result return result
@ -85,7 +86,7 @@ class AnalyzeByJSonPath(json: Any) {
result.add(obj.toString()) result.add(obj.toString())
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} else { } else {
result.add(st) result.add(st)
@ -135,7 +136,7 @@ class AnalyzeByJSonPath(json: Any) {
try { try {
return it.read<ArrayList<Any>>(rules[0]) return it.read<ArrayList<Any>>(rules[0])
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
} else { } else {

@ -13,7 +13,7 @@ import io.legado.app.utils.*
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.jsoup.nodes.Entities import org.jsoup.nodes.Entities
import org.mozilla.javascript.NativeObject import org.mozilla.javascript.NativeObject
import timber.log.Timber
import java.net.URL import java.net.URL
import java.util.regex.Pattern import java.util.regex.Pattern
import javax.script.SimpleBindings import javax.script.SimpleBindings
@ -662,7 +662,7 @@ class AnalyzeRule(
analyzeUrl.getStrResponseAwait().body analyzeUrl.getStrResponseAwait().body
}.onFailure { }.onFailure {
log("ajax(${urlStr}) error\n${it.stackTraceToString()}") log("ajax(${urlStr}) error\n${it.stackTraceToString()}")
Timber.e(it) it.printOnDebug()
}.getOrElse { }.getOrElse {
it.msg it.msg
} }

@ -5,10 +5,7 @@ import android.graphics.BitmapFactory
import android.text.TextUtils import android.text.TextUtils
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.utils.FileUtils import io.legado.app.utils.*
import io.legado.app.utils.HtmlFormatter
import io.legado.app.utils.MD5Utils
import io.legado.app.utils.externalFiles
import me.ag2s.epublib.domain.EpubBook import me.ag2s.epublib.domain.EpubBook
import me.ag2s.epublib.domain.Resource import me.ag2s.epublib.domain.Resource
import me.ag2s.epublib.domain.TOCReference import me.ag2s.epublib.domain.TOCReference
@ -17,7 +14,7 @@ import org.jsoup.Jsoup
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import org.jsoup.select.Elements import org.jsoup.select.Elements
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.IOException import java.io.IOException
@ -97,7 +94,7 @@ class EpubFile(var book: Book) {
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
@ -108,7 +105,7 @@ class EpubFile(var book: Book) {
//通过懒加载读取epub //通过懒加载读取epub
return EpubReader().readEpub(bis, "utf-8") return EpubReader().readEpub(bis, "utf-8")
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
return null return null
} }

@ -12,7 +12,7 @@ import io.legado.app.help.BookHelp
import io.legado.app.model.TocEmptyException import io.legado.app.model.TocEmptyException
import io.legado.app.utils.* import io.legado.app.utils.*
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileNotFoundException import java.io.FileNotFoundException
@ -69,7 +69,7 @@ object LocalBook {
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
e.localizedMessage e.localizedMessage
} }
} }

@ -2,13 +2,11 @@ package io.legado.app.model.localBook
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.utils.FileUtils import io.legado.app.utils.*
import io.legado.app.utils.MD5Utils
import io.legado.app.utils.externalFiles
import me.ag2s.umdlib.domain.UmdBook import me.ag2s.umdlib.domain.UmdBook
import me.ag2s.umdlib.umd.UmdReader import me.ag2s.umdlib.umd.UmdReader
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.io.File import java.io.File
import java.io.InputStream import java.io.InputStream
@ -77,7 +75,7 @@ class UmdFile(var book: Book) {
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
@ -111,7 +109,7 @@ class UmdFile(var book: Book) {
chapter.index = index chapter.index = index
chapter.bookUrl = book.bookUrl chapter.bookUrl = book.bookUrl
chapter.url = index.toString() chapter.url = index.toString()
Timber.d(chapter.url) DebugLog.d(javaClass.name, chapter.url)
chapterList.add(chapter) chapterList.add(chapter)
} }
book.latestChapterTitle = chapterList.lastOrNull()?.title book.latestChapterTitle = chapterList.lastOrNull()?.title

@ -7,13 +7,14 @@ import io.legado.app.help.BookHelp
import io.legado.app.model.Debug import io.legado.app.model.Debug
import io.legado.app.model.NoStackTraceException import io.legado.app.model.NoStackTraceException
import io.legado.app.model.analyzeRule.AnalyzeRule import io.legado.app.model.analyzeRule.AnalyzeRule
import io.legado.app.utils.DebugLog
import io.legado.app.utils.HtmlFormatter import io.legado.app.utils.HtmlFormatter
import io.legado.app.utils.NetworkUtils import io.legado.app.utils.NetworkUtils
import io.legado.app.utils.StringUtils.wordCountFormat import io.legado.app.utils.StringUtils.wordCountFormat
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ensureActive import kotlinx.coroutines.ensureActive
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
/** /**
* 获取详情 * 获取详情
@ -87,7 +88,7 @@ object BookInfo {
} ?: Debug.log(bookSource.bookSourceUrl, "") } ?: Debug.log(bookSource.bookSourceUrl, "")
} catch (e: Exception) { } catch (e: Exception) {
Debug.log(bookSource.bookSourceUrl, "${e.localizedMessage}") Debug.log(bookSource.bookSourceUrl, "${e.localizedMessage}")
Timber.e(e, "获取分类出错") DebugLog.e("获取分类出错", e)
} }
scope.ensureActive() scope.ensureActive()
Debug.log(bookSource.bookSourceUrl, "┌获取字数") Debug.log(bookSource.bookSourceUrl, "┌获取字数")
@ -98,7 +99,7 @@ object BookInfo {
} }
} catch (e: Exception) { } catch (e: Exception) {
Debug.log(bookSource.bookSourceUrl, "${e.localizedMessage}") Debug.log(bookSource.bookSourceUrl, "${e.localizedMessage}")
Timber.e(e, "获取字数出错") DebugLog.e("获取字数出错", e)
} }
scope.ensureActive() scope.ensureActive()
Debug.log(bookSource.bookSourceUrl, "┌获取最新章节") Debug.log(bookSource.bookSourceUrl, "┌获取最新章节")
@ -109,7 +110,7 @@ object BookInfo {
} }
} catch (e: Exception) { } catch (e: Exception) {
Debug.log(bookSource.bookSourceUrl, "${e.localizedMessage}") Debug.log(bookSource.bookSourceUrl, "${e.localizedMessage}")
Timber.e(e, "获取最新章节出错") DebugLog.e("获取最新章节出错", e)
} }
scope.ensureActive() scope.ensureActive()
Debug.log(bookSource.bookSourceUrl, "┌获取简介") Debug.log(bookSource.bookSourceUrl, "┌获取简介")
@ -120,7 +121,7 @@ object BookInfo {
} }
} catch (e: Exception) { } catch (e: Exception) {
Debug.log(bookSource.bookSourceUrl, "${e.localizedMessage}") Debug.log(bookSource.bookSourceUrl, "${e.localizedMessage}")
Timber.e(e, "获取简介出错") DebugLog.e("获取简介出错", e)
} }
scope.ensureActive() scope.ensureActive()
Debug.log(bookSource.bookSourceUrl, "┌获取封面链接") Debug.log(bookSource.bookSourceUrl, "┌获取封面链接")
@ -131,7 +132,7 @@ object BookInfo {
} }
} catch (e: Exception) { } catch (e: Exception) {
Debug.log(bookSource.bookSourceUrl, "${e.localizedMessage}") Debug.log(bookSource.bookSourceUrl, "${e.localizedMessage}")
Timber.e(e, "获取封面出错") DebugLog.e("获取封面出错", e)
} }
scope.ensureActive() scope.ensureActive()
Debug.log(bookSource.bookSourceUrl, "┌获取目录链接") Debug.log(bookSource.bookSourceUrl, "┌获取目录链接")

@ -33,7 +33,7 @@ import io.legado.app.utils.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
import splitties.systemservices.audioManager import splitties.systemservices.audioManager
import timber.log.Timber
class AudioPlayService : BaseService(), class AudioPlayService : BaseService(),
@ -138,7 +138,7 @@ class AudioPlayService : BaseService(),
exoPlayer.playWhenReady = true exoPlayer.playWhenReady = true
exoPlayer.prepare() exoPlayer.prepare()
}.onFailure { }.onFailure {
Timber.e(it) it.printOnDebug()
toastOnUi("$url ${it.localizedMessage}") toastOnUi("$url ${it.localizedMessage}")
stopSelf() stopSelf()
} }
@ -159,7 +159,7 @@ class AudioPlayService : BaseService(),
postEvent(EventBus.AUDIO_STATE, Status.PAUSE) postEvent(EventBus.AUDIO_STATE, Status.PAUSE)
upNotification() upNotification()
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
@ -178,7 +178,7 @@ class AudioPlayService : BaseService(),
postEvent(EventBus.AUDIO_STATE, Status.PLAY) postEvent(EventBus.AUDIO_STATE, Status.PLAY)
upNotification() upNotification()
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
stopSelf() stopSelf()
} }
} }
@ -250,7 +250,6 @@ class AudioPlayService : BaseService(),
val errorMsg = "音频播放出错\n${error.errorCodeName} ${error.errorCode}" val errorMsg = "音频播放出错\n${error.errorCodeName} ${error.errorCode}"
AppLog.put(errorMsg, error) AppLog.put(errorMsg, error)
toastOnUi(errorMsg) toastOnUi(errorMsg)
Timber.e(error)
} }
private fun setTimer(minute: Int) { private fun setTimer(minute: Int) {

@ -19,7 +19,7 @@ import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import okhttp3.Response import okhttp3.Response
import org.mozilla.javascript.WrappedException import org.mozilla.javascript.WrappedException
import timber.log.Timber
import java.io.File import java.io.File
import java.io.FileDescriptor import java.io.FileDescriptor
import java.io.FileInputStream import java.io.FileInputStream
@ -177,7 +177,7 @@ class HttpReadAloudService : BaseReadAloudService(),
is ScriptException, is WrappedException -> { is ScriptException, is WrappedException -> {
AppLog.put("js错误\n${it.localizedMessage}", it) AppLog.put("js错误\n${it.localizedMessage}", it)
toastOnUi("js错误\n${it.localizedMessage}") toastOnUi("js错误\n${it.localizedMessage}")
Timber.e(it) it.printOnDebug()
cancel() cancel()
pauseReadAloud(true) pauseReadAloud(true)
} }
@ -198,7 +198,7 @@ class HttpReadAloudService : BaseReadAloudService(),
downloadErrorNo++ downloadErrorNo++
val msg = "tts下载错误\n${it.localizedMessage}" val msg = "tts下载错误\n${it.localizedMessage}"
AppLog.put(msg, it) AppLog.put(msg, it)
Timber.e(it) it.printOnDebug()
if (downloadErrorNo > 5) { if (downloadErrorNo > 5) {
pauseReadAloud(true) pauseReadAloud(true)
} else { } else {
@ -222,7 +222,7 @@ class HttpReadAloudService : BaseReadAloudService(),
playingIndex = nowSpeak playingIndex = nowSpeak
postEvent(EventBus.TTS_PROGRESS, readAloudNumber + 1) postEvent(EventBus.TTS_PROGRESS, readAloudNumber + 1)
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
} }

@ -13,7 +13,7 @@ import io.legado.app.constant.PreferKey
import io.legado.app.utils.* import io.legado.app.utils.*
import io.legado.app.web.HttpServer import io.legado.app.web.HttpServer
import io.legado.app.web.WebSocketServer import io.legado.app.web.WebSocketServer
import timber.log.Timber
import java.io.IOException import java.io.IOException
class WebService : BaseService() { class WebService : BaseService() {
@ -88,7 +88,7 @@ class WebService : BaseService() {
upNotification() upNotification()
} catch (e: IOException) { } catch (e: IOException) {
toastOnUi(e.localizedMessage ?: "") toastOnUi(e.localizedMessage ?: "")
Timber.e(e) e.printOnDebug()
stopSelf() stopSelf()
} }
} else { } else {

@ -6,7 +6,7 @@ import android.service.quicksettings.Tile
import android.service.quicksettings.TileService import android.service.quicksettings.TileService
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import io.legado.app.constant.IntentAction import io.legado.app.constant.IntentAction
import timber.log.Timber import io.legado.app.utils.printOnDebug
/** /**
@ -28,7 +28,7 @@ class WebTileService : TileService() {
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
return super.onStartCommand(intent, flags, startId) return super.onStartCommand(intent, flags, startId)
} }

@ -7,11 +7,8 @@ import android.view.View
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import io.legado.app.R import io.legado.app.R
import io.legado.app.utils.ACache import io.legado.app.utils.*
import io.legado.app.utils.longToastOnUi
import io.legado.app.utils.openUrl
import io.legado.app.utils.sendToClip
import timber.log.Timber
class DonateFragment : PreferenceFragmentCompat() { class DonateFragment : PreferenceFragmentCompat() {
@ -50,7 +47,7 @@ class DonateFragment : PreferenceFragmentCompat() {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent) context.startActivity(intent)
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} finally { } finally {
ACache.get(requireContext(), cacheDir = false) ACache.get(requireContext(), cacheDir = false)
.put("proTime", System.currentTimeMillis()) .put("proTime", System.currentTimeMillis())

@ -6,6 +6,7 @@ import androidx.activity.viewModels
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.AppLog
import io.legado.app.databinding.ActivityTranslucenceBinding import io.legado.app.databinding.ActivityTranslucenceBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
@ -18,7 +19,7 @@ import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import timber.log.Timber
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
@ -145,7 +146,7 @@ class FileAssociationActivity :
mode = HandleFileContract.DIR_SYS mode = HandleFileContract.DIR_SYS
} }
else -> { else -> {
Timber.e(it, "导入书籍失败") AppLog.put("导入书籍失败", it)
toastOnUi(it.localizedMessage) toastOnUi(it.localizedMessage)
finish() finish()
} }

@ -7,8 +7,9 @@ import androidx.lifecycle.MutableLiveData
import io.legado.app.model.NoStackTraceException import io.legado.app.model.NoStackTraceException
import io.legado.app.model.localBook.LocalBook import io.legado.app.model.localBook.LocalBook
import io.legado.app.utils.isJson import io.legado.app.utils.isJson
import io.legado.app.utils.printOnDebug
import io.legado.app.utils.readText import io.legado.app.utils.readText
import timber.log.Timber
import java.io.File import java.io.File
class FileAssociationViewModel(application: Application) : BaseAssociationViewModel(application) { class FileAssociationViewModel(application: Application) : BaseAssociationViewModel(application) {
@ -54,7 +55,7 @@ class FileAssociationViewModel(application: Application) : BaseAssociationViewMo
onLineImportLive.postValue(uri) onLineImportLive.postValue(uri)
} }
}.onError { }.onError {
Timber.e(it) it.printOnDebug()
errorLiveData.postValue(it.localizedMessage) errorLiveData.postValue(it.localizedMessage)
} }
} }

@ -16,7 +16,7 @@ import io.legado.app.help.http.okHttpClient
import io.legado.app.help.http.text import io.legado.app.help.http.text
import io.legado.app.model.NoStackTraceException import io.legado.app.model.NoStackTraceException
import io.legado.app.utils.* import io.legado.app.utils.*
import timber.log.Timber
class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) { class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
var isAddGroup = false var isAddGroup = false
@ -113,7 +113,7 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
else -> throw NoStackTraceException(context.getString(R.string.wrong_format)) else -> throw NoStackTraceException(context.getString(R.string.wrong_format))
} }
}.onError { }.onError {
Timber.e(it) it.printOnDebug()
errorLiveData.postValue(it.localizedMessage ?: "") errorLiveData.postValue(it.localizedMessage ?: "")
}.onSuccess { }.onSuccess {
comparisonSource() comparisonSource()

@ -28,7 +28,7 @@ import me.ag2s.epublib.domain.*
import me.ag2s.epublib.epub.EpubWriter import me.ag2s.epublib.epub.EpubWriter
import me.ag2s.epublib.util.ResourceUtil import me.ag2s.epublib.util.ResourceUtil
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
@ -71,7 +71,7 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
exportProgress.remove(book.bookUrl) exportProgress.remove(book.bookUrl)
exportMsg[book.bookUrl] = it.localizedMessage ?: "ERROR" exportMsg[book.bookUrl] = it.localizedMessage ?: "ERROR"
upAdapterLiveData.postValue(book.bookUrl) upAdapterLiveData.postValue(book.bookUrl)
Timber.e(it) it.printOnDebug()
}.onSuccess { }.onSuccess {
exportProgress.remove(book.bookUrl) exportProgress.remove(book.bookUrl)
exportMsg[book.bookUrl] = context.getString(R.string.export_success) exportMsg[book.bookUrl] = context.getString(R.string.export_success)
@ -206,7 +206,7 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
exportProgress.remove(book.bookUrl) exportProgress.remove(book.bookUrl)
exportMsg[book.bookUrl] = it.localizedMessage ?: "ERROR" exportMsg[book.bookUrl] = it.localizedMessage ?: "ERROR"
upAdapterLiveData.postValue(book.bookUrl) upAdapterLiveData.postValue(book.bookUrl)
Timber.e(it) it.printOnDebug()
}.onSuccess { }.onSuccess {
exportProgress.remove(book.bookUrl) exportProgress.remove(book.bookUrl)
exportMsg[book.bookUrl] = context.getString(R.string.export_success) exportMsg[book.bookUrl] = context.getString(R.string.export_success)

@ -17,6 +17,7 @@ import io.legado.app.help.coroutine.CompositeCoroutine
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.getPrefBoolean
import io.legado.app.utils.getPrefString import io.legado.app.utils.getPrefString
import io.legado.app.utils.printOnDebug
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.ExecutorCoroutineDispatcher import kotlinx.coroutines.ExecutorCoroutineDispatcher
import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.asCoroutineDispatcher
@ -25,7 +26,7 @@ import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.util.* import java.util.*
import java.util.concurrent.Executors import java.util.concurrent.Executors
import kotlin.math.min import kotlin.math.min
@ -194,7 +195,7 @@ class ChangeBookSourceViewModel(application: Application) : BaseViewModel(applic
searchCallback?.searchSuccess(searchBook) searchCallback?.searchSuccess(searchBook)
} }
}.onError(IO) { }.onError(IO) {
Timber.e(it) it.printOnDebug()
} }
} }
@ -205,7 +206,7 @@ class ChangeBookSourceViewModel(application: Application) : BaseViewModel(applic
val searchBook: SearchBook = book.toSearchBook() val searchBook: SearchBook = book.toSearchBook()
searchCallback?.searchSuccess(searchBook) searchCallback?.searchSuccess(searchBook)
}.onError(IO) { }.onError(IO) {
Timber.e(it) it.printOnDebug()
} }
} }

@ -19,6 +19,7 @@ import io.legado.app.model.NoStackTraceException
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.getPrefBoolean
import io.legado.app.utils.getPrefString import io.legado.app.utils.getPrefString
import io.legado.app.utils.printOnDebug
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.ExecutorCoroutineDispatcher import kotlinx.coroutines.ExecutorCoroutineDispatcher
import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.asCoroutineDispatcher
@ -27,7 +28,7 @@ import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.util.* import java.util.*
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.Executors import java.util.concurrent.Executors
@ -204,7 +205,7 @@ class ChangeChapterSourceViewModel(application: Application) : BaseViewModel(app
searchCallback?.searchSuccess(searchBook) searchCallback?.searchSuccess(searchBook)
} }
}.onError(IO) { }.onError(IO) {
Timber.e(it) it.printOnDebug()
} }
} }
@ -216,7 +217,7 @@ class ChangeChapterSourceViewModel(application: Application) : BaseViewModel(app
val searchBook: SearchBook = book.toSearchBook() val searchBook: SearchBook = book.toSearchBook()
searchCallback?.searchSuccess(searchBook) searchCallback?.searchSuccess(searchBook)
}.onError(IO) { }.onError(IO) {
Timber.e(it) it.printOnDebug()
} }
} }

@ -10,9 +10,10 @@ import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.SearchBook import io.legado.app.data.entities.SearchBook
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.utils.msg import io.legado.app.utils.msg
import io.legado.app.utils.printOnDebug
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import timber.log.Timber
class ExploreShowViewModel(application: Application) : BaseViewModel(application) { class ExploreShowViewModel(application: Application) : BaseViewModel(application) {
@ -44,7 +45,7 @@ class ExploreShowViewModel(application: Application) : BaseViewModel(application
appDb.searchBookDao.insert(*searchBooks.toTypedArray()) appDb.searchBookDao.insert(*searchBooks.toTypedArray())
page++ page++
}.onError { }.onError {
Timber.e(it) it.printOnDebug()
errorLiveData.postValue(it.msg) errorLiveData.postValue(it.msg)
} }
} }

@ -24,7 +24,7 @@ import io.legado.app.databinding.ItemTextBinding
import io.legado.app.databinding.PopupActionMenuBinding import io.legado.app.databinding.PopupActionMenuBinding
import io.legado.app.service.BaseReadAloudService import io.legado.app.service.BaseReadAloudService
import io.legado.app.utils.* import io.legado.app.utils.*
import timber.log.Timber
import java.util.* import java.util.*
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
@ -210,7 +210,7 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac
} }
context.startActivity(intent) context.startActivity(intent)
}.onFailure { }.onFailure {
Timber.e(it) it.printOnDebug()
context.toastOnUi(it.localizedMessage ?: "ERROR") context.toastOnUi(it.localizedMessage ?: "ERROR")
} }
} }

@ -33,7 +33,7 @@ import io.legado.app.ui.document.HandleFileContract
import io.legado.app.ui.widget.seekbar.SeekBarChangeListener import io.legado.app.ui.widget.seekbar.SeekBarChangeListener
import io.legado.app.utils.* import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import timber.log.Timber
import java.io.File import java.io.File
class BgTextConfigDialog : BaseDialogFragment(R.layout.dialog_read_bg_text) { class BgTextConfigDialog : BaseDialogFragment(R.layout.dialog_read_bg_text) {
@ -293,7 +293,7 @@ class BgTextConfigDialog : BaseDialogFragment(R.layout.dialog_read_bg_text) {
}.onSuccess { }.onSuccess {
toastOnUi("导出成功, 文件名为 $exportFileName") toastOnUi("导出成功, 文件名为 $exportFileName")
}.onError { }.onError {
Timber.e(it) it.printOnDebug()
longToast("导出失败:${it.localizedMessage}") longToast("导出失败:${it.localizedMessage}")
} }
} }
@ -330,7 +330,7 @@ class BgTextConfigDialog : BaseDialogFragment(R.layout.dialog_read_bg_text) {
@Suppress("BlockingMethodInNonBlockingContext") @Suppress("BlockingMethodInNonBlockingContext")
importConfig(uri.readBytes(requireContext())) importConfig(uri.readBytes(requireContext()))
}.onError { }.onError {
Timber.e(it) it.printOnDebug()
longToast("导入失败:${it.localizedMessage}") longToast("导入失败:${it.localizedMessage}")
} }
} }
@ -344,7 +344,7 @@ class BgTextConfigDialog : BaseDialogFragment(R.layout.dialog_read_bg_text) {
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
toastOnUi("导入成功") toastOnUi("导入成功")
}.onError { }.onError {
Timber.e(it) it.printOnDebug()
longToast("导入失败:${it.localizedMessage}") longToast("导入失败:${it.localizedMessage}")
} }
} }

@ -10,7 +10,7 @@ import io.legado.app.help.http.okHttpClient
import io.legado.app.model.NoStackTraceException import io.legado.app.model.NoStackTraceException
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import timber.log.Timber
class BookSourceEditViewModel(application: Application) : BaseViewModel(application) { class BookSourceEditViewModel(application: Application) : BaseViewModel(application) {
@ -48,7 +48,7 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat
success?.invoke() success?.invoke()
}.onError { }.onError {
context.toastOnUi(it.localizedMessage) context.toastOnUi(it.localizedMessage)
Timber.e(it) it.printOnDebug()
} }
} }
@ -62,7 +62,7 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat
} }
}.onError { }.onError {
context.toastOnUi(it.localizedMessage ?: "Error") context.toastOnUi(it.localizedMessage ?: "Error")
Timber.e(it) it.printOnDebug()
} }
} }

@ -14,7 +14,7 @@ import io.legado.app.help.http.okHttpClient
import io.legado.app.model.NoStackTraceException import io.legado.app.model.NoStackTraceException
import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.utils.* import io.legado.app.utils.*
import timber.log.Timber
import java.io.File import java.io.File
import java.util.* import java.util.*
@ -41,7 +41,7 @@ class WebViewModel(application: Application) : BaseViewModel(application) {
success.invoke() success.invoke()
}.onError { }.onError {
context.toastOnUi("error\n${it.localizedMessage}") context.toastOnUi("error\n${it.localizedMessage}")
Timber.e(it) it.printOnDebug()
} }
} }

@ -7,12 +7,8 @@ import androidx.lifecycle.MutableLiveData
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
import io.legado.app.help.DirectLinkUpload import io.legado.app.help.DirectLinkUpload
import io.legado.app.utils.FileUtils import io.legado.app.utils.*
import io.legado.app.utils.GSON
import io.legado.app.utils.isContentScheme
import io.legado.app.utils.writeBytes
import timber.log.Timber
import java.io.File import java.io.File
class HandleFileViewModel(application: Application) : BaseViewModel(application) { class HandleFileViewModel(application: Application) : BaseViewModel(application) {
@ -31,7 +27,7 @@ class HandleFileViewModel(application: Application) : BaseViewModel(application)
success.invoke(it) success.invoke(it)
}.onError { }.onError {
AppLog.put("上传文件失败\n${it.localizedMessage}", it) AppLog.put("上传文件失败\n${it.localizedMessage}", it)
Timber.e(it) it.printOnDebug()
errorLiveData.postValue(it.localizedMessage) errorLiveData.postValue(it.localizedMessage)
} }
} }
@ -57,7 +53,7 @@ class HandleFileViewModel(application: Application) : BaseViewModel(application)
Uri.fromFile(newFile) Uri.fromFile(newFile)
} }
}.onError { }.onError {
Timber.e(it) it.printOnDebug()
errorLiveData.postValue(it.localizedMessage) errorLiveData.postValue(it.localizedMessage)
}.onSuccess { }.onSuccess {
success.invoke(it) success.invoke(it)

@ -8,7 +8,7 @@ import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.RecyclerAdapter import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.databinding.ItemFontBinding import io.legado.app.databinding.ItemFontBinding
import io.legado.app.utils.* import io.legado.app.utils.*
import timber.log.Timber
import java.io.File import java.io.File
import java.net.URLDecoder import java.net.URLDecoder
@ -45,7 +45,7 @@ class FontAdapter(context: Context, curFilePath: String, val callBack: CallBack)
} }
tvFont.typeface = typeface tvFont.typeface = typeface
}.onFailure { }.onFailure {
Timber.e(it) it.printOnDebug()
context.toastOnUi("Read ${item.name} Error: ${it.localizedMessage}") context.toastOnUi("Read ${item.name} Error: ${it.localizedMessage}")
} }
tvFont.text = item.name tvFont.text = item.name

@ -24,7 +24,7 @@ import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import splitties.views.onClick import splitties.views.onClick
import timber.log.Timber
class SourceLoginDialog : BaseDialogFragment(R.layout.dialog_login) { class SourceLoginDialog : BaseDialogFragment(R.layout.dialog_login) {
@ -124,7 +124,7 @@ class SourceLoginDialog : BaseDialogFragment(R.layout.dialog_login) {
} catch (e: Exception) { } catch (e: Exception) {
AppLog.put("登录出错\n${e.localizedMessage}", e) AppLog.put("登录出错\n${e.localizedMessage}", e)
context?.toastOnUi("登录出错\n${e.localizedMessage}") context?.toastOnUi("登录出错\n${e.localizedMessage}")
Timber.e(e) e.printOnDebug()
} }
} }
} }

@ -18,7 +18,7 @@ import io.legado.app.model.webBook.WebBook
import io.legado.app.service.CacheBookService import io.legado.app.service.CacheBookService
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import kotlinx.coroutines.* import kotlinx.coroutines.*
import timber.log.Timber
import java.util.concurrent.CopyOnWriteArraySet import java.util.concurrent.CopyOnWriteArraySet
import java.util.concurrent.Executors import java.util.concurrent.Executors
import kotlin.math.min import kotlin.math.min
@ -126,7 +126,6 @@ class MainViewModel(application: Application) : BaseViewModel(application) {
addDownload(source, book) addDownload(source, book)
}.onError(upTocPool) { }.onError(upTocPool) {
AppLog.put("${book.name} 更新目录失败\n${it.localizedMessage}", it) AppLog.put("${book.name} 更新目录失败\n${it.localizedMessage}", it)
Timber.e(it, "${book.name} 更新目录失败")
}.onCancel(upTocPool) { }.onCancel(upTocPool) {
upTocCancel(book.bookUrl) upTocCancel(book.bookUrl)
}.onFinally(upTocPool) { }.onFinally(upTocPool) {

@ -5,15 +5,17 @@ import android.os.Bundle
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.constant.AppLog
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.RssArticle import io.legado.app.data.entities.RssArticle
import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.RssSource
import io.legado.app.model.rss.Rss import io.legado.app.model.rss.Rss
import io.legado.app.utils.printOnDebug
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import timber.log.Timber
class RssArticlesViewModel(application: Application) : BaseViewModel(application) { class RssArticlesViewModel(application: Application) : BaseViewModel(application) {
val loadFinally = MutableLiveData<Boolean>() val loadFinally = MutableLiveData<Boolean>()
@ -54,7 +56,7 @@ class RssArticlesViewModel(application: Application) : BaseViewModel(application
} }
}.onError { }.onError {
loadFinally.postValue(false) loadFinally.postValue(false)
Timber.e(it) AppLog.put("rss获取内容失败", it)
context.toastOnUi(it.localizedMessage) context.toastOnUi(it.localizedMessage)
} }
} }
@ -70,7 +72,7 @@ class RssArticlesViewModel(application: Application) : BaseViewModel(application
loadMoreSuccess(it.first) loadMoreSuccess(it.first)
} }
.onError { .onError {
Timber.e(it) it.printOnDebug()
loadFinally.postValue(false) loadFinally.postValue(false)
} }
} else { } else {

@ -7,10 +7,11 @@ import io.legado.app.data.appDb
import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.RssSource
import io.legado.app.utils.getClipText import io.legado.app.utils.getClipText
import io.legado.app.utils.msg import io.legado.app.utils.msg
import io.legado.app.utils.printOnDebug
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import timber.log.Timber
class RssSourceEditViewModel(application: Application) : BaseViewModel(application) { class RssSourceEditViewModel(application: Application) : BaseViewModel(application) {
@ -42,7 +43,7 @@ class RssSourceEditViewModel(application: Application) : BaseViewModel(applicati
success() success()
}.onError { }.onError {
context.toastOnUi(it.localizedMessage) context.toastOnUi(it.localizedMessage)
Timber.e(it) it.printOnDebug()
} }
} }

@ -15,7 +15,7 @@ import android.view.Gravity
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import io.legado.app.R import io.legado.app.R
import timber.log.Timber import io.legado.app.utils.printOnDebug
class SearchView @JvmOverloads constructor( class SearchView @JvmOverloads constructor(
@ -44,7 +44,7 @@ class SearchView @JvmOverloads constructor(
textView!!.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14f) textView!!.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14f)
textView!!.gravity = Gravity.CENTER_VERTICAL textView!!.gravity = Gravity.CENTER_VERTICAL
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }

@ -25,7 +25,8 @@ import android.graphics.Rect
import android.media.MediaPlayer import android.media.MediaPlayer
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import timber.log.Timber import io.legado.app.utils.DebugLog
import java.util.* import java.util.*
@ -125,11 +126,11 @@ class ExplosionView @JvmOverloads constructor(context: Context, attrs: Attribute
} }
override fun onAnimationCancel(animator: Animator) { override fun onAnimationCancel(animator: Animator) {
Timber.i("CANCEL") DebugLog.i(javaClass.name, "CANCEL")
} }
override fun onAnimationRepeat(animator: Animator) { override fun onAnimationRepeat(animator: Animator) {
Timber.i("REPEAT") DebugLog.i(javaClass.name, "REPEAT")
} }
}) })

@ -22,7 +22,8 @@ import android.graphics.Canvas
import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.BitmapDrawable
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import timber.log.Timber import io.legado.app.utils.printOnDebug
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -67,7 +68,7 @@ object Utils {
try { try {
return Bitmap.createBitmap(width, height, config) return Bitmap.createBitmap(width, height, config)
} catch (e: OutOfMemoryError) { } catch (e: OutOfMemoryError) {
Timber.e(e) e.printOnDebug()
if (retryCount > 0) { if (retryCount > 0) {
System.gc() System.gc()
return createBitmapSafely(width, height, config, retryCount - 1) return createBitmapSafely(width, height, config, retryCount - 1)

@ -20,9 +20,10 @@ import androidx.annotation.RequiresApi
import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.AppCompatImageView
import io.legado.app.R import io.legado.app.R
import io.legado.app.utils.getCompatColor import io.legado.app.utils.getCompatColor
import io.legado.app.utils.printOnDebug
import io.legado.app.utils.sp import io.legado.app.utils.sp
import timber.log.Timber
import kotlin.math.min import kotlin.math.min
import kotlin.math.pow import kotlin.math.pow
@ -151,10 +152,6 @@ class CircleImageView @JvmOverloads constructor(
mReady = true mReady = true
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
outlineProvider = OutlineProvider()
}
if (mSetupPending) { if (mSetupPending) {
setup() setup()
mSetupPending = false mSetupPending = false
@ -318,7 +315,7 @@ class CircleImageView @JvmOverloads constructor(
drawable.draw(canvas) drawable.draw(canvas)
bitmap bitmap
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
null null
} }

@ -7,7 +7,8 @@ import android.graphics.drawable.Drawable
import android.view.View import android.view.View
import android.widget.LinearLayout import android.widget.LinearLayout
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import timber.log.Timber import io.legado.app.utils.DebugLog
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -38,7 +39,10 @@ class DividerNoLast(context: Context, orientation: Int) :
val a = context.obtainStyledAttributes(attrs) val a = context.obtainStyledAttributes(attrs)
mDivider = a.getDrawable(0) mDivider = a.getDrawable(0)
if (mDivider == null) { if (mDivider == null) {
Timber.w("@android:attr/listDivider was not set in the theme used for this DividerItemDecoration. Please set that attribute all call setDrawable()") DebugLog.w(
javaClass.name,
"@android:attr/listDivider was not set in the theme used for this DividerItemDecoration. Please set that attribute all call setDrawable()"
)
} }
a.recycle() a.recycle()
setOrientation(orientation) setOrientation(orientation)

@ -27,7 +27,8 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener
import io.legado.app.BuildConfig import io.legado.app.BuildConfig
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper.AdvanceCallback.Mode import io.legado.app.ui.widget.recycler.DragSelectTouchHelper.AdvanceCallback.Mode
import timber.log.Timber import io.legado.app.utils.DebugLog
import java.util.* import java.util.*
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
@ -971,15 +972,15 @@ class DragSelectTouchHelper(
private object Logger { private object Logger {
private val DEBUG = BuildConfig.DEBUG private val DEBUG = BuildConfig.DEBUG
fun d(msg: String) { fun d(msg: String) {
Timber.d(msg) DebugLog.d(javaClass.name, msg)
} }
fun e(msg: String) { fun e(msg: String) {
Timber.e(msg) DebugLog.e(javaClass.name, msg)
} }
fun i(msg: String) { fun i(msg: String) {
Timber.i(msg) DebugLog.i(javaClass.name, msg)
} }
fun logSelectStateChange(before: Int, after: Int) { fun logSelectStateChange(before: Int, after: Int) {

@ -11,7 +11,7 @@ import android.graphics.drawable.Drawable
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.io.* import java.io.*
import java.util.* import java.util.*
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
@ -70,11 +70,11 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
init { init {
try { try {
if (!cacheDir.exists() && !cacheDir.mkdirs()) { if (!cacheDir.exists() && !cacheDir.mkdirs()) {
Timber.i("can't make dirs in %s" + cacheDir.absolutePath) DebugLog.i(javaClass.name, "can't make dirs in %s" + cacheDir.absolutePath)
} }
mCache = ACacheManager(cacheDir, max_size, max_count) mCache = ACacheManager(cacheDir, max_size, max_count)
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
@ -96,7 +96,7 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
file.writeText(value) file.writeText(value)
mCache.put(file) mCache.put(file)
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
} }
@ -131,7 +131,7 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
removeFile = true removeFile = true
} }
} catch (e: IOException) { } catch (e: IOException) {
Timber.e(e) e.printOnDebug()
} finally { } finally {
if (removeFile) if (removeFile)
remove(key) remove(key)
@ -269,7 +269,7 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
null null
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} finally { } finally {
if (removeFile) if (removeFile)
remove(key) remove(key)
@ -299,7 +299,7 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
@ -318,18 +318,18 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
ois = ObjectInputStream(bis) ois = ObjectInputStream(bis)
return ois.readObject() return ois.readObject()
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} finally { } finally {
try { try {
bis?.close() bis?.close()
} catch (e: IOException) { } catch (e: IOException) {
Timber.e(e) e.printOnDebug()
} }
try { try {
ois?.close() ois?.close()
} catch (e: IOException) { } catch (e: IOException) {
Timber.e(e) e.printOnDebug()
} }
} }
@ -427,7 +427,7 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
return f return f
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
return null return null
@ -488,7 +488,7 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
return false return false
@ -662,7 +662,7 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
cacheCount.set(count) cacheCount.set(count)
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
@ -693,7 +693,7 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
file.setLastModified(currentTime) file.setLastModified(currentTime)
lastUsageDates[file] = currentTime lastUsageDates[file] = currentTime
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
@ -727,7 +727,7 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
} }
@ -767,7 +767,7 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
} }
return fileSize return fileSize
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
return 0 return 0
} }

@ -29,7 +29,7 @@ import io.legado.app.R
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
import io.legado.app.help.IntentHelp import io.legado.app.help.IntentHelp
import splitties.systemservices.clipboardManager import splitties.systemservices.clipboardManager
import timber.log.Timber
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
@ -178,7 +178,7 @@ val Context.sysScreenOffTime: Int
return kotlin.runCatching { return kotlin.runCatching {
Settings.System.getInt(contentResolver, Settings.System.SCREEN_OFF_TIMEOUT) Settings.System.getInt(contentResolver, Settings.System.SCREEN_OFF_TIMEOUT)
}.onFailure { }.onFailure {
Timber.e(it) it.printOnDebug()
}.getOrDefault(0) }.getOrDefault(0)
} }
@ -338,7 +338,7 @@ val Context.channel: String
val appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA) val appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA)
return appInfo.metaData.getString("channel") ?: "" return appInfo.metaData.getString("channel") ?: ""
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
return "" return ""
} }

@ -0,0 +1,54 @@
package io.legado.app.utils
import android.util.Log
import io.legado.app.BuildConfig
object DebugLog {
fun e(tag: String, throwable: Throwable) {
if (BuildConfig.DEBUG) {
Log.e(tag, throwable.stackTraceToString())
}
}
fun e(tag: String, msg: String, throwable: Throwable? = null) {
if (BuildConfig.DEBUG) {
if (throwable == null) {
Log.e(tag, msg)
} else {
Log.e(tag, msg, throwable)
}
}
}
fun d(tag: String, msg: String, throwable: Throwable? = null) {
if (BuildConfig.DEBUG) {
if (throwable == null) {
Log.d(tag, msg)
} else {
Log.d(tag, msg, throwable)
}
}
}
fun i(tag: String, msg: String, throwable: Throwable? = null) {
if (BuildConfig.DEBUG) {
if (throwable == null) {
Log.i(tag, msg)
} else {
Log.i(tag, msg, throwable)
}
}
}
fun w(tag: String, msg: String, throwable: Throwable? = null) {
if (BuildConfig.DEBUG) {
if (throwable == null) {
Log.w(tag, msg)
} else {
Log.w(tag, msg, throwable)
}
}
}
}

@ -4,7 +4,7 @@ import android.os.Environment
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import androidx.annotation.IntDef import androidx.annotation.IntDef
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.io.* import java.io.*
import java.nio.charset.Charset import java.nio.charset.Charset
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -46,7 +46,7 @@ object FileUtils {
file.createNewFile() file.createNewFile()
} }
} catch (e: IOException) { } catch (e: IOException) {
Timber.e(e) e.printOnDebug()
} }
return file return file
} }
@ -117,7 +117,7 @@ object FileUtils {
try { try {
sdCardDirectory = File(sdCardDirectory).canonicalPath sdCardDirectory = File(sdCardDirectory).canonicalPath
} catch (e: IOException) { } catch (e: IOException) {
Timber.e(e) e.printOnDebug()
} }
return sdCardDirectory return sdCardDirectory
} }

@ -4,7 +4,7 @@ import com.google.gson.*
import com.google.gson.internal.LinkedTreeMap import com.google.gson.internal.LinkedTreeMap
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonWriter import com.google.gson.stream.JsonWriter
import timber.log.Timber
import java.io.OutputStream import java.io.OutputStream
import java.io.OutputStreamWriter import java.io.OutputStreamWriter
import java.lang.reflect.ParameterizedType import java.lang.reflect.ParameterizedType
@ -27,18 +27,20 @@ val GSON: Gson by lazy {
inline fun <reified T> genericType(): Type = object : TypeToken<T>() {}.type inline fun <reified T> genericType(): Type = object : TypeToken<T>() {}.type
inline fun <reified T> Gson.fromJsonObject(json: String?): T? {//可转成任意类型 inline fun <reified T> Gson.fromJsonObject(json: String?): T? {//可转成任意类型
json ?: return null
return kotlin.runCatching { return kotlin.runCatching {
fromJson(json, genericType<T>()) as? T fromJson(json, genericType<T>()) as? T
}.onFailure { }.onFailure {
Timber.e(it, json) DebugLog.e("GSON解析出错", json, it)
}.getOrNull() }.getOrNull()
} }
inline fun <reified T> Gson.fromJsonArray(json: String?): List<T>? { inline fun <reified T> Gson.fromJsonArray(json: String?): List<T>? {
json ?: return null
return kotlin.runCatching { return kotlin.runCatching {
fromJson(json, ParameterizedTypeImpl(T::class.java)) as? List<T> fromJson(json, ParameterizedTypeImpl(T::class.java)) as? List<T>
}.onFailure { }.onFailure {
Timber.e(it, json) DebugLog.e("GSON解析出错", json, it)
}.getOrNull() }.getOrNull()
} }

@ -3,6 +3,7 @@
package io.legado.app.utils package io.legado.app.utils
import android.annotation.SuppressLint import android.annotation.SuppressLint
import io.legado.app.BuildConfig
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import splitties.init.appCtx import splitties.init.appCtx
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -73,3 +74,9 @@ object LogUtils {
return sdf.format(date) return sdf.format(date)
} }
} }
fun Throwable.printOnDebug() {
if (BuildConfig.DEBUG) {
printStackTrace()
}
}

@ -1,6 +1,6 @@
package io.legado.app.utils package io.legado.app.utils
import timber.log.Timber
import java.security.MessageDigest import java.security.MessageDigest
import java.security.NoSuchAlgorithmException import java.security.NoSuchAlgorithmException
@ -26,7 +26,7 @@ object MD5Utils {
} }
reStr = stringBuffer.toString() reStr = stringBuffer.toString()
} catch (e: NoSuchAlgorithmException) { } catch (e: NoSuchAlgorithmException) {
Timber.e(e) e.printOnDebug()
} }
return reStr return reStr

@ -3,9 +3,10 @@ package io.legado.app.utils
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.NetworkCapabilities import android.net.NetworkCapabilities
import android.os.Build import android.os.Build
import io.legado.app.constant.AppLog
import okhttp3.internal.publicsuffix.PublicSuffixDatabase import okhttp3.internal.publicsuffix.PublicSuffixDatabase
import splitties.systemservices.connectivityManager import splitties.systemservices.connectivityManager
import timber.log.Timber
import java.net.InetAddress import java.net.InetAddress
import java.net.NetworkInterface import java.net.NetworkInterface
import java.net.SocketException import java.net.SocketException
@ -117,7 +118,7 @@ object NetworkUtils {
relativeUrl = parseUrl.toString() relativeUrl = parseUrl.toString()
return relativeUrl return relativeUrl
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
} }
return relativeUrl return relativeUrl
} }
@ -134,7 +135,7 @@ object NetworkUtils {
relativeUrl = parseUrl.toString() relativeUrl = parseUrl.toString()
return relativeUrl return relativeUrl
} catch (e: Exception) { } catch (e: Exception) {
Timber.e("网址拼接出错\n${e.localizedMessage}", e) AppLog.put("网址拼接出错\n${e.localizedMessage}", e)
} }
return relativeUrl return relativeUrl
} }
@ -179,7 +180,7 @@ object NetworkUtils {
try { try {
enumeration = NetworkInterface.getNetworkInterfaces() enumeration = NetworkInterface.getNetworkInterfaces()
} catch (e: SocketException) { } catch (e: SocketException) {
Timber.e(e) e.printOnDebug()
} }
if (enumeration != null) { if (enumeration != null) {

@ -9,7 +9,7 @@ import android.os.Build
import android.os.Environment import android.os.Environment
import android.provider.DocumentsContract import android.provider.DocumentsContract
import android.provider.MediaStore import android.provider.MediaStore
import timber.log.Timber
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
@ -112,7 +112,7 @@ object RealPathUtil {
return cursor.getString(index) return cursor.getString(index)
} }
} catch (e: IllegalArgumentException) { } catch (e: IllegalArgumentException) {
Timber.e(e) e.printOnDebug()
val file = File(context.cacheDir, "tmp") val file = File(context.cacheDir, "tmp")
val filePath = file.absolutePath val filePath = file.absolutePath
var input: FileInputStream? = null var input: FileInputStream? = null
@ -130,8 +130,8 @@ object RealPathUtil {
output.write(bytes, 0, read) output.write(bytes, 0, read)
} }
return File(filePath).absolutePath return File(filePath).absolutePath
} catch (ignored: IOException) { } catch (e: IOException) {
Timber.e(ignored) e.printStackTrace()
} finally { } finally {
input?.close() input?.close()
output?.close() output?.close()

@ -2,7 +2,7 @@ package io.legado.app.utils
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.text.TextUtils.isEmpty import android.text.TextUtils.isEmpty
import timber.log.Timber
import java.text.DecimalFormat import java.text.DecimalFormat
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -83,7 +83,7 @@ object StringUtils {
} }
} }
}.onFailure { }.onFailure {
Timber.e(it) it.printOnDebug()
} }
return "" return ""
} }

@ -9,7 +9,7 @@ import io.legado.app.R
import io.legado.app.lib.permission.Permissions import io.legado.app.lib.permission.Permissions
import io.legado.app.lib.permission.PermissionsCompat import io.legado.app.lib.permission.PermissionsCompat
import io.legado.app.model.NoStackTraceException import io.legado.app.model.NoStackTraceException
import timber.log.Timber
import java.io.File import java.io.File
fun Uri.isContentScheme() = this.scheme == "content" fun Uri.isContentScheme() = this.scheme == "content"
@ -42,7 +42,7 @@ fun AppCompatActivity.readUri(uri: Uri?, success: (name: String, bytes: ByteArra
.request() .request()
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
toastOnUi(e.localizedMessage ?: "read uri error") toastOnUi(e.localizedMessage ?: "read uri error")
} }
} }
@ -75,7 +75,7 @@ fun Fragment.readUri(uri: Uri?, success: (name: String, bytes: ByteArray) -> Uni
.request() .request()
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) e.printOnDebug()
toastOnUi(e.localizedMessage ?: "read uri error") toastOnUi(e.localizedMessage ?: "read uri error")
} }
} }

@ -21,7 +21,7 @@ import androidx.viewpager.widget.ViewPager
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.lib.theme.TintHelper import io.legado.app.lib.theme.TintHelper
import splitties.systemservices.inputMethodManager import splitties.systemservices.inputMethodManager
import timber.log.Timber
import java.lang.reflect.Field import java.lang.reflect.Field
@ -170,6 +170,6 @@ fun PopupMenu.show(x: Int, y: Int) {
field.isAccessible = true field.isAccessible = true
(field.get(this) as MenuPopupHelper).show(x, y) (field.get(this) as MenuPopupHelper).show(x, y)
}.onFailure { }.onFailure {
Timber.e(it) it.printOnDebug()
} }
} }

@ -2,7 +2,7 @@ package io.legado.app.utils
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import timber.log.Timber
import java.io.* import java.io.*
import java.util.zip.ZipEntry import java.util.zip.ZipEntry
import java.util.zip.ZipFile import java.util.zip.ZipFile
@ -241,7 +241,7 @@ object ZipUtils {
val entry = entries.nextElement() as ZipEntry val entry = entries.nextElement() as ZipEntry
val entryName = entry.name val entryName = entry.name
if (entryName.contains("../")) { if (entryName.contains("../")) {
Timber.e("entryName: $entryName is dangerous!") DebugLog.e(javaClass.name, "entryName: $entryName is dangerous!")
continue continue
} }
if (!unzipChildFile(destDir, files, zip, entry, entryName)) return files if (!unzipChildFile(destDir, files, zip, entry, entryName)) return files
@ -251,7 +251,7 @@ object ZipUtils {
val entry = entries.nextElement() as ZipEntry val entry = entries.nextElement() as ZipEntry
val entryName = entry.name val entryName = entry.name
if (entryName.contains("../")) { if (entryName.contains("../")) {
Timber.e("entryName: $entryName is dangerous!") DebugLog.e(javaClass.name, "entryName: $entryName is dangerous!")
continue continue
} }
if (entryName.contains(keyword!!)) { if (entryName.contains(keyword!!)) {
@ -314,7 +314,7 @@ object ZipUtils {
while (entries.hasMoreElements()) { while (entries.hasMoreElements()) {
val entryName = (entries.nextElement() as ZipEntry).name val entryName = (entries.nextElement() as ZipEntry).name
if (entryName.contains("../")) { if (entryName.contains("../")) {
Timber.e("entryName: $entryName is dangerous!") DebugLog.e(javaClass.name, "entryName: $entryName is dangerous!")
paths.add(entryName) paths.add(entryName)
} else { } else {
paths.add(entryName) paths.add(entryName)
@ -368,7 +368,7 @@ object ZipUtils {
return try { return try {
file.createNewFile() file.createNewFile()
} catch (e: IOException) { } catch (e: IOException) {
Timber.e(e) e.printOnDebug()
false false
} }
} }

@ -6,14 +6,11 @@ import fi.iki.elonen.NanoWSD
import io.legado.app.R import io.legado.app.R
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.model.Debug import io.legado.app.model.Debug
import io.legado.app.utils.GSON import io.legado.app.utils.*
import io.legado.app.utils.fromJsonObject
import io.legado.app.utils.isJson
import io.legado.app.utils.runOnIO
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.io.IOException import java.io.IOException
@ -90,7 +87,7 @@ class BookSourceDebugWebSocket(handshakeRequest: NanoHTTPD.IHTTPSession) :
close(NanoWSD.WebSocketFrame.CloseCode.NormalClosure, "调试结束", false) close(NanoWSD.WebSocketFrame.CloseCode.NormalClosure, "调试结束", false)
} }
}.onFailure { }.onFailure {
Timber.e(it) it.printOnDebug()
} }
} }
} }

@ -6,14 +6,11 @@ import fi.iki.elonen.NanoWSD
import io.legado.app.R import io.legado.app.R
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.model.Debug import io.legado.app.model.Debug
import io.legado.app.utils.GSON import io.legado.app.utils.*
import io.legado.app.utils.fromJsonObject
import io.legado.app.utils.isJson
import io.legado.app.utils.runOnIO
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import splitties.init.appCtx import splitties.init.appCtx
import timber.log.Timber
import java.io.IOException import java.io.IOException
@ -89,7 +86,7 @@ class RssSourceDebugWebSocket(handshakeRequest: NanoHTTPD.IHTTPSession) :
close(NanoWSD.WebSocketFrame.CloseCode.NormalClosure, "调试结束", false) close(NanoWSD.WebSocketFrame.CloseCode.NormalClosure, "调试结束", false)
} }
}.onFailure { }.onFailure {
Timber.e(it) it.printOnDebug()
} }
} }
} }

@ -17,6 +17,7 @@ buildscript {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'de.timfreiheit.resourceplaceholders:placeholders:0.4' classpath 'de.timfreiheit.resourceplaceholders:placeholders:0.4'
classpath 'de.undercouch:gradle-download-task:4.1.2' classpath 'de.undercouch:gradle-download-task:4.1.2'
classpath 'com.google.gms:google-services:4.3.10'
} }
} }

Loading…
Cancel
Save