【问题标题】:Android Studio: While Loop Freezing ApplicationAndroid Studio:While 循环冻结应用程序
【发布时间】:2019-01-19 04:40:29
【问题描述】:

我在 Android Studio 中的应用程序上的代码包含一个开始/停止按钮,用于使用 AudioRecord 录制音频,然后将该音频数据输出到文本视图,一次完成后效果很好。如果我反复单击该按钮,它也可以工作。但是,如果我把它放在一个 while 循环中,应用程序会冻结(只有应用程序会冻结;在模拟器和真正的智能手机上的结果相同)。我相信我发现它与 AudioRecord 没有任何关系,或者将循环放在按钮侦听器中或将其放在从侦听器调用的方法中,或者在调用的方法中开始和停止录制而不是侦听器,甚至 lambda 表达式或任何东西。没有while循环它工作正常;有了它,它就会冻结。但我需要不断地获取音频数据。非常感谢您的帮助。我的缩写代码:

public class MainActivity extends AppCompatActivity {

    public static final int SAMPLE_RATE = 16000;

    private AudioRecord recorder;
    private Button btn;
    private TextView txtView;
    private boolean isRecording = false;
    private short[] buffer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn = (Button) findViewById(R.id.btn);
        txtView = (TextView) findViewById(R.id.TextView);

        initializeRecorder();

        btn.setOnClickListener(e -> {
            if (!isRecording) {
                btn.setText("Stop");
                isRecording = true;
                recorder.startRecording();
                record();
            }
            else {
                btn.setText("Start");
                isRecording = false;
                recorder.stop();
            }
        });
    }

    private void initializeRecorder() {
        int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, 
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT);
        buffer = new short[bufferSize];
        recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 
                SAMPLE_RATE,
                AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, 
                bufferSize);
    }

    private void record() {
        int readSize;

        while (isRecording) { // This is the loop causing trouble

            readSize = recorder.read(buffer, 0, buffer.length);
            // Perform calculations on this data and output to txtView, 
            // like:

            txtView.setText(Integer.toString(readSize));

            // BTW, I know I'm not saving this audio to a file; that's on 
            // purpose. I just need this data.
        }
    }

    @Override
    public void onDestroy() {
        recorder.release();
        super.onDestroy();
    }
}

【问题讨论】:

  • 异步获取数据-使用线程或将其放入服务中。

标签: java android android-studio audiorecord


【解决方案1】:

应用挂掉的原因是Android有这个UI线程的概念:简单来说就是渲染UI的线程,负责用户输入等 为了确保您的应用程序不会感觉缓慢,您需要能够在每 16 毫秒的窗口中以 60 fps 的速度进行渲染。因此,如果你超载 UI 线程(比如在一个大循环/IO 中) - 系统将无法呈现 UI,及时响应事件,因此应用程序将冻结。

为避免这种情况,您需要异步获取数据。最好的选择是投入服务。 GitHub上有很多例子,这里有一个很好的:

https://github.com/dkim0419/SoundRecorder

RecordingService example

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 2021-09-24
    • 2015-06-05
    • 2017-10-18
    • 2023-04-08
    • 1970-01-01
    相关资源
    最近更新 更多