我确定这个错误是因为我没有完全理解线程,但在这里它... ...
我在方法中调用onCreate()
时启动了runnable:
@Override
protected void onCreate(Bundle savedInstanceState) {
//Set all app specific starting points here
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_avatar);
...
soundMeterLoop();
}
public void soundMeterLoop() {
Log.d("SpeechKit", "Start Sound Meter");
soundMeterHandler = new Handler();
soundMeterRunnable = new Runnable() {
@Override
public void run() {
if(!soundMeter.SoundMeterRunning) {
Log.d("SpeechKit", "Start SoundMeter in the runnable");
startSoundMeter();
}
if (soundMeter.mMediaRecorder != null) {
amplitude = soundMeter.getAmplitude();
decibelLevelOutput.setText("" + amplitude);
if (amplitude > threshold) {
decibelLevelOutput.setTextColor(Color.RED);
Log.d("SpeechKit", "Interrupt and run startNuance()");
startNuance();
} else {
decibelLevelOutput.setTextColor(Color.BLACK);
Log.d("SpeechKit", "Running");
soundMeterHandler.postDelayed(this, 100);
}
}
}
};
soundMeterHandler.postDelayed(soundMeterRunnable, 100);
}
当它在onCreate
中创建时运行正常。正如您所看到的,它会自行消失(如果语句失败,则不会更新循环)并运行startNuance()
。
public void startNuance() {
soundMeterHandler.removeCallbacksAndMessages(soundMeterRunnable);
nuance.toggleReco();
}
然后我杀了runnable并在另一个类中启动一个方法。这个类运行正常,然后当它完成它的事情时,我用avatar.stopNuance();
这是Nuance.java类
@Override
public void onFinishedRecording(Transaction transaction) {
Log.d("SpeechKit", "onFinishedRecording");
//We have finished recording the users voice.
//We should update our state and stop polling their volume.
state = State.PROCESSING;
stopAudioLevelPoll();
avatar.stopNuance(); // <<<<<
}
然后返回我的主要活动(avatar
)并运行此stopNuance()
方法:
public void stopNuance() {
Log.d("SpeechKit", "stopNuance(), start loop again");
soundMeterLoop();
}
然后它尝试从之前运行相同的循环。只是这一次,我收到了很多与nullpointerexceptions有关的错误。特别是从decibelLevelOutput.setText("" + amplitude);
我不确定为什么这些东西是空的或如何修复它们。这是因为它启动了一个在创建runnable时没有启动的新线程吗?
答案 0 :(得分:1)
在谈论聊天之后,实际问题出现在代码库的其他地方。
问题在于:
public class Nuance {
private Activity activity;
private Session session;
public Avatar avatarActivity = new Avatar(); // DONT DO THIS
....
@Override
public void onFinishedRecording(Transaction transaction) {
Log.d("SpeechKit", "onFinishedRecording");
//We have finished recording the users voice.
//We should update our state and stop polling their volume.
state = State.PROCESSING;
stopAudioLevelPoll();
avatarActivity.stopNuance();
}
您永远不应该创建自己的Activity实例。它们由系统进行创建和管理。系统将调用实例(onCreate
等)上的生命周期方法,但如果您创建实例,则不会调用这些方法 - 因此会发生许多奇怪的行为。
这里的解决方法是:
public class Nuance {
private Avatar activity;
private Session session;
....
@Override
public void onFinishedRecording(Transaction transaction) {
Log.d("SpeechKit", "onFinishedRecording");
//We have finished recording the users voice.
//We should update our state and stop polling their volume.
state = State.PROCESSING;
stopAudioLevelPoll();
activity.stopNuance();
}
答案 1 :(得分:0)
每次调用soundMeterLoop()
时,您都不想创建新的runnable。
试试这个:
private final Handler soundMeterHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
//Set all app specific starting points here
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_avatar);
...
soundMeterLoop();
}
public void soundMeterLoop() {
Log.d("SpeechKit", "Start Sound Meter");
soundMeterHandler.postDelayed(soundMeterRunnable, 100);
}
private final Runnable soundMeterRunnable = new Runnable() {
@Override
public void run() {
if(!soundMeter.SoundMeterRunning) {
Log.d("SpeechKit", "Start SoundMeter in the runnable");
startSoundMeter();
}
if (soundMeter.mMediaRecorder != null) {
amplitude = soundMeter.getAmplitude();
decibelLevelOutput.setText("" + amplitude);
if (amplitude > threshold) {
decibelLevelOutput.setTextColor(Color.RED);
Log.d("SpeechKit", "Interrupt and run startNuance()");
startNuance();
} else {
decibelLevelOutput.setTextColor(Color.BLACK);
Log.d("SpeechKit", "Running");
soundMeterHandler.postDelayed(this, 100);
}
}
}
};