Question

I have created a timer, so that when it finishes, music plays. But the song does not ever stop playing if the user presses the back button. So I tried to override the lifecycle method onPause(), which worked, so if the timer had finished and the music was actually playing - then using the back button stopped the music.

However, when a user tries to press the back button of their device before the timer finishes (and the music has not started yet), then I get a null pointer exception in the onPause() method.

What can be causing this? How do I write code that says "if MediaPlayer is playing, then stop and release it, otherwise do nothing". That is what I need conceptually. (Or there might be a better way to write it?)

Here is my code snippet for the MediaPlayer in the timer's onFinishes() method, which makes the song start playing, when the timer finishes. (mpCease is just a global variable that represents mp, so I can use it outside of 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);
        }

Here is the onPause method written so far (it's not complete), which works really well to stop the music when the back button is pressed (only if it's already playing).

@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 (when back button is pressed before timer is finished, it crashes).

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)
Was it helpful?

Solution

Just get rid of mp and replace it with mpCease. Then check if that is 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
        }
    }

You don't even have to get rid of mp but just check if mpCease is null. You don't initialize it until onFinish() of (I assume) a CountDownTimer. So, if they press back before it has finished then obviously it is null.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top