我有一个应用程序,它使用MediaPlayer类将声音文件制作成Android文件易于播放的可播放文件 所有效率低下的代码都是因为我们只允许使用到目前为止所教授的资源 现在,我遇到了一个MediaPlayer对象数组的问题。
我们被要求制作一个让Twinkle Twinkle Little Star演奏的按钮
无论何时调用一个对象(mpA,mpB等),都会播放声音
但是,无论何时使用数组(mediaFiles [0],mediaFiles [1]等)调用对象,应用程序都会因NullPointerExeption
而崩溃。
该对象不为null,我已经多次测试过了 该对象被视为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 :(得分:1)
如果你用一个更简单的例子测试它,你会发现在这种情况下值确实为空。
e.g。与
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();
}
}
始终记住,您只将引用(即指针)放入数组中的对象(或null)。如果属性指向新对象(在您的情况下是MediaPlayer对象),则不将更改原始引用,该引用具有与以前相同的地址。
真实世界的例子是包含朋友地址的地址簿。如果这位朋友移动,地址簿中的条目仍将指向他/她的旧房子。
编辑:你不需要onButtonClick方法的那么多实现,一个就足够了,因为你有一个view参数告诉你点击了哪个按钮。
答案 1 :(得分:1)
该对象不为null,我已经多次测试过了。该对象被视为MediaPlayer对象
该对象为null。堆栈跟踪不在......
我和老师都不知道是什么导致了这个
您的老师是否了解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
。