refactor(common): 优化崩溃处理器和离线命令服务

- 移除未使用的 FileNotFoundException 导入
- 修复 CrashHandler 单例模式的双重检查锁定实现
- 使用 try-with-resources 语句简化文件流管理
- 添加详细的崩溃日志写入错误日志记录

- 重构 OfflineCmdServiceHelper 使用 CopyOnWriteArrayList 替代
- 提取各页面语音命令为常量列表避免重复创建对象
- 简化页面语音命令注册和移除方法的实现逻辑

- 重构 TaskListActivity 语音命令分发逻辑
- 使用映射表和解析函数替代大量重复的条件判断
- 提取语音命令常量配置便于维护

- 在 WelcomeVM 中使用 try-with-resources 管理资源
- 修改 NetworkModule 构造函数参数命名规范
- 修复 AppManager logout 方法中的循环清理逻辑
- 从本地属性文件读取仓库认证凭据避免提交到版本控制
这个提交包含在:
徐勤民 2026-04-15 18:21:00 +08:00
父节点 16378820c8
当前提交 c77b59cee4
共有 8 个文件被更改,包括 168 次插入321 次删除

查看文件

@ -6,7 +6,6 @@ import android.os.SystemClock;
import android.util.Log; import android.util.Log;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
@ -51,7 +50,9 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler {
public static CrashHandler getInstance() { public static CrashHandler getInstance() {
if (mCrashHandler == null) { if (mCrashHandler == null) {
synchronized (CrashHandler.class) { synchronized (CrashHandler.class) {
mCrashHandler = new CrashHandler(); if (mCrashHandler == null) {
mCrashHandler = new CrashHandler();
}
} }
} }
return mCrashHandler; return mCrashHandler;
@ -135,17 +136,11 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler {
if (!dir.exists()) { if (!dir.exists()) {
dir.mkdir(); dir.mkdir();
} }
FileOutputStream fos = null; try (FileOutputStream fos = new FileOutputStream(path + fileName, true)) {
try {
fos = new FileOutputStream(path + fileName, true);
fos.write(text.getBytes()); fos.write(text.getBytes());
fos.flush(); fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); Log.e(TAG, "写入崩溃日志失败: " + fileName, e);
} }
return fileName; return fileName;
} }

查看文件

@ -1,92 +1,81 @@
package com.nova.brain.glass.helper 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.open.sdk.GlassSdk
import com.rokid.security.glass3.sdk.base.data.offlineCmd.bean.VoiceAction 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.glass3.sdk.base.data.offlineCmd.listener.IVoiceCallback
import com.rokid.security.system.server.offlineCmd.IOfflineCmdService import com.rokid.security.system.server.offlineCmd.IOfflineCmdService
import com.xuqm.base.common.LogHelper 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) data class OfflineCmdBean(val text: String, val pinyin: String)
object OfflineCmdServiceHelper { object OfflineCmdServiceHelper {
private var listenerList = mutableListOf<OfflineCmdListener>() // CopyOnWriteArrayList遍历时不需要加锁,add/remove 不会引发 ConcurrentModificationException
private val initExecutor = Executors.newSingleThreadExecutor() private val listenerList = CopyOnWriteArrayList<OfflineCmdListener>()
@Volatile
private var initialized = false
@Volatile
private var initializing = false
private val list = mutableListOf<OfflineCmdBean>().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( private val COMMON_CMDS = listOf(
OfflineCmdBean("退出", "tui chu"), OfflineCmdBean("退出", "tui chu"),
OfflineCmdBean("返回", "fan hui") 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 var service: IOfflineCmdService? = null
private fun registerBeans(beans: List<OfflineCmdBean>) { private fun registerBeans(beans: List<OfflineCmdBean>) {
@ -131,24 +120,8 @@ object OfflineCmdServiceHelper {
this.listenerList.remove(listener) this.listenerList.remove(listener)
} }
fun addListenerList(){ fun addListenerList() {
// 任务列表独有关键词(通用关键词已在 init 注册,无需重复) registerBeans(CMDS_TASK_LIST)
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 removeAll(){ fun removeAll(){
@ -158,167 +131,48 @@ object OfflineCmdServiceHelper {
// addListenerFo: 无独有关键词,通用关键词已在 init 注册 // addListenerFo: 无独有关键词,通用关键词已在 init 注册
fun addListenerFo(){ } fun addListenerFo(){ }
fun addListenerInspection(){ fun addListenerInspection() = registerBeans(CMDS_INSPECTION)
// 巡检页独有关键词
registerBeans(listOf(
OfflineCmdBean("驳回", "bo hui"),
OfflineCmdBean("通过", "tong guo"),
OfflineCmdBean("同意", "tong yi")
))
}
fun addListenerSpraying(){ fun addListenerSpraying() = registerBeans(CMDS_SPRAYING)
// 喷涂页独有关键词
registerBeans(listOf(
OfflineCmdBean("开始任务", "kai shi ren wu")
))
}
fun addListenerSprayingFinish(){ fun addListenerSprayingFinish() = registerBeans(CMDS_SPRAYING_FINISH)
// 喷涂完成页独有关键词
registerBeans(listOf(
OfflineCmdBean("补充照片", "bu chong zhao pian"),
OfflineCmdBean("确认提交", "que ren ti jiao")
))
}
fun addListenerSprayingManualResulth(){ fun addListenerSprayingManualResulth() = registerBeans(CMDS_SPRAYING_MANUAL_RESULT)
// 喷涂人工更正页独有关键词
registerBeans(listOf(
OfflineCmdBean("合格", "he ge"),
OfflineCmdBean("不合格", "bu he ge"),
OfflineCmdBean("取消", "qu xiao")
))
}
fun addListenerSprayingOCR(){ fun addListenerSprayingOCR() = registerBeans(CMDS_SPRAYING_OCR)
// 喷涂OCR页独有关键词
registerBeans(listOf(
OfflineCmdBean("重拍", "chong pai")
))
}
fun addListenerSprayingResult(){ fun addListenerSprayingResult() = registerBeans(CMDS_SPRAYING_RESULT)
// 喷涂结果页独有关键词
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 removeListenerList(){ fun removeListenerList() = removeBeans(CMDS_TASK_LIST)
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")
))
}
// addListenerFo 无独有关键词,无需对应 remove 方法 // addListenerFo 无独有关键词,无需对应 remove 方法
fun removeListenerInspection(){ fun removeListenerInspection() = removeBeans(CMDS_INSPECTION)
removeBeans(listOf(
OfflineCmdBean("驳回", "bo hui"),
OfflineCmdBean("通过", "tong guo"),
OfflineCmdBean("同意", "tong yi")
))
}
fun removeListenerSpraying(){ fun removeListenerSpraying() = removeBeans(CMDS_SPRAYING)
removeBeans(listOf(
OfflineCmdBean("开始任务", "kai shi ren wu")
))
}
fun removeListenerSprayingFinish(){ fun removeListenerSprayingFinish() = removeBeans(CMDS_SPRAYING_FINISH)
removeBeans(listOf(
OfflineCmdBean("补充照片", "bu chong zhao pian"),
OfflineCmdBean("确认提交", "que ren ti jiao")
))
}
fun removeListenerSprayingManualResulth(){ fun removeListenerSprayingManualResulth() = removeBeans(CMDS_SPRAYING_MANUAL_RESULT)
removeBeans(listOf(
OfflineCmdBean("合格", "he ge"),
OfflineCmdBean("不合格", "bu he ge"),
OfflineCmdBean("取消", "qu xiao")
))
}
fun removeListenerSprayingOCR(){ fun removeListenerSprayingOCR() = removeBeans(CMDS_SPRAYING_OCR)
removeBeans(listOf(
OfflineCmdBean("重拍", "chong pai")
))
}
fun removeListenerSprayingResult(){ fun removeListenerSprayingResult() = removeBeans(CMDS_SPRAYING_RESULT)
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")
))
}
// ---- Inspection 页面关键词 ---- // ---- Inspection 页面关键词 ----
fun addListenerInspectionResult(){ fun addListenerInspectionResult() = registerBeans(CMDS_INSPECTION_RESULT)
registerBeans(listOf(
OfflineCmdBean("重拍照", "chong pai zhao"),
OfflineCmdBean("结束任务", "jie shu ren wu"),
OfflineCmdBean("继续任务", "ji xu ren wu")
))
}
fun removeListenerInspectionResult(){ fun removeListenerInspectionResult() = removeBeans(CMDS_INSPECTION_RESULT)
removeBeans(listOf(
OfflineCmdBean("重拍照", "chong pai zhao"),
OfflineCmdBean("结束任务", "jie shu ren wu"),
OfflineCmdBean("继续任务", "ji xu ren wu")
))
}
fun addListenerInspectionMissing(){ fun addListenerInspectionMissing() = registerBeans(CMDS_INSPECTION_MISSING)
registerBeans(listOf(
OfflineCmdBean("补充单证", "bu chong dan zheng"),
OfflineCmdBean("继续提交", "ji xu ti jiao")
))
}
fun removeListenerInspectionMissing(){ fun removeListenerInspectionMissing() = removeBeans(CMDS_INSPECTION_MISSING)
removeBeans(listOf(
OfflineCmdBean("补充单证", "bu chong dan zheng"),
OfflineCmdBean("继续提交", "ji xu ti jiao")
))
}
fun addListenerInspectionComplete(){ fun addListenerInspectionComplete() = registerBeans(CMDS_INSPECTION_COMPLETE)
registerBeans(listOf(
OfflineCmdBean("完成任务", "wan cheng ren wu")
))
}
fun removeListenerInspectionComplete(){ fun removeListenerInspectionComplete() = removeBeans(CMDS_INSPECTION_COMPLETE)
removeBeans(listOf(
OfflineCmdBean("完成任务", "wan cheng ren wu")
))
}
} }

查看文件

@ -24,6 +24,33 @@ class TaskListActivity :
override fun fullscreen(): Boolean = true override fun fullscreen(): Boolean = true
private var pageStartPosition = 0 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?) { override fun initView(savedInstanceState: Bundle?) {
super.initView(savedInstanceState) super.initView(savedInstanceState)
window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
@ -48,65 +75,34 @@ class TaskListActivity :
private val offlineCmdListener = object : OfflineCmdListener { private val offlineCmdListener = object : OfflineCmdListener {
override fun onOfflineCmd(cmd: String) { override fun onOfflineCmd(cmd: String) {
runOnUiThread { runOnUiThread { dispatchVoiceCmd(cmd) }
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)
}
}
}
} }
} }
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() { private fun toPre() {
val layoutManager = binding.baseRecyclerView.layoutManager as? LinearLayoutManager val layoutManager = binding.baseRecyclerView.layoutManager as? LinearLayoutManager
if (layoutManager != null) { if (layoutManager != null) {

查看文件

@ -42,18 +42,19 @@ class WelcomeVM : BaseViewModel() {
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.subscribe({ body -> .subscribe({ body ->
val sb = StringBuilder("SSE 流式响应:\n") val sb = StringBuilder("SSE 流式响应:\n")
try { body.charStream().buffered().use { reader ->
val reader = body.charStream().buffered() try {
var line: String? var line: String?
while (reader.readLine().also { line = it } != null) { while (reader.readLine().also { line = it } != null) {
val l = line!! val l = line!!
if (l.isNotEmpty()) { if (l.isNotEmpty()) {
sb.appendLine(l) sb.appendLine(l)
result.postValue(sb.toString()) result.postValue(sb.toString())
}
} }
} catch (e: Exception) {
result.postValue("SSE 读取异常: ${e.message}")
} }
} catch (e: Exception) {
result.postValue("SSE 读取异常: ${e.message}")
} }
}, { e -> }, { e ->
result.postValue("SSE 失败: ${e.message}") result.postValue("SSE 失败: ${e.message}")

查看文件

@ -85,8 +85,14 @@ afterEvaluate {
allowInsecureProtocol true allowInsecureProtocol true
url("http://xuqinmin.com.cn:8081/repository/android-releases/") url("http://xuqinmin.com.cn:8081/repository/android-releases/")
credentials { credentials {
username = "admin" // local.properties
password = "xuqinmin1022" 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", "")
} }
} }
} }

查看文件

@ -65,13 +65,10 @@ public class AppManager {
/** /**
* finish最后一个之外的所有页面 * finish最后一个之外的所有页面
*
* @return
*/ */
public void logout() { public void logout() {
if (activityStack.size() < 1) // for 循环在 popActivity size 动态缩小导致只清理约一半改为 while 确保全部清理
return; while (activityStack.size() > 1) {
for (int i = 0; i < activityStack.size() - 1; i++) {
Activity activity = activityStack.firstElement(); Activity activity = activityStack.firstElement();
if (activity == null) break; if (activity == null) break;
popActivity(activity); popActivity(activity);

查看文件

@ -25,16 +25,16 @@ import retrofit2.converter.gson.GsonConverterFactory;
@Module @Module
public class NetworkModule { public class NetworkModule {
private String BaseUrl = "https://xuqinmin.com/"; private final String BaseUrl;
private final List<Interceptor> interceptor = new ArrayList<>(); private final List<Interceptor> interceptor;
public NetworkModule() { public NetworkModule() {
this("https://xuqinmin.com/");
} }
public NetworkModule(String baseUrl, Interceptor... interceptor) { public NetworkModule(String baseUrl, Interceptor... interceptors) {
BaseUrl = baseUrl; BaseUrl = baseUrl;
this.interceptor.clear(); interceptor = interceptors.length > 0 ? Arrays.asList(interceptors) : new ArrayList<>();
this.interceptor.addAll(Arrays.asList(interceptor));
} }
@Provides @Provides
@ -59,10 +59,8 @@ public class NetworkModule {
.readTimeout(60, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS); .writeTimeout(60, TimeUnit.SECONDS);
// builder.addNetworkInterceptor(httpLoggingInterceptor); // builder.addNetworkInterceptor(httpLoggingInterceptor);
if (0 != interceptor.size()) { for (Interceptor interceptor1 : this.interceptor) {
for (Interceptor interceptor1 : this.interceptor) { builder.addInterceptor(interceptor1);
builder.addInterceptor(interceptor1);
}
} }
return builder.cookieJar(persistentCookieJar) return builder.cookieJar(persistentCookieJar)

查看文件

@ -119,7 +119,7 @@ public class LoadingDialog {
try { try {
mDialog.dismiss(); mDialog.dismiss();
} catch (Exception e) { } catch (Exception e) {
// TODO: handle exception LogHelper.e(LoadingDialog.class.getSimpleName(), e);
} }
} }
} }