Android Studio:While循环冻结应用程序 [英] Android Studio: While Loop Freezing Application

查看:148
本文介绍了Android Studio:While循环冻结应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My code on an app in Android Studio, consisting of a start/stop button for recording audio using AudioRecord and then outputting that audio data to a text view, works great when done once. If I repeatedly click the button, it works too. However, if I put it in a while loop, the app freezes (only the app freezes; same result on an emulator and a real smartphone). I believe I've found that it doesn't have anything to do with AudioRecord, or putting the loop in the button listener or putting it in the method called from the listener, or starting and stopping recording in the called method as opposed to the listener, or even lambda expressions or anything. Without the while loop it works fine; with it, it freezes. But I need to get the audio data continuously. Help is much appreciated. My abbreviated code:

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();
    }
}

推荐答案

应用程序挂起的原因是Android具有以下UI线程的概念:简而言之,一个呈现UI,负责用户输入等的线程.为了确保您的应用不会变慢,您需要能够在每16ms窗口中以60fps的速度进行渲染.因此,如果您超载UI线程(例如在大循环/IO中)-系统将无法呈现UI,请及时响应事件,因此应用程序将冻结.

The reason the application hangs is that Android has this concept of UI Thread: In short a thread that renders UI, responsible for user input, etc To make sure that your app doesn't feel slow you need to be able to render in every 16ms windows for 60fps. Thus, if you overload UI thread (like in a big loop / IO) - the system won't be able to render UI, respond to the events in time, so the app will freeze.

为避免这种情况,您需要使数据异步.最好的选择是放入服务.GitHub上有很多示例,这是一个很好的示例:

To avoid that you need to get data async. The best option will be to put into a Service. There are many example on the GitHub, here is a good one:

https://github.com/dkim0419/SoundRecorder

RecordingService例子

这篇关于Android Studio:While循环冻结应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆