2016-12-30 9 views
1

Ich bin sicher, dass dieser Fehler ist, weil ich nicht in vollem Umfang Fäden verstehen, aber hier geht es ...Android Nullpointer in Runnable zum zweiten Mal

Ich habe einen lauffähiges, dass gestartet wird, wenn onCreate() innerhalb aufgerufen eine Methode:

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

das läuft ganz gut, wenn es in den onCreate erstellt wird. Wie Sie sehen können, wird es selbst beendet (indem die Schleife nicht erneuert wird, wenn die Anweisung fehlschlägt) und startNuance() ausgeführt wird.

public void startNuance() { 
    soundMeterHandler.removeCallbacksAndMessages(soundMeterRunnable); 
    nuance.toggleReco(); 
} 

Ich kille dann die Runnable und starten Sie eine Methode in einer anderen Klasse. Diese Klasse läuft gut, dann, wenn es seine Sache tut fertig ist, nenne ich diese Hauptklasse zurück mit avatar.stopNuance();

Dies ist in der Nuance.java Klasse

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

Es dann zurück zu meiner Haupttätigkeit zurück (avatar) und führt diese stopNuance() Methode:

public void stopNuance() { 
    Log.d("SpeechKit", "stopNuance(), start loop again"); 
    soundMeterLoop(); 
} 

Dann versucht es, aus, bevor die gleiche Schleife laufen. Nur dieses Mal bekomme ich eine Menge Fehler, die zu Nullpunkterfassungen führen. speziell beginnend mit decibelLevelOutput.setText("" + amplitude);

Ich bin mir nicht sicher, warum diese Dinge null sind oder wie sie zu beheben sind. Ist das so, weil es einen neuen Thread gestartet hat, der nicht beim Erstellen des Runnable gestartet wurde?

+0

was ist der Typ der Variablen 'nuance'? Ich würde auch 'avatar' in' avatarActivity' umbenennen, so dass es offensichtlicher ist, was Sie mit – Blundell

+0

'nuance' kommunizieren, bezieht sich auf die Klasse' Nuance'. Das ist ein guter Ruf auf dem AvatarActivity – ntgCleaner

Antwort

1

Nach dem Gespräch im Chat der aktuellen Ausgabe an anderer Stelle im Code-Basis wurde.

Das Problem war:

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

Sie sollten nie, nie jemals Ihre eigene Instanz einer Aktivität erstellen. Sie werden vom System erstellt und verwaltet. Das System ruft die Lifecycle-Methoden für die Instanz auf (onCreate usw.), aber wenn Sie eine Instanz erstellen, werden diese Methoden nicht aufgerufen - daher passiert eine Menge merkwürdiges Verhalten.

Das Update hier ist diese:

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

Vielen Dank für diesen Blick! Du hast mich wahrscheinlich Tage der Forschung gerettet! Danke auch für die Lektion. Jeden Tag lernen! – ntgCleaner

0

Sie möchten nicht jedes Mal einen neuen Runnable erstellen, wenn soundMeterLoop() aufgerufen wird.

Versuchen Sie folgendes:

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

     } 
    }; 
+0

@ntgCleaner Ich möchte wirklich das jetzt arbeiten! haha – Blundell

+0

Hahaha danke! Ich teste es gerade aus – ntgCleaner

+0

Ich bekomme eine 'RuntimeException' mit der Aussage 'Aktivität kann nicht gestartet werden' und auch' java.lang.NullPointerException: Versuch, virtuelle Methode aufzurufen'. stammend aus dem 'soundMeterHandler.postDelayed (soundMeterRunnable, 100);' Ich habe keinen Handler eingerichtet, ich nehme an – ntgCleaner

Verwandte Themen