Discuz! BBS

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 353|回复: 1

系统不响应myAudioRecord.stopRecord()

[复制链接]

465

主题

640

帖子

3734

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3734
发表于 2025-11-19 04:40:02 | 显示全部楼层 |阅读模式
根据你提供的测试代码,问题出现在 myAudioRecord.doRecord() 阻塞了测试线程,导致后续的 stopRecord() 无法执行。以下是改进建议:
问题分析
myAudioRecord.doRecord() 在主线程中执行,可能是阻塞式的调用
测试线程被阻塞后,无法继续执行后续的停止录音逻辑
需要将录音操作放到后台线程执行
改进方案
方案一:使用多线程执行录音
  1. @Test
  2. public void testRecordAndStop() {
  3.     Log.d(tag, "testRecordAndStop");

  4.     // 在新线程中执行录音
  5.     Thread recordThread = new Thread(() -> {
  6.         myAudioRecord.doRecord();
  7.     });
  8.     recordThread.start();

  9.     try {
  10.         // 等待一段时间让录音开始
  11.         Thread.sleep(5000);
  12.         Log.d(tag, "testRecordAndStop: stopping");

  13.         // 停止录音
  14.         myAudioRecord.isRecording = false;
  15.         myAudioRecord.stopRecord();
  16.         
  17.         // 等待录音线程结束
  18.         recordThread.join(3000); // 最多等待3秒

  19.     } catch(Exception e){
  20.         Log.e(tag, "Exception occurred: " + e.getMessage());
  21.     }

  22.     // 验证录音文件
  23.     String testFilePath = myAudioRecord.filePath;
  24.     Log.i(tag, "testRecordAndStop: filePath=" + testFilePath);
  25.     assertTrue("File should exist and have content", new File(testFilePath).length() > 0);
  26. }
复制代码
方案二:优化 MyAudioRecord 类
建议修改 MyAudioRecord 类中的 doRecord() 方法,使其支持异步执行
  1. // 在 MyAudioRecord 类中添加异步录音方法
  2. public void startRecordAsync() {
  3.     Thread recordThread = new Thread(() -> {
  4.         doRecord();
  5.     });
  6.     recordThread.setDaemon(true); // 设置为守护线程
  7.     recordThread.start();
  8. }
复制代码
然后在测试中使用:
  1. @Test
  2. public void testRecordAndStop() {
  3.     Log.d(tag, "testRecordAndStop");

  4.     // 异步开始录音
  5.     myAudioRecord.startRecordAsync();

  6.     try {
  7.         Thread.sleep(5000); // 录音5秒
  8.         Log.d(tag, "testRecordAndStop: stopping");

  9.         myAudioRecord.isRecording = false;
  10.         myAudioRecord.stopRecord();

  11.         Thread.sleep(1000); // 给一些时间完成停止操作

  12.     } catch(Exception e){
  13.         Log.e(tag, "Exception occurred: " + e.getMessage());
  14.     }

  15.     String testFilePath = myAudioRecord.filePath;
  16.     Log.i(tag, "testRecordAndStop: filePath=" + testFilePath);
  17.     assertTrue("File should exist and have content", new File(testFilePath).length() > 0);
  18. }
复制代码
关键改进点
避免阻塞测试线程:将 doRecord() 放到单独线程执行
正确同步:使用 join() 或适当的等待机制确保线程协调
优雅停止:通过 isRecording 标志位控制录音循环
超时处理:添加合理的超时机制防止测试hang住


回复

使用道具 举报

465

主题

640

帖子

3734

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3734
 楼主| 发表于 2025-11-19 04:42:29 | 显示全部楼层
守护线程详解
基本概念
守护线程(Daemon Thread):是一种在后台运行的线程,当程序中所有非守护线程结束时,JVM会自动退出,不会等待守护线程完成
用户线程(User Thread):普通的线程,默认都是用户线程,JVM会等待所有用户线程执行完毕才退出
主要特点
生命周期依赖性
守护线程会随着所有用户线程的终止而自动终止
不会阻止JVM的关闭过程
适用场景
后台服务任务(如垃圾回收、内存监控)
日志记录、数据备份等辅助功能
在recordThread.setDaemon(true)中,适合用于录音这种可能会持续运行的后台任务
设置时机
必须在recordThread.start()之前调用setDaemon(true)
否则会抛出IllegalThreadStateException异常
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|DiscuzX

GMT+8, 2026-2-4 12:02 , Processed in 0.011101 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表