我已经创建了一个计时器,所以当它完成时,音乐播放。但如果用户按下后退键,这首歌也不会停止播放。所以我试图覆盖生命周期方法onPause()
,这是有效的,所以如果计时器已经完成,音乐实际上正在播放-然后使用后退按钮停止音乐。
然而,当用户试图在计时器完成之前按下他们的设备的后退按钮时(音乐尚未开始),然后我在onPause()
方法中得到null pointer exception
。
是什么原因导致的?我怎么写代码,说"如果MediaPlayer 是播放,然后停止并释放它,否则什么都不做"。这就是我在概念上需要的。(或者有更好的写法?)
这是我在计时器的onFinishes()
方法中的MediaPlayer的代码片段,当计时器结束时,它使歌曲开始播放。 (mpCease
只是一个代表mp
的全局变量,所以我可以在onFinish()
之外使用它)。
public void onFinish() {
mTextField.setText("BRAINS!!");
// call some media function here
MediaPlayer mp = MediaPlayer.create(ZombieThemedActivity.this, R.raw.zombie_sound);
mp.start();
mpCease = mp;
// This disables the pause/play button when timer ends
Button disablePausePlay = (Button)findViewById(R.id.btnPause);
disablePausePlay.setEnabled(false);
}
这是目前为止编写的onPause方法(它还不完整),当按下后退按钮时(只有当它已经在播放时),它的工作非常好。
@Override
protected void onPause(){
super.onPause();
if (mpCease.isPlaying()) {
mpCease.stop();
mpCease.release();
} else if (!mpCease.isPlaying()) {
// it should do nothing to mpCease or to anything else
}
}
LogCat(当返回键在定时器完成之前按下时,它崩溃)。
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to pause activity {com.azurespot.disastertimer.app/com.azurespot.disastertimer.app.themedactivities.ZombieThemedActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2838)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2794)
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2772)
at android.app.ActivityThread.access$800(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1212)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.azurespot.disastertimer.app.themedactivities.ZombieThemedActivity.onPause(ZombieThemedActivity.java:157)
at android.app.Activity.performPause(Activity.java:5106)
at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1225)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2825)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2794)
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2772)
at android.app.ActivityThread.access$800(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1212)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
把mp
去掉,换成mpCease
。然后检查是否为null
@Override
protected void onPause(){
super.onPause();
if (mpCease != null) //add a null check here
{
if (mpCease.isPlaying()) {
mpCease.stop();
mpCease.release();
// if this does nothing then the else isn't needed
} else {
// it should do nothing to mpCease or to anything else
}
}
你甚至不需要去掉mp
,只需要检查mpCease
是否为null
。你不初始化它,直到onFinish()
(我假设)CountDownTimer
。因此,如果他们在完成之前按回,那么显然是null
。