-5

MainActivity.java:

    import android.media.MediaPlayer;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;

    public class MainActivity extends AppCompatActivity {

        int currentPosition;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            MyListener myListener = new MyListener();

            Button startButton = (Button) findViewById(R.id.start);
            startButton.setOnClickListener(myListener);

            Button pauseButton = (Button) findViewById(R.id.pause);
            pauseButton.setOnClickListener(myListener);

        }
    }

MyListener.java:

    import android.media.MediaPlayer;
    import android.provider.MediaStore;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;

    public class MyListener extends AppCompatActivity implements View.OnClickListener{

        MediaPlayer musicPlayer = MediaPlayer.create(this, R.raw.sound_file);

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_my_listener);
        }

        @Override
        public void onClick(View v){

            switch(v.getId()){
                case R.id.start:
                    musicPlayer.start();
                    break;
                case R.id.pause:
                    musicPlayer.pause();
                    break;
            }
        }
    }

Logcat shows the following error:

    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.musicplayer/com.example.android.musicplayer.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference

I am trying to create an app that plays audio from my res/raw file, but there seems to be something wrong with my code as it is not working, please help me.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Jordan23
  • 3
  • 2
  • 6
    You cannot initialize `musicPlayer` before receiving `onCreate` call. – Pawel Sep 28 '18 at 10:20
  • 5
    Your listener should not extend `AppCompatActivity`. They are special purpose classes. Only an Activity should extend it. In fact, you don't even need a different class for listener here. That code should go to `MainActivity` itself. – Rohit5k2 Sep 28 '18 at 10:24

1 Answers1

0

Firstly, your MediaPlayer instance should reside within MainActivity, not MyListener, and MyListener should not extend an activity. In fact, you should move all of your code from MyListener into MainActivity, I don't really see a purpose for it in the snippet you've provided.

Secondly, You're creating your MediaPlayer outside of the Activity Lifecycle, while still trying to pass a Context to it:

public class MainActivity extends AppCompatActivity {

    MediaPlayer musicPlayer = MediaPlayer.create(this, R.raw.sound_file);
    ...
}

The activity has no Context (this) until the Activity Lifecycle has started, the way you've written it above is equivalent to defining musicPlayer in a constructor:

public class MainActivity extends AppCompatActivity {

    MediaPlayer musicPlayer; 

    public MyListener() {
        musicPlayer = MediaPlayer.create(this, R.raw.sound_file);
    }
    ...
}

This will also fail as the Activity Lifecycle has not yet started. What you need to do is declare musicPlayer as a member of the class, and then create an instance in onCreate() where the Context will have been initialsed:

public class MainActivity extends AppCompatActivity {

    MediaPlayer musicPlayer; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_listener);
        musicPlayer = MediaPlayer.create(this, R.raw.sound_file);
    }
    ...
}

To address your comment, here's an example of how it could all fit in to your MainActivity using lambdas:

public class MainActivity extends AppCompatActivity {

    int currentPosition;
    MediaPlayer musicPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        musicPlayer = MediaPlayer.create(this, R.raw.sound_file);

        Button startButton = (Button) findViewById(R.id.start);
        startButton.setOnClickListener(view -> musicPlayer.start());

        Button pauseButton = (Button) findViewById(R.id.pause);
        pauseButton.setOnClickListener(view -> musicPlayer.pause());
    }
}
Michael Dodd
  • 10,102
  • 12
  • 51
  • 64
  • Thank you for answering! I wanted to create a different class that implements listener because i think that would make my mainactivity less clustered, is that stupid? My listener class is working after adding the following public constructor| public MyListener(Context c) { musicPlayer = MediaPlayer.create(c, R.raw.sound_file); } should i just implement listener in my mainactivity and build my code there? – Jordan23 Sep 28 '18 at 11:07
  • Well, with lambda methods introduced in Java 8, there's no real need to define a full `OnClickListener`, I'll update my answer with an example – Michael Dodd Sep 28 '18 at 11:09
  • But yes, your listener can still implement `OnClickListener` if you want to take that approach. The rest of the class will still work if you remove the extension on `AppCompatActivity` and pass in a Context via the constructor, like you've already done. – Michael Dodd Sep 28 '18 at 11:16
  • 1
    Omggg i just got introduced to this, this is much more convenient than implementing listener or creating a anonymous class, thanks for your help!! – Jordan23 Sep 28 '18 at 11:42