Search code examples
javaandroidandroid-mediaplayermedia

How to use mediaPlayer correctlty?


I'm trying to play music in my app and while the media player is loading I want to allow the user to keep on using the app, but the app gets stuck for few seconds every time I start loading the media player, and when the media player is finished loading, only then the app returns to normal and starts working again, sometimes it's not just freezing, it also shows popup menu from the OS that prompts the user to quit the app.

I couldn't find any solution in Google or YouTube, anyone knows what's wrong with my code?

final Handler handler = new Handler();
Runnable runnable = new Runnable() {
    @Override
    public void run() {
            try {
                    String STREAM_URL = #####;  // here i put the URL of the song
                    mediaPlayer = new MediaPlayer();
                    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

                    try {
                        mediaPlayer.setDataSource(STREAM_URL);
                        mediaPlayer.prepare();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
            } catch (NullPointerException e) {
                Log.d(TAG, "run: NullPointerException = " + e.getMessage());
                FirebaseCrash.log("Tag = " + TAG + "run: NullPointerException = " + e.getMessage());
            }
        }
    }
};
handler.post(runnable);

Solution

  • Even though you are creating a Handler, the creation of the MediaPlayer still happens on the main UI thread. You should call prepareAsync or use an AsyncTask or some other means to avoid calling prepare on the main thread.

    From the documentation for Handler:

    When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it

    If you are streaming music from the network, preparing the media for playback is especially going to take a while. One option may be to call prepareAsync instead of calling prepare. In that case, you should set the OnPreparedListener, and in that callback call start.