什么是一个很好的方式停止在android系统线程 [英] what is a good way to stop a thread in android

查看:220
本文介绍了什么是一个很好的方式停止在android系统线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图直通从麦克风到扬声器获得的输入(目标是能够实时在未来执行音频处理)。这是code:

I am trying to passthrough the input obtained from the microphone to the speaker (the goal is to be able to perform audio processing in real time in the future). This is the code:

public class MainActivity extends Activity {
    AudioManager am = null;
    AudioRecord record =null;
    AudioTrack track =null;
    final int SAMPLE_FREQUENCY = 44100;
    final int SIZE_OF_RECORD_ARRAY = 1024;  // 1024 ORIGINAL
    final int WAV_SAMPLE_MULTIPLICATION_FACTOR = 1;
    int i= 0;
    boolean isPlaying = true;
    class MyThread extends Thread{
        @Override
        public void run(){
            recordAndPlay();
        }
    }

    MyThread newThread;

    private void init() {
        int min = AudioRecord.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
        record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO,
                                 AudioFormat.ENCODING_PCM_16BIT, min);
        int maxJitter = AudioTrack.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
        track = new AudioTrack(AudioManager.MODE_IN_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO,
                               AudioFormat.ENCODING_PCM_16BIT, maxJitter, AudioTrack.MODE_STREAM);
     }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setVolumeControlStream(AudioManager.MODE_IN_COMMUNICATION);
        init();
        newThread = new MyThread();
        newThread.start();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    private void recordAndPlay() {
        short[] lin = new short[SIZE_OF_RECORD_ARRAY];
        int num = 0;
        am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
        am.setMode(AudioManager.MODE_IN_COMMUNICATION);
        record.startRecording();
        track.play();
        while (true) {
            num = record.read(lin, 0, SIZE_OF_RECORD_ARRAY);
            for(i=0;i<lin.length;i++)
                lin[i] *= WAV_SAMPLE_MULTIPLICATION_FACTOR; 
            track.write(lin, 0, num);
        }
    }

    public void passStop(View view){
        Button playBtn = (Button) findViewById(R.id.playBtn);  
        // /*
        if(!isPlaying){
            record.startRecording();
            track.play();
            isPlaying = true;
            playBtn.setText("Pause");
        }
        else{
           record.stop();
           track.pause();
           isPlaying=false;
           playBtn.setText("Pass through");
        }
        // */
    }

/*
    @SuppressWarnings("deprecation")
    @Override
    public void onDestroy(){
        newThread.stop();
    }
    */

    @Override
    protected void onDestroy() {
        android.os.Process.killProcess(android.os.Process.myPid());
        // killProcess(android.os.Process.myPid());
    }
}  

梗概:结果
,而(真){} recordAndPlay无限循环()功能将继续从麦克风和输出原始音频采样原始样品到扬声器。 recordAndPlay()是从一个线程在的onCreate()函数开始调用。因此,它即开始发送麦克风输入到扬声器的程序启动(当然实际上经过几秒钟的滞后性,但是我觉得在这不可避免的延迟)。我也有一个按钮,可以暂停和恢复此通过。现在,如果线程没有停止,闯关继续,甚至当我退出应用程序或应用程序失去焦点时(因此,即使当手机桌面上它一直在做直通)。

Brief overview:
The while(true) {} infinite loop in recordAndPlay() function continuously reads raw audio samples from the microphone and outputs the raw samples to the speaker. recordAndPlay() is called from a Thread started in the onCreate() function. So it starts sending the input on the microphone to the speaker as soon as the program starts (well actually after a few seconds lag but I think this latency in unavoidable). I also have a button that can pause and resume this pass through. Now if the Thread is not stopped, the pass through continues even when I exit the application or the application looses focus (so even when the phone is on the desktop it keeps doing the passthrough).

@SuppressWarnings("deprecation")
@Override
public void onDestroy(){
    newThread.stop();
}  

这code使应用程序崩溃退出(为什么?),所以我用

This code causes the app to crash on exit (Why?) so I used

@Override
protected void onDestroy() {
    android.os.Process.killProcess(android.os.Process.myPid());
    // killProcess(android.os.Process.myPid());
}  

这是我在计算器发现某处(我忘了在哪里)。这似乎做什么,我想现在,但我想知道这是否是正确的方法停止线程与否。它做什么,我需要的,也就是说,它停止直通当我退出应用程序,但我不知道究竟是什么killProcess()函数做我的应用程序的整体,如果是停止线程的最好方式,我开始我自己。

that I found somewhere in stackoverflow (I forgot where). It seems to do what I want for now, but I want know if this is the proper way to stop the Thread or not. It does what I need, that is, it stops the passthrough when I exit the application, but I am not sure what exactly the killProcess() function does to my application overall, and if it is the best way to stop a Thread that I started myself.

另外,我可以,如果我离开我的应用程序(或松散的焦点吧),而直通被暂停获得同样的效果。但我认为,这意味着线程仍在运行,这意味着无限循环也连续运行也是如此。它是一个好主意,要做到这一点,那就是刚刚离开线程运行,只要我的总体方案是为了表现我所想要的?如果我有很多线程或其他后台进程运行的是什么?可以在将来这种做法导致内存问题,如果应用增长得太大?

Also, I can get the same effect if I exit my application (or loose focus to it) while the passthrough is being paused. But I assume this means the Thread is still running which means the infinite loop is also continuously running as well. Is it a good idea to do this, that is, just leave the Thread running, as long as my overall program is behaving as I want it to? What if I have lots of Threads or other background processes running? Can this practice cause memory problems in the future if the app grows too big?

推荐答案

线程应该定期检查其环部分 shouldTerminate 标志,则​​只需设置从UI线程这个标志(可选)等待线程终止优雅。不要忘了挥发性或适当的场同步。

Threads should periodically check for some shouldTerminate flag in their loop, then just set this flag from UI thread and (optionally) wait until thread terminate gracefully. Don't forget volatile or proper field synchronization.

这篇关于什么是一个很好的方式停止在android系统线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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