2017-02-21 54 views
-1

我有一個應用程序使用MediaPlayer類將聲音文件轉換爲Android可以輕鬆處理的可播放文件。
所有低效的代碼都是由於我們只被允許使用目前已經教過的資源。
現在,我遇到了一個MediaPlayer對象數組的問題。MediaPlayer對象陣列的問題

我們被指示製作一個讓Twinkle Twinkle Little Star玩的按鈕。
任何時候調用一個對象(mpA,mpB等)時,聲音都會播放。
但是,無論何時使用數組(mediaFiles [0],mediaFiles [1]等)調用對象,應用程序都會因NullPointerExeption而崩潰。

該對象不爲空,並且我已經多次測試過。
該對象被視爲MediaPlayer對象。

我和我的老師都不知道可能是什麼原因造成的。

package com.example.mgeyer.synthesizer; 

import android.media.MediaPlayer; 
import android.provider.MediaStore; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.NumberPicker; 

public class SynthesizerActivity extends AppCompatActivity { 
    private final int WHOLE_NOTE = 1000; 
    private static final String TAG = 
      SynthesizerActivity.class.getName(); 
    private Button mAButton; 
    private Button mASButton; 
    private Button mBButton; 
    private Button mCButton; 
    private Button mCSButton; 
    private Button mDButton; 
    private Button mDSButton; 
    private Button mEButton; 
    private Button mFButton; 
    private Button mFSButton; 
    private Button mGButton; 
    private Button mGSButton; 
    private Button mHEButton; 
    private Button mHFButton; 
    private Button mHFSButton; 
    private Button mHGButton; 
    private MediaPlayer mpA; 
    private MediaPlayer mpAS; 
    private MediaPlayer mpB; 
    private MediaPlayer mpC; 
    private MediaPlayer mpCS; 
    private MediaPlayer mpD; 
    private MediaPlayer mpDS; 
    private MediaPlayer mpE; 
    private MediaPlayer mpF; 
    private MediaPlayer mpFS; 
    private MediaPlayer mpG; 
    private MediaPlayer mpGS; 
    private MediaPlayer mpHE; 
    private MediaPlayer mpHF; 
    private MediaPlayer mpHFS; 
    private MediaPlayer mpHG; 
    private NumberPicker numberPickerNote; 
    private NumberPicker numberPickerAmount; 
    // private int timesPlayed = 1; 
    //private MediaPlayer selectedNote = mpA; 
    private MediaPlayer[] mediaFiles = {mpA, mpAS, mpB, mpC, mpCS, mpD, mpDS, mpE, mpF, mpFS, mpG, mpGS, mpHE, mpHF, mpHFS, mpHG}; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_synthesizer); 
     mAButton = (Button) findViewById(R.id.aButton); 
     mASButton = (Button) findViewById(R.id.asButton); 
     mBButton = (Button) findViewById(R.id.bButton); 
     mCButton = (Button) findViewById(R.id.cButton); 
     mCSButton = (Button) findViewById(R.id.csButton); 
     mDButton = (Button) findViewById(R.id.dButton); 
     mDSButton = (Button) findViewById(R.id.dsButton); 
     mEButton = (Button) findViewById(R.id.eButton); 
     mFButton = (Button) findViewById(R.id.fButton); 
     mFSButton = (Button) findViewById(R.id.fsButton); 
     mGButton = (Button) findViewById(R.id.gButton); 
     mGSButton = (Button) findViewById(R.id.gsButton); 
     mHEButton = (Button) findViewById(R.id.heButton); 
     mHFButton = (Button) findViewById(R.id.hfButton); 
     mHFSButton = (Button) findViewById(R.id.hfsButton); 
     mHGButton = (Button) findViewById(R.id.hgButton); 
     mpA = MediaPlayer.create(this, R.raw.scalea); 
     mpAS = MediaPlayer.create(this, R.raw.scaleas); 
     mpB = MediaPlayer.create(this, R.raw.scaleb); 
     mpC = MediaPlayer.create(this, R.raw.scalec); 
     mpCS = MediaPlayer.create(this, R.raw.scalecs); 
     mpD = MediaPlayer.create(this, R.raw.scaled); 
     mpDS = MediaPlayer.create(this, R.raw.scaleds); 
     mpE = MediaPlayer.create(this, R.raw.scalee); 
     mpF = MediaPlayer.create(this, R.raw.scalef); 
     mpFS = MediaPlayer.create(this, R.raw.scalefs); 
     mpG = MediaPlayer.create(this, R.raw.scaleg); 
     mpGS = MediaPlayer.create(this, R.raw.scalegs); 
     mpHE = MediaPlayer.create(this, R.raw.scalehighe); 
     mpHF = MediaPlayer.create(this, R.raw.scalehighf); 
     mpHFS = MediaPlayer.create(this, R.raw.scalehighfs); 
     mpHG = MediaPlayer.create(this, R.raw.scalehighg); 
     numberPickerNote = (NumberPicker)findViewById(R.id.numberPicker); 
     numberPickerAmount = (NumberPicker)findViewById(R.id.numberPicker2); 
     numberPickerNote.setMinValue(1); 
     numberPickerNote.setMaxValue(16); 
     numberPickerAmount.setMinValue(1); 
     numberPickerAmount.setMaxValue(10); 

     numberPickerNote.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { 
      @Override 
      public void onValueChange(NumberPicker picker, int oldVal, int newVal) { 
       //selectedNote = mediaFiles[numberPickerNote.getValue() - 1]; 
      } 
     }); 

     numberPickerAmount.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { 
      @Override 
      public void onValueChange(NumberPicker picker, int oldVal, int newVal) { 
       //timesPlayed = numberPickerAmount.getValue(); 
      } 
     }); 
    } 

    private void delayPlaying(int delay) throws InterruptedException { 
     try { 
      Thread.sleep(delay); 
     } catch (InterruptedException e) { 
      Log.e("SynthesizerActivity", "Audio playback interrupted"); 
     } 
    } 

    public void onButtonClick(View v) { 
     mpA.seekTo(0); 
     Log.i(TAG, "A Button clicked"); 
     mpA.start(); 
    } 

    public void onButton2Click(View v) { 
     mpAS.seekTo(0); 
     Log.i(TAG, "A# Button clicked"); 
     mpAS.start(); 
    } 

    public void onButton3Click(View v) { 
     mpB.seekTo(0); 
     Log.i(TAG, "B Button clicked"); 
     mpB.start(); 
    } 

    public void onButton4Click(View v) { 
     mpC.seekTo(0); 
     Log.i(TAG, "C Button clicked"); 
     mpC.start(); 
    } 

    public void onButton5Click(View v) { 
     mpCS.seekTo(0); 
     Log.i(TAG, "C# Button clicked"); 
     mpCS.start(); 
    } 

    public void onButton6Click(View v) { 
     mpD.seekTo(0); 
     Log.i(TAG, "D Button clicked"); 
     mpD.start(); 
    } 

    public void onButton7Click(View v) { 
     mpDS.seekTo(0); 
     Log.i(TAG, "D# Button clicked"); 
     mpDS.start(); 
    } 

    public void onButton8Click(View v) { 
     mpE.seekTo(0); 
     Log.i(TAG, "E Button clicked"); 
     mpE.start(); 
    } 

    public void onButton9Click(View v) { 
     mpF.seekTo(0); 
     Log.i(TAG, "F Button clicked"); 
     mpF.start(); 
    } 

    public void onButton10Click(View v) { 
     mpFS.seekTo(0); 
     Log.i(TAG, "F# Button clicked"); 
     mpFS.start(); 
    } 

    public void onButton11Click(View v) { 
     mpG.seekTo(0); 
     Log.i(TAG, "G Button clicked"); 
     mpG.start(); 
    } 

    public void onButton12Click(View v) { 
     mpGS.seekTo(0); 
     Log.i(TAG, "G# Button clicked"); 
     mpGS.start(); 
    } 

    public void onButton13Click(View v) { 
     mpHE.seekTo(0); 
     Log.i(TAG, "High E Button clicked"); 
     mpHE.start(); 
    } 

    public void onButton14Click(View v) { 
     mpHF.seekTo(0); 
     Log.i(TAG, "High F Button clicked"); 
     mpHF.start(); 
    } 

    public void onButton15Click(View v) { 
     mpHFS.seekTo(0); 
     Log.i(TAG, "High F# Button clicked"); 
     mpHFS.start(); 
    } 

    public void onButton16Click(View v) { 
     mpHG.seekTo(0); 
     Log.i(TAG, "High G Button clicked"); 
     mpHG.start(); 
    } 

    public void onButton17Click(View v) { 
     try { 
      mpE.seekTo(0); 
      mpE.start(); 
      delayPlaying(WHOLE_NOTE/2); 
      mpFS.seekTo(0); 
      mpFS.start(); 
      delayPlaying(WHOLE_NOTE/2); 
      mpG.seekTo(0); 
      mpG.start(); 
      delayPlaying(WHOLE_NOTE/2); 
      mpA.seekTo(0); 
      mpA.start(); 
      delayPlaying(WHOLE_NOTE/2); 
      mpB.seekTo(0); 
      mpB.start(); 
      delayPlaying(WHOLE_NOTE/2); 
      mpCS.seekTo(0); 
      mpCS.start(); 
      delayPlaying(WHOLE_NOTE/2); 
      mpD.seekTo(0); 
      mpD.start(); 
      delayPlaying(WHOLE_NOTE/2); 
      mpHE.seekTo(0); 
      mpHE.start(); 
      delayPlaying(WHOLE_NOTE/2); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

    } 

    public void onSelectedNoteClick(View v) { 
     for (int i = numberPickerAmount.getValue(); i > 0; i--) { 
      try { 
       mediaFiles[(numberPickerNote.getValue() - 1)].seekTo(0); 
       mediaFiles[(numberPickerNote.getValue() - 1)].start(); 
       delayPlaying(WHOLE_NOTE/2); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public void onTwinkleClick (View v) { 
     try { 
      mediaFiles[0].seekTo(0); 
      mediaFiles[0].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[0].seekTo(0); 
      mediaFiles[0].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[12].seekTo(0); 
      mediaFiles[12].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[12].seekTo(0); 
      mediaFiles[12].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[13].seekTo(0); 
      mediaFiles[13].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[13].seekTo(0); 
      mediaFiles[13].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[12].seekTo(0); 
      mediaFiles[12].start(); 
      delayPlaying(WHOLE_NOTE/2); 
      mediaFiles[5].seekTo(0); 
      mediaFiles[5].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[5].seekTo(0); 
      mediaFiles[5].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[4].seekTo(0); 
      mediaFiles[4].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[4].seekTo(0); 
      mediaFiles[4].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[2].seekTo(0); 
      mediaFiles[2].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[2].seekTo(0); 
      mediaFiles[2].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[0].seekTo(0); 
      mediaFiles[0].start(); 
      delayPlaying(WHOLE_NOTE/2); 
      mediaFiles[12].seekTo(0); 
      mediaFiles[12].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[12].seekTo(0); 
      mediaFiles[12].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[5].seekTo(0); 
      mediaFiles[5].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[5].seekTo(0); 
      mediaFiles[5].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[4].seekTo(0); 
      mediaFiles[4].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[4].seekTo(0); 
      mediaFiles[4].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[2].seekTo(0); 
      mediaFiles[2].start(); 
      delayPlaying(WHOLE_NOTE/2); 
      mediaFiles[12].seekTo(0); 
      mediaFiles[12].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[12].seekTo(0); 
      mediaFiles[12].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[5].seekTo(0); 
      mediaFiles[5].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[5].seekTo(0); 
      mediaFiles[5].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[4].seekTo(0); 
      mediaFiles[4].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[4].seekTo(0); 
      mediaFiles[4].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[2].seekTo(0); 
      mediaFiles[2].start(); 
      delayPlaying(WHOLE_NOTE/2); 
      mediaFiles[0].seekTo(0); 
      mediaFiles[0].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[0].seekTo(0); 
      mediaFiles[0].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[12].seekTo(0); 
      mediaFiles[12].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[12].seekTo(0); 
      mediaFiles[12].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[13].seekTo(0); 
      mediaFiles[13].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[13].seekTo(0); 
      mediaFiles[13].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[12].seekTo(0); 
      mediaFiles[12].start(); 
      delayPlaying(WHOLE_NOTE/2); 
      mediaFiles[5].seekTo(0); 
      mediaFiles[5].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[5].seekTo(0); 
      mediaFiles[5].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[4].seekTo(0); 
      mediaFiles[4].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[4].seekTo(0); 
      mediaFiles[4].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[2].seekTo(0); 
      mediaFiles[2].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[2].seekTo(0); 
      mediaFiles[2].start(); 
      delayPlaying(WHOLE_NOTE/4); 
      mediaFiles[0].seekTo(0); 
      mediaFiles[0].start(); 
      delayPlaying(WHOLE_NOTE/2); 
     } catch (InterruptedException e){ 
      e.printStackTrace(); 
     } 
    } 
} 

此外,這裏是調試器的輸出。

E/AndroidRuntime: FATAL EXCEPTION: main 
        Process: com.example.mgeyer.synthesizer, PID: 4066 
        java.lang.IllegalStateException: Could not execute method for android:onClick 
         at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293) 
         at android.view.View.performClick(View.java:5637) 
         at android.view.View$PerformClick.run(View.java:22429) 
         at android.os.Handler.handleCallback(Handler.java:751) 
         at android.os.Handler.dispatchMessage(Handler.java:95) 
         at android.os.Looper.loop(Looper.java:154) 
         at android.app.ActivityThread.main(ActivityThread.java:6119) 
         at java.lang.reflect.Method.invoke(Native Method) 
         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
        Caused by: java.lang.reflect.InvocationTargetException 
         at java.lang.reflect.Method.invoke(Native Method) 
         at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
         at android.view.View.performClick(View.java:5637) 
         at android.view.View$PerformClick.run(View.java:22429) 
         at android.os.Handler.handleCallback(Handler.java:751) 
         at android.os.Handler.dispatchMessage(Handler.java:95) 
         at android.os.Looper.loop(Looper.java:154) 
         at android.app.ActivityThread.main(ActivityThread.java:6119) 
         at java.lang.reflect.Method.invoke(Native Method) 
         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
        Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.media.MediaPlayer.seekTo(int)' on a null object reference 
         at com.example.mgeyer.synthesizer.SynthesizerActivity.onTwinkleClick(SynthesizerActivity.java:261) 
         at java.lang.reflect.Method.invoke(Native Method) 
         at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
         at android.view.View.performClick(View.java:5637) 
         at android.view.View$PerformClick.run(View.java:22429) 
         at android.os.Handler.handleCallback(Handler.java:751) 
         at android.os.Handler.dispatchMessage(Handler.java:95) 
         at android.os.Looper.loop(Looper.java:154) 
         at android.app.ActivityThread.main(ActivityThread.java:6119) 
         at java.lang.reflect.Method.invoke(Native Method) 
         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
+0

爲什麼你創造這麼多的媒體播放器對象?應用程序應該同時播放多個文件嗎? –

+0

其餘的代碼真的是多餘的,onButtonClick方法是完全足夠的,因爲你從視圖參數知道哪個按鈕被點擊過。 –

+0

請看[mcve]。關鍵字很少。 –

回答

1

如果你用一個更簡單的例子來測試它,你會發現在這種情況下這些值確實是空的。

例如與

public class Test 
    { 
    Object o1; //reference to null! (default value) 
    Object [] tests = new Object[] {o1}; //..therefore tests contains null 


    public void test() 
    { 
    this.o1=new Object(); //now points to a new object, but tests[0]... 
    System.out.println(this.tests[0]); //...has the null reference 
    System.out.println(this.o1); //prints out reference to object 
    this.tests[0]=this.o1; //now tests[0] points to the same object... 
    System.out.println(this.tests[0]); //...as this.o1 

    } 
    public static void main(String[] args) 
    { 
    new Test().test(); 
    } 
} 

一定要記住,你只把參考(即指針)到陣列中一個對象(或空值)。如果屬性指向一個新的對象(在你的情況下是一個MediaPlayer對象),這將而不是更改原來的引用,它具有與以前相同的地址。

一個真實世界的例子是包含朋友地址的地址簿。如果這位朋友移動,通訊簿中的條目仍然會指向他/她的舊家。

編輯:你不需要onButtonClick方法的很多實現,因爲你有視圖參數,它告訴你哪個按鈕被點擊,這是足夠的。

1

該對象不是空的,我已經多次測試過。該對象被視爲MediaPlayer對象

該對象爲空。堆棧跟蹤不說謊......

我和我的老師不知道是什麼導致這個

請問你的老師瞭解Java?

製作未初始化的字段數組肯定會使它們爲空!


取而代之的是...

private MediaPlayer[] mediaFiles = {mpA, mpAS, mpB, mpC, mpCS, mpD, mpDS, mpE, mpF, mpFS, mpG, mpGS, mpHE, mpHF, mpHFS, mpHG}; 

與此

private MediaPlayer[] mediaFiles; 

而且更換內onCreate,你可以創建一個非空引用數組。

// Other players... 
mpHG = MediaPlayer.create(this, R.raw.scalehighg); 
mediaFiles = {mpA, mpAS, mpB, mpC, mpCS, mpD, mpDS, mpE, mpF, mpFS, mpG, mpGS, mpHE, mpHF, mpHFS, mpHG}; 

或者使用HashMap<Integer, MediaPlayer>像這樣

private Map<Integer, MediaPlayer> mediaPlayerMap = new HashMap<Integer, MediaPlayer>(); 

... 

// For example 
button.setTag(R.raw.scalehighg); 
mediaPlayerMap.put(R.raw.scalehighg, MediaPlayer.create(this, R.raw.scalehighg)); 

... 

// Any button click... 
@Override 
public void onClick(View v) { 
    Integer songId = (Integer) v.getTag(); 
    MediaPlayer mp = mediaPlayerMap.get(songId); 
    mp.seekTo(0); 
    mp.start(); 
} 

雖然,現實,我想你只需要一個MediaPlayer根據您的需要。