kunfei há 4 anos atrás
pai
commit
b5142b22c1

+ 18 - 10
app/src/main/java/io/legado/app/help/TTS.kt

@@ -4,14 +4,19 @@ import android.speech.tts.TextToSpeech
 import android.speech.tts.UtteranceProgressListener
 import android.speech.tts.UtteranceProgressListener
 import io.legado.app.R
 import io.legado.app.R
 import io.legado.app.constant.AppLog
 import io.legado.app.constant.AppLog
+import io.legado.app.utils.buildMainHandler
 import io.legado.app.utils.splitNotBlank
 import io.legado.app.utils.splitNotBlank
 import io.legado.app.utils.toastOnUi
 import io.legado.app.utils.toastOnUi
 import splitties.init.appCtx
 import splitties.init.appCtx
 
 
 class TTS {
 class TTS {
 
 
+    private val handler by lazy { buildMainHandler() }
+
     private val tag = "legado_tts"
     private val tag = "legado_tts"
 
 
+    private val clearTtsRunnable = Runnable { clearTts() }
+
     private var textToSpeech: TextToSpeech? = null
     private var textToSpeech: TextToSpeech? = null
 
 
     private var text: String? = null
     private var text: String? = null
@@ -24,20 +29,19 @@ class TTS {
         TTSUtteranceListener()
         TTSUtteranceListener()
     }
     }
 
 
+    @Synchronized
     fun speak(text: String) {
     fun speak(text: String) {
+        handler.removeCallbacks(clearTtsRunnable)
         this.text = text
         this.text = text
         if (textToSpeech == null) {
         if (textToSpeech == null) {
-
+            textToSpeech = TextToSpeech(appCtx, initListener)
         } else {
         } else {
-
+            addTextToSpeakList()
         }
         }
     }
     }
 
 
-    private fun initTts() {
-        textToSpeech == TextToSpeech(appCtx, initListener)
-    }
-
-    private fun clearTts() {
+    @Synchronized
+    fun clearTts() {
         textToSpeech?.let { tts ->
         textToSpeech?.let { tts ->
             tts.stop()
             tts.stop()
             tts.shutdown()
             tts.shutdown()
@@ -72,6 +76,7 @@ class TTS {
         override fun onInit(status: Int) {
         override fun onInit(status: Int) {
             if (status == TextToSpeech.SUCCESS) {
             if (status == TextToSpeech.SUCCESS) {
                 textToSpeech?.setOnUtteranceProgressListener(utteranceListener)
                 textToSpeech?.setOnUtteranceProgressListener(utteranceListener)
+                addTextToSpeakList()
             } else {
             } else {
                 appCtx.toastOnUi(R.string.tts_init_failed)
                 appCtx.toastOnUi(R.string.tts_init_failed)
             }
             }
@@ -85,15 +90,18 @@ class TTS {
     private inner class TTSUtteranceListener : UtteranceProgressListener() {
     private inner class TTSUtteranceListener : UtteranceProgressListener() {
 
 
         override fun onStart(utteranceId: String?) {
         override fun onStart(utteranceId: String?) {
-            TODO("Not yet implemented")
+            //开始朗读取消释放资源任务
+            handler.removeCallbacks(clearTtsRunnable)
         }
         }
 
 
         override fun onDone(utteranceId: String?) {
         override fun onDone(utteranceId: String?) {
-            TODO("Not yet implemented")
+            //一分钟没有朗读释放资源
+            handler.postDelayed(clearTtsRunnable, 60000L)
         }
         }
 
 
+        @Deprecated("Deprecated in Java")
         override fun onError(utteranceId: String?) {
         override fun onError(utteranceId: String?) {
-            TODO("Not yet implemented")
+
         }
         }
 
 
     }
     }

+ 4 - 4
app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt

@@ -431,13 +431,13 @@ class ReadBookActivity : BaseReadBookActivity(),
             if (event.action == MotionEvent.ACTION_SCROLL) {
             if (event.action == MotionEvent.ACTION_SCROLL) {
                 val axisValue = event.getAxisValue(MotionEvent.AXIS_VSCROLL)
                 val axisValue = event.getAxisValue(MotionEvent.AXIS_VSCROLL)
                 LogUtils.d("onGenericMotionEvent", "axisValue = $axisValue")
                 LogUtils.d("onGenericMotionEvent", "axisValue = $axisValue")
-                mainHandler.removeCallbacks(nextPageRunnable)
-                mainHandler.removeCallbacks(prevPageRunnable)
+                binding.root.removeCallbacks(nextPageRunnable)
+                binding.root.removeCallbacks(prevPageRunnable)
                 // 获得垂直坐标上的滚动方向
                 // 获得垂直坐标上的滚动方向
                 if (axisValue < 0.0f) { // 滚轮向下滚
                 if (axisValue < 0.0f) { // 滚轮向下滚
-                    mainHandler.postDelayed(nextPageRunnable, 200)
+                    binding.root.postDelayed(nextPageRunnable, 200)
                 } else { // 滚轮向上滚
                 } else { // 滚轮向上滚
-                    mainHandler.postDelayed(prevPageRunnable, 200)
+                    binding.root.postDelayed(prevPageRunnable, 200)
                 }
                 }
                 return true
                 return true
             }
             }

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

@@ -10,20 +10,14 @@ import kotlinx.coroutines.Dispatchers.IO
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.launch
 
 
 /** This main looper cache avoids synchronization overhead when accessed repeatedly. */
 /** This main looper cache avoids synchronization overhead when accessed repeatedly. */
-@JvmField
-val mainLooper: Looper = Looper.getMainLooper()
+private val mainLooper: Looper = Looper.getMainLooper()
 
 
-@JvmField
-val mainThread: Thread = mainLooper.thread
+private val mainThread: Thread = mainLooper.thread
 
 
-val isMainThread: Boolean inline get() = mainThread === Thread.currentThread()
+private val isMainThread: Boolean inline get() = mainThread === Thread.currentThread()
 
 
-@PublishedApi
-internal val currentThread: Any?
-    inline get() = Thread.currentThread()
-
-val mainHandler: Handler by lazy {
-    if (SDK_INT >= 28) Handler.createAsync(mainLooper) else try {
+fun buildMainHandler(): Handler {
+    return if (SDK_INT >= 28) Handler.createAsync(mainLooper) else try {
         Handler::class.java.getDeclaredConstructor(
         Handler::class.java.getDeclaredConstructor(
             Looper::class.java,
             Looper::class.java,
             Handler.Callback::class.java,
             Handler.Callback::class.java,
@@ -35,6 +29,8 @@ val mainHandler: Handler by lazy {
     }
     }
 }
 }
 
 
+private val mainHandler by lazy { buildMainHandler() }
+
 fun runOnUI(function: () -> Unit) {
 fun runOnUI(function: () -> Unit) {
     if (isMainThread) {
     if (isMainThread) {
         function()
         function()

+ 4 - 2
app/src/main/java/io/legado/app/utils/RegexExtensions.kt

@@ -9,6 +9,8 @@ import splitties.init.appCtx
 import kotlin.coroutines.resume
 import kotlin.coroutines.resume
 import kotlin.coroutines.resumeWithException
 import kotlin.coroutines.resumeWithException
 
 
+private val handler by lazy { buildMainHandler() }
+
 /**
 /**
  * 带有超时检测的正则替换
  * 带有超时检测的正则替换
  * 超时重启apk,线程不能强制结束,只能重启apk
  * 超时重启apk,线程不能强制结束,只能重启apk
@@ -24,14 +26,14 @@ suspend fun CharSequence.replace(regex: Regex, replacement: String, timeout: Lon
                 block.resumeWithException(e)
                 block.resumeWithException(e)
             }
             }
         }
         }
-        mainHandler.postDelayed(timeout) {
+        handler.postDelayed(timeout) {
             if (coroutine.isActive) {
             if (coroutine.isActive) {
                 val timeoutMsg = "替换超时,3秒后还未结束将重启应用\n替换规则$regex\n替换内容:${this}"
                 val timeoutMsg = "替换超时,3秒后还未结束将重启应用\n替换规则$regex\n替换内容:${this}"
                 val exception = RegexTimeoutException(timeoutMsg)
                 val exception = RegexTimeoutException(timeoutMsg)
                 block.cancel(exception)
                 block.cancel(exception)
                 appCtx.longToastOnUi(timeoutMsg)
                 appCtx.longToastOnUi(timeoutMsg)
                 CrashHandler.saveCrashInfo2File(exception)
                 CrashHandler.saveCrashInfo2File(exception)
-                mainHandler.postDelayed(3000) {
+                handler.postDelayed(3000) {
                     if (coroutine.isActive) {
                     if (coroutine.isActive) {
                         appCtx.restart()
                         appCtx.restart()
                     }
                     }