This commit is contained in:
kunfei 2022-02-26 20:59:43 +08:00
parent 8712a58ed4
commit 8dcb62c984
72 changed files with 334 additions and 267 deletions

View File

@ -3,6 +3,7 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
apply plugin: 'de.timfreiheit.resourceplaceholders'
apply plugin: 'com.google.gms.google-services'
apply from: 'download.gradle'
static def releaseTime() {
@ -150,7 +151,9 @@ dependencies {
implementation('com.google.code.gson:gson:2.8.9')
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
implementation("androidx.media:media:1.5.0")

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,8 +1,9 @@
package io.legado.app.help.http.cronet
import io.legado.app.help.http.CookieStore
import io.legado.app.utils.printOnDebug
import okhttp3.*
import timber.log.Timber
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)
&& !e.message.toString().contains("ERR_SSL_", true)
) {
Timber.e(e)
e.printOnDebug()
}
chain.proceed(original)
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@ import android.service.quicksettings.Tile
import android.service.quicksettings.TileService
import androidx.annotation.RequiresApi
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) {
Timber.e(e)
e.printOnDebug()
}
return super.onStartCommand(intent, flags, startId)
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,8 @@ import android.graphics.drawable.Drawable
import android.view.View
import android.widget.LinearLayout
import androidx.recyclerview.widget.RecyclerView
import timber.log.Timber
import io.legado.app.utils.DebugLog
import kotlin.math.roundToInt
@ -38,7 +39,10 @@ class DividerNoLast(context: Context, orientation: Int) :
val a = context.obtainStyledAttributes(attrs)
mDivider = a.getDrawable(0)
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()
setOrientation(orientation)

View File

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

View File

@ -11,7 +11,7 @@ import android.graphics.drawable.Drawable
import org.json.JSONArray
import org.json.JSONObject
import splitties.init.appCtx
import timber.log.Timber
import java.io.*
import java.util.*
import java.util.concurrent.atomic.AtomicInteger
@ -70,11 +70,11 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
init {
try {
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)
} 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)
mCache.put(file)
} 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
}
} catch (e: IOException) {
Timber.e(e)
e.printOnDebug()
} finally {
if (removeFile)
remove(key)
@ -269,7 +269,7 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
null
}
} catch (e: Exception) {
Timber.e(e)
e.printOnDebug()
} finally {
if (removeFile)
remove(key)
@ -299,7 +299,7 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
}
}
} 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)
return ois.readObject()
} catch (e: Exception) {
Timber.e(e)
e.printOnDebug()
} finally {
try {
bis?.close()
} catch (e: IOException) {
Timber.e(e)
e.printOnDebug()
}
try {
ois?.close()
} 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
}
} catch (e: Exception) {
Timber.e(e)
e.printOnDebug()
}
}
return null
@ -488,7 +488,7 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
}
}
} catch (e: Exception) {
Timber.e(e)
e.printOnDebug()
}
return false
@ -662,7 +662,7 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
cacheCount.set(count)
}
} 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)
lastUsageDates[file] = currentTime
} 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) {
Timber.e(e)
e.printOnDebug()
}
}
@ -767,7 +767,7 @@ class ACache private constructor(cacheDir: File, max_size: Long, max_count: Int)
}
return fileSize
} catch (e: Exception) {
Timber.e(e)
e.printOnDebug()
return 0
}

View File

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

View File

@ -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)
}
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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