变量的值意外变化:Java / Android Studio

时间:2017-09-09 02:05:22

标签: java android multithreading

我在Android工作室制作应用程序,使用麦克风录制声音并同时将其转换为另一个线程上的分贝值。我需要在调用stopRecord函数时停止进程,因此我想在stopRecord函数中停止该线程。我正在使用一个静态类变量,当调用stopRecord时,我将其值设置为“1”。默认情况下,变量的值为“0”,在这种情况下,线程必须继续在循环中运行。但是,即使在调用runnable的Run方法之前,变量的值总是意外地设置为“1”,这很明显,如果您运行该文件并看到Log.i。结果,甚至没有输入runnable的run()中的循环,并且runnable只运行一次。 我真的不知道为什么价值在变化,任何帮助都会受到高度赞赏。

package com.example.rohanbs.soundtest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import android.view.View;
import android.os.Handler;
import android.util.Log;
import android.media.MediaRecorder;

public class MainActivity extends AppCompatActivity {

    TextView mStatusView;

    private static double mEMA = 0.0;
    static final private double EMA_FILTER = 0.6;

    static String decider="0";
    private dbRunnable newdb = new dbRunnable();
    MediaRecorder recorder;

    class dbRunnable implements Runnable{

        @Override
        public void run(){
            Log.i("Runnable","called");  //Log to see if runnable is called successfully
            Log.i("decider",decider);   //decider is supposed to be "0" until stopRecord is called, but somehow becomes "1" before that 
            while(true){
                Log.i("Runnable","called");
                if(decider=="1"){
                    break;
                }
            }
        }

    }


    public void startRecord(View view) {
        Log.i("Inside", "start record");
        if (recorder == null) {
            recorder = new MediaRecorder();
            recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            recorder.setOutputFile("/dev/null");
            try {
                recorder.prepare();
            } catch (java.io.IOException ioe) {
                android.util.Log.e("[Monkey]", "IOException: " +
                        android.util.Log.getStackTraceString(ioe));

            } catch (java.lang.SecurityException e) {
                android.util.Log.e("[Monkey]", "SecurityException: " +
                        android.util.Log.getStackTraceString(e));
            }
            try {
                recorder.start();
                Thread dec1 = new Thread(newdb);   //Creating new thread
                dec1.start();                      //Starting the runnable

            } catch (java.lang.SecurityException e) {
                android.util.Log.e("[Monkey]", "SecurityException: " +
                        android.util.Log.getStackTraceString(e));
            }
        }
    }
    public void stopRecord(View view){
        if (recorder != null) {
            recorder.stop();
            recorder.release();
            recorder = null;
        }

        decider="1";

        Log.i("Hello","record complete");
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void updateTv(){
        mStatusView.setText(Double.toString((getAmplitudeEMA())) + " dB");
    }
    public double soundDb(double ampl){
        return  20 * Math.log10(getAmplitudeEMA() / ampl);
    }
    public double getAmplitude() {
        if (recorder != null)
            return  (recorder.getMaxAmplitude());
        else
            return 0;

    }
    public double getAmplitudeEMA() {
        double amp =  getAmplitude();
        mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
        return mEMA/100;
    }

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }
}

2 个答案:

答案 0 :(得分:0)

尝试创建一个布尔调用“录制”而不是字符串。一旦被调用等等,将其设置为false。您只需在按钮上点击stopRecord()?你还在哪里设置决策者值?

答案 1 :(得分:0)

从我所知道的代码中,您将变量设置为为“0”并且从不重置它。因此,如果您要开始,停止并重新开始,则该值将永远不会再为“0”。一个简单的解决方法是确保在开始新录制之前始终重置此变量:

recorder.start();
decider = "0"; // Reset control variable before starting thread
Thread dec1 = new Thread(newdb);   //Creating new thread
dec1.start();   

你打破while循环的逻辑是错误的,顺便说一句。

if (decider == "1") {
    break;
}

在Java中==表示引用相等,所以这几乎肯定是false。请改为"1".equals(decider)(注意顺序以避免NullPointerException)。

希望有所帮助!