Android Studio: While Loop Freezing Application

只谈情不闲聊 提交于 2021-01-29 08:13:47

问题


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

回答1:


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.

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 example



来源:https://stackoverflow.com/questions/54264125/android-studio-while-loop-freezing-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!