diff --git a/app/src/main/java/com/nova/brain/glass/common/CrashHandler.java b/app/src/main/java/com/nova/brain/glass/common/CrashHandler.java index 8a74076..5bf835b 100644 --- a/app/src/main/java/com/nova/brain/glass/common/CrashHandler.java +++ b/app/src/main/java/com/nova/brain/glass/common/CrashHandler.java @@ -6,7 +6,6 @@ import android.os.SystemClock; import android.util.Log; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; @@ -51,7 +50,9 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler { public static CrashHandler getInstance() { if (mCrashHandler == null) { synchronized (CrashHandler.class) { - mCrashHandler = new CrashHandler(); + if (mCrashHandler == null) { + mCrashHandler = new CrashHandler(); + } } } return mCrashHandler; @@ -135,17 +136,11 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler { if (!dir.exists()) { dir.mkdir(); } - FileOutputStream fos = null; - try { - fos = new FileOutputStream(path + fileName, true); + try (FileOutputStream fos = new FileOutputStream(path + fileName, true)) { fos.write(text.getBytes()); fos.flush(); - fos.close(); - - } catch (FileNotFoundException e) { - e.printStackTrace(); } catch (IOException e) { - e.printStackTrace(); + Log.e(TAG, "写入崩溃日志失败: " + fileName, e); } return fileName; } diff --git a/app/src/main/java/com/nova/brain/glass/helper/OfflineCmdServiceHelper.kt b/app/src/main/java/com/nova/brain/glass/helper/OfflineCmdServiceHelper.kt index 1c8da07..1367fb2 100644 --- a/app/src/main/java/com/nova/brain/glass/helper/OfflineCmdServiceHelper.kt +++ b/app/src/main/java/com/nova/brain/glass/helper/OfflineCmdServiceHelper.kt @@ -1,92 +1,81 @@ package com.nova.brain.glass.helper -import com.luck.picture.lib.config.PictureSelectionConfig.listener import com.rokid.security.glass3.open.sdk.GlassSdk import com.rokid.security.glass3.sdk.base.data.offlineCmd.bean.VoiceAction import com.rokid.security.glass3.sdk.base.data.offlineCmd.listener.IVoiceCallback import com.rokid.security.system.server.offlineCmd.IOfflineCmdService import com.xuqm.base.common.LogHelper -import java.util.concurrent.Executors +import java.util.concurrent.CopyOnWriteArrayList data class OfflineCmdBean(val text: String, val pinyin: String) object OfflineCmdServiceHelper { - private var listenerList = mutableListOf() - private val initExecutor = Executors.newSingleThreadExecutor() - @Volatile - private var initialized = false - @Volatile - private var initializing = false + // CopyOnWriteArrayList:遍历时不需要加锁,add/remove 不会引发 ConcurrentModificationException + private val listenerList = CopyOnWriteArrayList() - private val list = mutableListOf().apply { - // 首页 - add(OfflineCmdBean("任务列表", "ren wu lie biao")) - add(OfflineCmdBean("查看任务", "cha kan ren wu")) - add(OfflineCmdBean("查看任务列表", "cha kan ren wu lie biao")) - // 任务列表 - add(OfflineCmdBean("下一页", "xia yi ye")) - add(OfflineCmdBean("上一页", "shang yi ye")) - - add(OfflineCmdBean("退出", "tui chu")) - add(OfflineCmdBean("返回", "fan hui")) - - add(OfflineCmdBean("同意", "tong yi")) - add(OfflineCmdBean("驳回", "bo hui")) - add(OfflineCmdBean("通过", "tong guo")) - add(OfflineCmdBean("合格", "he ge")) - add(OfflineCmdBean("不合格", "bu he ge")) - add(OfflineCmdBean("取消", "qu xiao")) - - add(OfflineCmdBean("查看第一项任务", "cha kan di yi xiang ren wu")) - add(OfflineCmdBean("第一个", "di yi ge")) - - add(OfflineCmdBean("查看第二项任务", "cha kan di er xiang ren wu")) - add(OfflineCmdBean("第二个", "di er ge")) - - add(OfflineCmdBean("查看第三项任务", "cha kan di san xiang ren wu")) - add(OfflineCmdBean("第三个", "di san ge")) - - add(OfflineCmdBean("查看第四项任务", "cha kan di si xiang ren wu")) - add(OfflineCmdBean("第四个", "di si ge")) - - add(OfflineCmdBean("查看第五项任务", "cha kan di wu xiang ren wu")) - add(OfflineCmdBean("第五个", "di wu ge")) - - add(OfflineCmdBean("查看第六项任务", "cha kan di liu xiang ren wu")) - add(OfflineCmdBean("第六个", "di liu ge")) - - add(OfflineCmdBean("查看第七项任务", "cha kan di qi xiang ren wu")) - add(OfflineCmdBean("第七个", "di qi ge")) - - add(OfflineCmdBean("查看第八项任务", "cha kan di ba xiang ren wu")) - add(OfflineCmdBean("第八个", "di ba ge")) - - add(OfflineCmdBean("查看第九项任务", "cha kan di jiu xiang ren wu")) - add(OfflineCmdBean("第九个", "di jiu ge")) - - add(OfflineCmdBean("查看第十项任务", "cha kan di shi xiang ren wu")) - add(OfflineCmdBean("第十个", "di shi ge")) - - //喷涂 - add(OfflineCmdBean("开始", "kai shi")) - add(OfflineCmdBean("开始任务", "kai shi ren wu")) - add(OfflineCmdBean("重拍", "chong pai")) - add(OfflineCmdBean("继续拍摄", "ji xu pai she")) - add(OfflineCmdBean("人工更正结果", "ren gong geng zheng jie guo")) - add(OfflineCmdBean("人工更正", "ren gong geng zheng")) - add(OfflineCmdBean("更正", "geng zheng")) - add(OfflineCmdBean("结束任务", "jie shu ren wu")) - add(OfflineCmdBean("补充照片", "bu chong zhao pian")) - add(OfflineCmdBean("确认提交", "que ren ti jiao")) - // - } - - // 所有页面通用关键词 + // 所有页面通用关键词(常量,只分配一次) private val COMMON_CMDS = listOf( OfflineCmdBean("退出", "tui chu"), OfflineCmdBean("返回", "fan hui") ) + // 各页面独有命令列表(常量,避免每次 onResume/onPause 重复创建对象) + private val CMDS_TASK_LIST = listOf( + OfflineCmdBean("下一页", "xia yi ye"), + OfflineCmdBean("上一页", "shang yi ye"), + OfflineCmdBean("查看第一项任务", "cha kan di yi xiang ren wu"), + OfflineCmdBean("第一个", "di yi ge"), + OfflineCmdBean("查看第二项任务", "cha kan di er xiang ren wu"), + OfflineCmdBean("第二个", "di er ge"), + OfflineCmdBean("查看第三项任务", "cha kan di san xiang ren wu"), + OfflineCmdBean("第三个", "di san ge"), + OfflineCmdBean("查看第四项任务", "cha kan di si xiang ren wu"), + OfflineCmdBean("第四个", "di si ge"), + OfflineCmdBean("查看第五项任务", "cha kan di wu xiang ren wu"), + OfflineCmdBean("第五个", "di wu ge"), + OfflineCmdBean("查看第六项任务", "cha kan di liu xiang ren wu"), + OfflineCmdBean("第六个", "di liu ge") + ) + private val CMDS_INSPECTION = listOf( + OfflineCmdBean("驳回", "bo hui"), + OfflineCmdBean("通过", "tong guo"), + OfflineCmdBean("同意", "tong yi") + ) + private val CMDS_SPRAYING = listOf( + OfflineCmdBean("开始任务", "kai shi ren wu") + ) + private val CMDS_SPRAYING_FINISH = listOf( + OfflineCmdBean("补充照片", "bu chong zhao pian"), + OfflineCmdBean("确认提交", "que ren ti jiao") + ) + private val CMDS_SPRAYING_MANUAL_RESULT = listOf( + OfflineCmdBean("合格", "he ge"), + OfflineCmdBean("不合格", "bu he ge"), + OfflineCmdBean("取消", "qu xiao") + ) + private val CMDS_SPRAYING_OCR = listOf( + OfflineCmdBean("重拍", "chong pai") + ) + private val CMDS_SPRAYING_RESULT = listOf( + OfflineCmdBean("重拍", "chong pai"), + OfflineCmdBean("继续拍摄", "ji xu pai she"), + OfflineCmdBean("人工更正结果", "ren gong geng zheng jie guo"), + OfflineCmdBean("更正", "geng zheng"), + OfflineCmdBean("结束任务", "jie shu ren wu") + ) + private val CMDS_INSPECTION_RESULT = listOf( + OfflineCmdBean("重拍照", "chong pai zhao"), + OfflineCmdBean("结束任务", "jie shu ren wu"), + OfflineCmdBean("继续任务", "ji xu ren wu") + ) + private val CMDS_INSPECTION_MISSING = listOf( + OfflineCmdBean("补充单证", "bu chong dan zheng"), + OfflineCmdBean("继续提交", "ji xu ti jiao") + ) + private val CMDS_INSPECTION_COMPLETE = listOf( + OfflineCmdBean("完成任务", "wan cheng ren wu") + ) + private var service: IOfflineCmdService? = null private fun registerBeans(beans: List) { @@ -131,24 +120,8 @@ object OfflineCmdServiceHelper { this.listenerList.remove(listener) } - fun addListenerList(){ - // 任务列表独有关键词(通用关键词已在 init 注册,无需重复) - registerBeans(listOf( - OfflineCmdBean("下一页", "xia yi ye"), - OfflineCmdBean("上一页", "shang yi ye"), - OfflineCmdBean("查看第一项任务", "cha kan di yi xiang ren wu"), - OfflineCmdBean("第一个", "di yi ge"), - OfflineCmdBean("查看第二项任务", "cha kan di er xiang ren wu"), - OfflineCmdBean("第二个", "di er ge"), - OfflineCmdBean("查看第三项任务", "cha kan di san xiang ren wu"), - OfflineCmdBean("第三个", "di san ge"), - OfflineCmdBean("查看第四项任务", "cha kan di si xiang ren wu"), - OfflineCmdBean("第四个", "di si ge"), - OfflineCmdBean("查看第五项任务", "cha kan di wu xiang ren wu"), - OfflineCmdBean("第五个", "di wu ge"), - OfflineCmdBean("查看第六项任务", "cha kan di liu xiang ren wu"), - OfflineCmdBean("第六个", "di liu ge") - )) + fun addListenerList() { + registerBeans(CMDS_TASK_LIST) } fun removeAll(){ @@ -158,167 +131,48 @@ object OfflineCmdServiceHelper { // addListenerFo: 无独有关键词,通用关键词已在 init 注册 fun addListenerFo(){ } - fun addListenerInspection(){ - // 巡检页独有关键词 - registerBeans(listOf( - OfflineCmdBean("驳回", "bo hui"), - OfflineCmdBean("通过", "tong guo"), - OfflineCmdBean("同意", "tong yi") - )) - } + fun addListenerInspection() = registerBeans(CMDS_INSPECTION) - fun addListenerSpraying(){ - // 喷涂页独有关键词 - registerBeans(listOf( - OfflineCmdBean("开始任务", "kai shi ren wu") - )) - } + fun addListenerSpraying() = registerBeans(CMDS_SPRAYING) - fun addListenerSprayingFinish(){ - // 喷涂完成页独有关键词 - registerBeans(listOf( - OfflineCmdBean("补充照片", "bu chong zhao pian"), - OfflineCmdBean("确认提交", "que ren ti jiao") - )) - } + fun addListenerSprayingFinish() = registerBeans(CMDS_SPRAYING_FINISH) - fun addListenerSprayingManualResulth(){ - // 喷涂人工更正页独有关键词 - registerBeans(listOf( - OfflineCmdBean("合格", "he ge"), - OfflineCmdBean("不合格", "bu he ge"), - OfflineCmdBean("取消", "qu xiao") - )) - } + fun addListenerSprayingManualResulth() = registerBeans(CMDS_SPRAYING_MANUAL_RESULT) - fun addListenerSprayingOCR(){ - // 喷涂OCR页独有关键词 - registerBeans(listOf( - OfflineCmdBean("重拍", "chong pai") - )) - } + fun addListenerSprayingOCR() = registerBeans(CMDS_SPRAYING_OCR) - fun addListenerSprayingResult(){ - // 喷涂结果页独有关键词 - registerBeans(listOf( - OfflineCmdBean("重拍", "chong pai"), - OfflineCmdBean("继续拍摄", "ji xu pai she"), - OfflineCmdBean("人工更正结果", "ren gong geng zheng jie guo"), - OfflineCmdBean("更正", "geng zheng"), - OfflineCmdBean("结束任务", "jie shu ren wu") - )) - } + fun addListenerSprayingResult() = registerBeans(CMDS_SPRAYING_RESULT) // ---- 各页面离开时移除独有关键词(退出/返回为公共关键词,不移除)---- - fun removeListenerList(){ - removeBeans(listOf( - OfflineCmdBean("下一页", "xia yi ye"), - OfflineCmdBean("上一页", "shang yi ye"), - OfflineCmdBean("查看第一项任务", "cha kan di yi xiang ren wu"), - OfflineCmdBean("第一个", "di yi ge"), - OfflineCmdBean("查看第二项任务", "cha kan di er xiang ren wu"), - OfflineCmdBean("第二个", "di er ge"), - OfflineCmdBean("查看第三项任务", "cha kan di san xiang ren wu"), - OfflineCmdBean("第三个", "di san ge"), - OfflineCmdBean("查看第四项任务", "cha kan di si xiang ren wu"), - OfflineCmdBean("第四个", "di si ge"), - OfflineCmdBean("查看第五项任务", "cha kan di wu xiang ren wu"), - OfflineCmdBean("第五个", "di wu ge"), - OfflineCmdBean("查看第六项任务", "cha kan di liu xiang ren wu"), - OfflineCmdBean("第六个", "di liu ge") - )) - } + fun removeListenerList() = removeBeans(CMDS_TASK_LIST) // addListenerFo 无独有关键词,无需对应 remove 方法 - fun removeListenerInspection(){ - removeBeans(listOf( - OfflineCmdBean("驳回", "bo hui"), - OfflineCmdBean("通过", "tong guo"), - OfflineCmdBean("同意", "tong yi") - )) - } + fun removeListenerInspection() = removeBeans(CMDS_INSPECTION) - fun removeListenerSpraying(){ - removeBeans(listOf( - OfflineCmdBean("开始任务", "kai shi ren wu") - )) - } + fun removeListenerSpraying() = removeBeans(CMDS_SPRAYING) - fun removeListenerSprayingFinish(){ - removeBeans(listOf( - OfflineCmdBean("补充照片", "bu chong zhao pian"), - OfflineCmdBean("确认提交", "que ren ti jiao") - )) - } + fun removeListenerSprayingFinish() = removeBeans(CMDS_SPRAYING_FINISH) - fun removeListenerSprayingManualResulth(){ - removeBeans(listOf( - OfflineCmdBean("合格", "he ge"), - OfflineCmdBean("不合格", "bu he ge"), - OfflineCmdBean("取消", "qu xiao") - )) - } + fun removeListenerSprayingManualResulth() = removeBeans(CMDS_SPRAYING_MANUAL_RESULT) - fun removeListenerSprayingOCR(){ - removeBeans(listOf( - OfflineCmdBean("重拍", "chong pai") - )) - } + fun removeListenerSprayingOCR() = removeBeans(CMDS_SPRAYING_OCR) - fun removeListenerSprayingResult(){ - removeBeans(listOf( - OfflineCmdBean("重拍", "chong pai"), - OfflineCmdBean("继续拍摄", "ji xu pai she"), - OfflineCmdBean("人工更正结果", "ren gong geng zheng jie guo"), - OfflineCmdBean("更正", "geng zheng"), - OfflineCmdBean("结束任务", "jie shu ren wu") - )) - } + fun removeListenerSprayingResult() = removeBeans(CMDS_SPRAYING_RESULT) // ---- Inspection 页面关键词 ---- - fun addListenerInspectionResult(){ - registerBeans(listOf( - OfflineCmdBean("重拍照", "chong pai zhao"), - OfflineCmdBean("结束任务", "jie shu ren wu"), - OfflineCmdBean("继续任务", "ji xu ren wu") - )) - } + fun addListenerInspectionResult() = registerBeans(CMDS_INSPECTION_RESULT) - fun removeListenerInspectionResult(){ - removeBeans(listOf( - OfflineCmdBean("重拍照", "chong pai zhao"), - OfflineCmdBean("结束任务", "jie shu ren wu"), - OfflineCmdBean("继续任务", "ji xu ren wu") - )) - } + fun removeListenerInspectionResult() = removeBeans(CMDS_INSPECTION_RESULT) - fun addListenerInspectionMissing(){ - registerBeans(listOf( - OfflineCmdBean("补充单证", "bu chong dan zheng"), - OfflineCmdBean("继续提交", "ji xu ti jiao") - )) - } + fun addListenerInspectionMissing() = registerBeans(CMDS_INSPECTION_MISSING) - fun removeListenerInspectionMissing(){ - removeBeans(listOf( - OfflineCmdBean("补充单证", "bu chong dan zheng"), - OfflineCmdBean("继续提交", "ji xu ti jiao") - )) - } + fun removeListenerInspectionMissing() = removeBeans(CMDS_INSPECTION_MISSING) - fun addListenerInspectionComplete(){ - registerBeans(listOf( - OfflineCmdBean("完成任务", "wan cheng ren wu") - )) - } + fun addListenerInspectionComplete() = registerBeans(CMDS_INSPECTION_COMPLETE) - fun removeListenerInspectionComplete(){ - removeBeans(listOf( - OfflineCmdBean("完成任务", "wan cheng ren wu") - )) - } + fun removeListenerInspectionComplete() = removeBeans(CMDS_INSPECTION_COMPLETE) } diff --git a/app/src/main/java/com/nova/brain/glass/ui/TaskListActivity.kt b/app/src/main/java/com/nova/brain/glass/ui/TaskListActivity.kt index f28acbe..b2549f3 100644 --- a/app/src/main/java/com/nova/brain/glass/ui/TaskListActivity.kt +++ b/app/src/main/java/com/nova/brain/glass/ui/TaskListActivity.kt @@ -24,6 +24,33 @@ class TaskListActivity : override fun fullscreen(): Boolean = true private var pageStartPosition = 0 + companion object { + // 序数词到索引的映射 + private val ORDINAL_INDEX = mapOf( + "第一" to 0, "第二" to 1, "第三" to 2, "第四" to 3, + "第五" to 4, "第六" to 5, "第七" to 6, "第八" to 7, + "第九" to 8, "第十" to 9 + ) + // 单字序数词(口语化)到索引的映射 + private val SHORT_ORDINAL_INDEX = mapOf( + "第一个" to 0, "第一条" to 0, "第一项" to 0, + "第二个" to 1, "第二条" to 1, "第二项" to 1, + "第三个" to 2, "第三条" to 2, "第三项" to 2, + "第四个" to 3, "第四条" to 3, "第四项" to 3, + "第五个" to 4, "第五条" to 4, "第五项" to 4, + "第六个" to 5, "第六条" to 5, "第六项" to 5, + "第七个" to 6, "第七条" to 6, "第七项" to 6, + "第八个" to 7, "第八条" to 7, "第八项" to 7, + "第九个" to 8, "第九条" to 8, "第九项" to 8, + "第十个" to 9, "第十条" to 9, "第十项" to 9 + ) + private val TASK_PREFIXES = listOf("查看", "打开", "处理") + private val TASK_SUFFIXES = listOf("任务", "条任务", "项任务", "个任务") + private val NEXT_PAGE_CMDS = setOf("下一页", "翻页", "查看下一页", "继续翻页", "继续下一页") + private val PREV_PAGE_CMDS = setOf("上一页", "查看上一页", "继续上一页") + private val EXIT_CMDS = setOf("退出", "返回", "退回") + } + override fun initView(savedInstanceState: Bundle?) { super.initView(savedInstanceState) window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) @@ -48,65 +75,34 @@ class TaskListActivity : private val offlineCmdListener = object : OfflineCmdListener { override fun onOfflineCmd(cmd: String) { - runOnUiThread { - when (cmd) { - "退出","返回","退回"->{ - finish() - } - "下一页", "翻页", "查看下一页", "继续翻页", "继续下一页" -> { - "--------------->".log() - toNext() - } - "上一页", "查看上一页", "继续上一页" -> { - toPre() - } - "查看第一条任务", "查看第一项任务", "查看第一个任务", - "第一个", "第一条", "第一项", - "打开第一条任务", "打开第一项任务", "打开第一个任务", - "处理第一条任务", "处理第一项任务", "处理第一个任务" -> { - openVisibleTask(0) - } - "查看第二条任务", "查看第二项任务", "第二个", "第二条", "第二项", - "打开第二条任务", "打开第二项任务", "处理第二条任务", "处理第二项任务" -> { - openVisibleTask(1) - } - "查看第三条任务", "查看第三项任务", "第三个", "第三条", "第三项", - "打开第三条任务", "打开第三项任务", "处理第三条任务", "处理第三项任务" -> { - openVisibleTask(2) - } - "查看第四条任务", "查看第四项任务", "第四个", "第四条", "第四项", - "打开第四条任务", "打开第四项任务", "处理第四条任务", "处理第四项任务" -> { - openVisibleTask(3) - } - "查看第五条任务", "查看第五项任务", "第五个", "第五条", "第五项", - "打开第五条任务", "打开第五项任务", "处理第五条任务", "处理第五项任务" -> { - openVisibleTask(4) - } - "查看第六条任务", "查看第六项任务", "第六个", "第六条", "第六项", - "打开第六条任务", "打开第六项任务", "处理第六条任务", "处理第六项任务" -> { - openVisibleTask(5) - } - "查看第七条任务", "查看第七项任务", "第七个", "第七条", "第七项", - "打开第七条任务", "打开第七项任务", "处理第七条任务", "处理第七项任务" -> { - openVisibleTask(6) - } - "查看第八条任务", "查看第八项任务", "第八个", "第八条", "第八项", - "打开第八条任务", "打开第八项任务", "处理第八条任务", "处理第八项任务" -> { - openVisibleTask(7) - } - "查看第九条任务", "查看第九项任务", "第九个", "第九条", "第九项", - "打开第九条任务", "打开第九项任务", "处理第九条任务", "处理第九项任务" -> { - openVisibleTask(8) - } - "查看第十条任务", "查看第十项任务", "第十个", "第十条", "第十项", - "打开第十条任务", "打开第十项任务", "处理第十条任务", "处理第十项任务" -> { - openVisibleTask(9) - } - } - } + runOnUiThread { dispatchVoiceCmd(cmd) } } } + private fun dispatchVoiceCmd(cmd: String) { + when { + cmd in EXIT_CMDS -> finish() + cmd in NEXT_PAGE_CMDS -> { + "--------------->".log() + toNext() + } + cmd in PREV_PAGE_CMDS -> toPre() + else -> resolveTaskIndex(cmd)?.let { openVisibleTask(it) } + } + } + + /** + * 将语音命令解析为任务序号(0-based),无法识别则返回 null。 + * 支持格式:「第N个/条/项」、「查看/打开/处理 + 第N条/项/个 + 任务(可省)」 + */ + private fun resolveTaskIndex(cmd: String): Int? { + SHORT_ORDINAL_INDEX[cmd]?.let { return it } + val prefix = TASK_PREFIXES.firstOrNull { cmd.startsWith(it) } ?: return null + val body = cmd.removePrefix(prefix) + val ordinalEntry = ORDINAL_INDEX.entries.firstOrNull { body.startsWith(it.key) } ?: return null + return ordinalEntry.value + } + private fun toPre() { val layoutManager = binding.baseRecyclerView.layoutManager as? LinearLayoutManager if (layoutManager != null) { diff --git a/app/src/main/java/com/nova/brain/glass/viewmodel/WelcomeVM.kt b/app/src/main/java/com/nova/brain/glass/viewmodel/WelcomeVM.kt index e2de622..9dba9c1 100644 --- a/app/src/main/java/com/nova/brain/glass/viewmodel/WelcomeVM.kt +++ b/app/src/main/java/com/nova/brain/glass/viewmodel/WelcomeVM.kt @@ -42,18 +42,19 @@ class WelcomeVM : BaseViewModel() { .subscribeOn(Schedulers.io()) .subscribe({ body -> val sb = StringBuilder("SSE 流式响应:\n") - try { - val reader = body.charStream().buffered() - var line: String? - while (reader.readLine().also { line = it } != null) { - val l = line!! - if (l.isNotEmpty()) { - sb.appendLine(l) - result.postValue(sb.toString()) + body.charStream().buffered().use { reader -> + try { + var line: String? + while (reader.readLine().also { line = it } != null) { + val l = line!! + if (l.isNotEmpty()) { + sb.appendLine(l) + result.postValue(sb.toString()) + } } + } catch (e: Exception) { + result.postValue("SSE 读取异常: ${e.message}") } - } catch (e: Exception) { - result.postValue("SSE 读取异常: ${e.message}") } }, { e -> result.postValue("SSE 失败: ${e.message}") diff --git a/base/build.gradle b/base/build.gradle index e3a4d55..62638c9 100644 --- a/base/build.gradle +++ b/base/build.gradle @@ -85,8 +85,14 @@ afterEvaluate { allowInsecureProtocol true url("http://xuqinmin.com.cn:8081/repository/android-releases/") credentials { - username = "admin" - password = "xuqinmin1022" + // 从 local.properties 读取,避免凭据提交到版本控制 + def props = new Properties() + def localPropertiesFile = rootProject.file("local.properties") + if (localPropertiesFile.exists()) { + localPropertiesFile.withInputStream { props.load(it) } + } + username = props.getProperty("nexus.username", "") + password = props.getProperty("nexus.password", "") } } } diff --git a/base/src/main/java/com/xuqm/base/common/AppManager.java b/base/src/main/java/com/xuqm/base/common/AppManager.java index 0f1b19d..2774813 100644 --- a/base/src/main/java/com/xuqm/base/common/AppManager.java +++ b/base/src/main/java/com/xuqm/base/common/AppManager.java @@ -65,13 +65,10 @@ public class AppManager { /** * finish最后一个之外的所有页面 - * - * @return */ public void logout() { - if (activityStack.size() < 1) - return; - for (int i = 0; i < activityStack.size() - 1; i++) { + // 原 for 循环在 popActivity 后 size 动态缩小,导致只清理约一半;改为 while 确保全部清理 + while (activityStack.size() > 1) { Activity activity = activityStack.firstElement(); if (activity == null) break; popActivity(activity); diff --git a/base/src/main/java/com/xuqm/base/di/module/NetworkModule.java b/base/src/main/java/com/xuqm/base/di/module/NetworkModule.java index 543bdb5..2e0b1ab 100644 --- a/base/src/main/java/com/xuqm/base/di/module/NetworkModule.java +++ b/base/src/main/java/com/xuqm/base/di/module/NetworkModule.java @@ -25,16 +25,16 @@ import retrofit2.converter.gson.GsonConverterFactory; @Module public class NetworkModule { - private String BaseUrl = "https://xuqinmin.com/"; - private final List interceptor = new ArrayList<>(); + private final String BaseUrl; + private final List interceptor; public NetworkModule() { + this("https://xuqinmin.com/"); } - public NetworkModule(String baseUrl, Interceptor... interceptor) { + public NetworkModule(String baseUrl, Interceptor... interceptors) { BaseUrl = baseUrl; - this.interceptor.clear(); - this.interceptor.addAll(Arrays.asList(interceptor)); + interceptor = interceptors.length > 0 ? Arrays.asList(interceptors) : new ArrayList<>(); } @Provides @@ -59,10 +59,8 @@ public class NetworkModule { .readTimeout(60, TimeUnit.SECONDS) .writeTimeout(60, TimeUnit.SECONDS); // builder.addNetworkInterceptor(httpLoggingInterceptor); - if (0 != interceptor.size()) { - for (Interceptor interceptor1 : this.interceptor) { - builder.addInterceptor(interceptor1); - } + for (Interceptor interceptor1 : this.interceptor) { + builder.addInterceptor(interceptor1); } return builder.cookieJar(persistentCookieJar) diff --git a/base/src/main/java/com/xuqm/base/dialog/loading/LoadingDialog.java b/base/src/main/java/com/xuqm/base/dialog/loading/LoadingDialog.java index e28d83b..f377fb6 100644 --- a/base/src/main/java/com/xuqm/base/dialog/loading/LoadingDialog.java +++ b/base/src/main/java/com/xuqm/base/dialog/loading/LoadingDialog.java @@ -119,7 +119,7 @@ public class LoadingDialog { try { mDialog.dismiss(); } catch (Exception e) { - // TODO: handle exception + LogHelper.e(LoadingDialog.class.getSimpleName(), e); } } }