Horis 1 rok temu
rodzic
commit
f0247b3a8a

+ 1 - 0
app/src/main/assets/web/help/md/jsHelp.md

@@ -39,6 +39,7 @@
 ### [RssJsExtensions](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/ui/rss/read/RssJsExtensions.kt)
 ### [RssJsExtensions](https://github.com/gedoor/legado/blob/master/app/src/main/java/io/legado/app/ui/rss/read/RssJsExtensions.kt)
 > 只能在订阅源`shouldOverrideUrlLoading`规则中使用  
 > 只能在订阅源`shouldOverrideUrlLoading`规则中使用  
 > 订阅添加跳转url拦截, js, 返回true拦截,js变量url,可以通过js打开url  
 > 订阅添加跳转url拦截, js, 返回true拦截,js变量url,可以通过js打开url  
+> url跳转拦截规则不能执行耗时操作
 > 例子https://github.com/gedoor/legado/discussions/3259
 > 例子https://github.com/gedoor/legado/discussions/3259
 
 
 * 调用阅读搜索
 * 调用阅读搜索

+ 10 - 0
app/src/main/java/io/legado/app/help/JsExtensions.kt

@@ -40,6 +40,7 @@ import io.legado.app.utils.createFileReplace
 import io.legado.app.utils.externalCache
 import io.legado.app.utils.externalCache
 import io.legado.app.utils.fromJsonObject
 import io.legado.app.utils.fromJsonObject
 import io.legado.app.utils.isAbsUrl
 import io.legado.app.utils.isAbsUrl
+import io.legado.app.utils.isMainThread
 import io.legado.app.utils.longToastOnUi
 import io.legado.app.utils.longToastOnUi
 import io.legado.app.utils.mapAsync
 import io.legado.app.utils.mapAsync
 import io.legado.app.utils.stackTraceStr
 import io.legado.app.utils.stackTraceStr
@@ -167,6 +168,9 @@ interface JsExtensions : JsEncodeUtils {
      * @return 返回js获取的内容
      * @return 返回js获取的内容
      */
      */
     fun webView(html: String?, url: String?, js: String?): String? {
     fun webView(html: String?, url: String?, js: String?): String? {
+        if (isMainThread) {
+            error("webView must be called on a background thread")
+        }
         return runBlocking(context) {
         return runBlocking(context) {
             BackstageWebView(
             BackstageWebView(
                 url = url,
                 url = url,
@@ -182,6 +186,9 @@ interface JsExtensions : JsEncodeUtils {
      * 使用webView获取资源url
      * 使用webView获取资源url
      */
      */
     fun webViewGetSource(html: String?, url: String?, js: String?, sourceRegex: String): String? {
     fun webViewGetSource(html: String?, url: String?, js: String?, sourceRegex: String): String? {
+        if (isMainThread) {
+            error("webViewGetSource must be called on a background thread")
+        }
         return runBlocking(context) {
         return runBlocking(context) {
             BackstageWebView(
             BackstageWebView(
                 url = url,
                 url = url,
@@ -203,6 +210,9 @@ interface JsExtensions : JsEncodeUtils {
         js: String?,
         js: String?,
         overrideUrlRegex: String
         overrideUrlRegex: String
     ): String? {
     ): String? {
+        if (isMainThread) {
+            error("webViewGetOverrideUrl must be called on a background thread")
+        }
         return runBlocking(context) {
         return runBlocking(context) {
             BackstageWebView(
             BackstageWebView(
                 url = url,
                 url = url,

+ 7 - 1
app/src/main/java/io/legado/app/help/source/SourceVerificationHelp.kt

@@ -7,6 +7,7 @@ import io.legado.app.help.CacheManager
 import io.legado.app.help.IntentData
 import io.legado.app.help.IntentData
 import io.legado.app.ui.association.VerificationCodeActivity
 import io.legado.app.ui.association.VerificationCodeActivity
 import io.legado.app.ui.browser.WebViewActivity
 import io.legado.app.ui.browser.WebViewActivity
+import io.legado.app.utils.isMainThread
 import io.legado.app.utils.startActivity
 import io.legado.app.utils.startActivity
 import splitties.init.appCtx
 import splitties.init.appCtx
 import java.util.concurrent.locks.LockSupport
 import java.util.concurrent.locks.LockSupport
@@ -19,7 +20,9 @@ object SourceVerificationHelp {
 
 
     private val waitTime = 1.minutes.inWholeNanoseconds
     private val waitTime = 1.minutes.inWholeNanoseconds
 
 
-    private fun getVerificationResultKey(source: BaseSource) = getVerificationResultKey(source.getKey())
+    private fun getVerificationResultKey(source: BaseSource) =
+        getVerificationResultKey(source.getKey())
+
     private fun getVerificationResultKey(sourceKey: String) = "${sourceKey}_verificationResult"
     private fun getVerificationResultKey(sourceKey: String) = "${sourceKey}_verificationResult"
 
 
     /**
     /**
@@ -35,6 +38,9 @@ object SourceVerificationHelp {
     ): String {
     ): String {
         source
         source
             ?: throw NoStackTraceException("getVerificationResult parameter source cannot be null")
             ?: throw NoStackTraceException("getVerificationResult parameter source cannot be null")
+        if (isMainThread) {
+            error("getVerificationResult must be called on a background thread")
+        }
 
 
         clearResult(source.getKey())
         clearResult(source.getKey())
 
 

+ 6 - 1
app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt

@@ -6,6 +6,7 @@ import android.content.res.Configuration
 import android.net.Uri
 import android.net.Uri
 import android.net.http.SslError
 import android.net.http.SslError
 import android.os.Bundle
 import android.os.Bundle
+import android.os.SystemClock
 import android.view.Menu
 import android.view.Menu
 import android.view.MenuItem
 import android.view.MenuItem
 import android.view.View
 import android.view.View
@@ -473,6 +474,7 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
             val source = viewModel.rssSource
             val source = viewModel.rssSource
             val js = source?.shouldOverrideUrlLoading
             val js = source?.shouldOverrideUrlLoading
             if (!js.isNullOrBlank()) {
             if (!js.isNullOrBlank()) {
+                val t = SystemClock.uptimeMillis()
                 val result = kotlin.runCatching {
                 val result = kotlin.runCatching {
                     runScriptWithContext(lifecycleScope.coroutineContext) {
                     runScriptWithContext(lifecycleScope.coroutineContext) {
                         source.evalJS(js) {
                         source.evalJS(js) {
@@ -481,8 +483,11 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
                         }.toString()
                         }.toString()
                     }
                     }
                 }.onFailure {
                 }.onFailure {
-                    AppLog.put("url跳转拦截js出错", it)
+                    AppLog.put("${source.getKey()}: url跳转拦截js出错", it)
                 }.getOrNull()
                 }.getOrNull()
+                if (SystemClock.uptimeMillis() - t > 30) {
+                    AppLog.put("${source.getKey()}: url跳转拦截js执行耗时过长")
+                }
                 if (result.isTrue()) {
                 if (result.isTrue()) {
                     return true
                     return true
                 }
                 }

+ 1 - 1
app/src/main/java/io/legado/app/utils/HandlerUtils.kt

@@ -14,7 +14,7 @@ private val mainLooper: Looper = Looper.getMainLooper()
 
 
 private val mainThread: Thread = mainLooper.thread
 private val mainThread: Thread = mainLooper.thread
 
 
-private val isMainThread: Boolean inline get() = mainThread === Thread.currentThread()
+val isMainThread: Boolean get() = mainThread === Thread.currentThread()
 
 
 fun buildMainHandler(): Handler {
 fun buildMainHandler(): Handler {
     return if (SDK_INT >= 28) Handler.createAsync(mainLooper) else try {
     return if (SDK_INT >= 28) Handler.createAsync(mainLooper) else try {