2010-07-30 14 views
41

Próbuję odtworzyć plik dźwiękowy jednym kliknięciem. Dźwięk ma zaledwie 1 sek. Gra się dobrze, po raz pierwszy klikam przycisk, ale po chwili daje NullPointerException. Oto kod:Android - odtwarzanie dźwięku po kliknięciu przycisku - wyjątek wskaźnika pustego

button[i].setOnClickListener(new OnClickListener() { 
    public void onClick(View view) {   
     mp = MediaPlayer.create(Test.this, R.raw.mysound); 
     mp.start(); 
    } 
}); 

I tu jest wyjątek:

07-29 23:07:27.690: ERROR/AndroidRuntime(10542): Uncaught handler: thread main exiting due to uncaught exception 
07-29 23:07:27.710: ERROR/AndroidRuntime(10542): java.lang.NullPointerException 
07-29 23:07:27.710: ERROR/AndroidRuntime(10542):  at com.example.mypackage.Test$3.onClick(Test.java:270) 
+3

nie wiem, czy to pomoże, ale może spróbować mp.reset() po zakończeniu? –

+0

Tak, pomogło! Dziękuję Ci! – Chris

+0

Jeśli chcesz, aby zasoby były zarządzane automatycznie, możesz wywołać 'MusicManager.getInstance(). Play (this, R.raw.my_sound);' itd. Ta biblioteka może być dla Ciebie: https: // github .com/delight-im/Android-Audio – caw

Odpowiedz

4

To może rozwiązać problem,

button[i].setOnClickListener(new OnClickListener() { 
    public void onClick(View view) {  
     new Thread(){ 
      public void run(){ 
       mp = MediaPlayer.create(Test.this, R.raw.mysound); 
       mp.start(); 
     }.start(); 
    } 
}); 
+0

Nadal działa dobrze dla pierwszych kilku kliknięć, a następnie daje wyjątek wskaźnika pustego, szczególnie gdy szybko klikam przyciski po kolei. – Chris

+0

możesz spróbować, 1) wprowadzenie czeku przed rozpoczęciem. mam na myśli sprawdzenie, czy gracz jest na etapie gry, a nie wykonuj tego polecenia. mp = MediaPlayer.create (Test.this, R.raw.mysound); mp.start(); lub 2) make mp jako zmienna lokalna – sohilv

101

dziękuje za odpowiedzi! Doceniam to!

Oto, jak udało mi się dostać to działa:

  button[i].setOnClickListener(new OnClickListener() { 
       public void onClick(View view) { 

        mp = MediaPlayer.create(Test.this, R.raw.mysound); 
        mp.setOnCompletionListener(new OnCompletionListener() { 

         @Override 
         public void onCompletion(MediaPlayer mp) { 
          // TODO Auto-generated method stub 
          mp.release(); 
         } 

        }); 
        mp.start(); 
       } 

      }); 
+9

wydaje się być może .setOnCompletionListener powinien pojawić się przed .start nie po (?) –

+0

Zgadzam się z Ryanem. – Carcamano

+0

zmieniono kolejność wywołań – WarrenFaith

0

Jeśli nadal nie rozwiązany problem został następnie spróbować tego, jak mi pomóc.

public void playSound(int resources){ 
     try{ 
      boolean mStartPlaying = true; 
      MediaPlayer mPlayer=null; 
      if (mStartPlaying==true){ 
       mPlayer = new MediaPlayer(); 

       Uri uri = Uri.parse("android.resource://YOUR_PACKAGENAME/" + resources); 
       mPlayer.setDataSource(getApplicationContext(),uri); 
       mPlayer.prepare(); 
       mPlayer.start(); 
      } 
      else{ 
       mPlayer.release(); 
       mPlayer = null; 
      } 
      mStartPlaying = !mStartPlaying; 
     } 
     catch (IOException e){ 
      Log.e(LOG_TAG, "prepare() failed"); 
     } 

//  MediaPlayer mp = MediaPlayer.create(SpyMainActivity.this, resources); 
//  mp.start(); 

    } 

Ciesz się. :)

24

Można też spróbować:

final soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0); 
final sound = soundPool.load(this, R.raw.mysound, 1); 

button[i].setOnClickListener(new OnClickListener() 
{ 
    public void onClick(View view) 
    {  
     soundPool.play(sound, 1.0f, 1.0f, 0, 0, 1.0f); 
    } 
}); 
+6

Wygląda na to, że jest to lepszy sposób na wykonanie powtarzającego się, krótkiego dźwięku kliknięcia przycisku (zamiast tworzenia/niszczenia odtwarzacza multimedialnego za każdym razem). Nie zapomnij jednak zrobić 'soundPool.release();' w swoim 'onDestroy' (lub gdziekolwiek chcesz wyczyścić działanie). – Alconja

+0

@Alconja Z mojego doświadczenia wynika, że ​​nie ma żadnej gwarancji na to, żeDestroy zostanie wywołany (np. Zabójca z Androidem zazwyczaj zabija moją aplikację bez ostrzeżenia). – Michael

+0

@Michael, gdy aplikacja jest zabijana w ten sposób, zwykle nie ma potrzeby cofania zasobów, ponieważ cały proces zostaje zakończony, a wszystko, co zostało otwarte i przydzielone, jest automatycznie zamykane i zwalniane przez system. – Grishka

1

Należy złapać wyjątek.

wypróbować ten kod:

 try{ 
     MediaPlayer mplayer = MediaPlayer.create(contextTop, R.raw.<your sound>); 
     mplayer.start(); 
    }catch(Exception e){ 
     Log.d("<your TAG here>" , "error: " + e); 
    } 
Powiązane problemy