我在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");
}
}
答案 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
)。
希望有所帮助!