fix(cw): prevent double AudioRecord when toggling capture
CwDecodeScreen 的 LaunchedEffect 原先用内层 launch{} 启动音频采集。
isListening 在权限授予后由 false->true->(授予回调再次置 true), 加上
LaunchedEffect(isListening, permissionGranted) 的双 key 重启, 会造成
前一个 audioFlow().collect 尚未取消、新的又启动 —— 两个 AudioRecord
同时录音, 内存翻倍、音频混叠, 是低内存机 OOM 崩溃的实锤级嫌疑。
改为在 LaunchedEffect 协程体内直接 collect (取消时随父协程及时停止),
并保持 (isListening, permissionGranted) 双 key 以正确处理权限授予后
需要重启采集的情形。
同时清理不再使用的 kotlinx.coroutines.launch import。
验证: :feature:cw:compileDebugKotlin => BUILD SUCCESSFUL
This commit is contained in:
1 parent
c374058e1d
commit
e0405b541f
1 file changed
+11
-12
@@ -65,7 +65,6 @@ import androidx.compose.ui.unit.sp
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.rtbishop.look4sat.core.domain.repository.IContainerProvider
|
||||
import com.rtbishop.look4sat.core.presentation.R as CoreR
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* Full-page CW decoder backed by DeepCW.
|
||||
@@ -110,19 +109,19 @@ fun CwDecodeScreen(navigateUp: () -> Unit = {}) {
|
||||
if (granted) isListening = true
|
||||
}
|
||||
|
||||
// Capture runs only while listening; cancelling the effect stops the mic.
|
||||
// Capture runs only while listening. Keyed on both listening state and
|
||||
// permission so granting the permission mid-flow restarts collection
|
||||
// (isListening may already be true when the launcher returns).
|
||||
LaunchedEffect(isListening, permissionGranted) {
|
||||
if (!isListening || !permissionGranted) return@LaunchedEffect
|
||||
launch {
|
||||
audioCapture.audioFlow().collect { chunk ->
|
||||
decoder.processBuffer(chunk, audioCapture.sampleRate)
|
||||
waterfall.pushSamples(chunk, audioCapture.sampleRate)
|
||||
}
|
||||
if (!isListening) return@LaunchedEffect
|
||||
if (!permissionGranted) {
|
||||
permissionLauncher.launch(Manifest.permission.RECORD_AUDIO)
|
||||
return@LaunchedEffect
|
||||
}
|
||||
audioCapture.audioFlow().collect { chunk ->
|
||||
decoder.processBuffer(chunk, audioCapture.sampleRate)
|
||||
waterfall.pushSamples(chunk, audioCapture.sampleRate)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(permissionGranted) {
|
||||
if (permissionGranted) isListening = true
|
||||
}
|
||||
|
||||
DisposableEffect(Unit) {
|
||||
|
||||
Reference in new issue
Block a user