After reading "Media Playback" and "MediaPlayer" android documentations I'm still confused and need experienced advice about setDataSource overloaded method.
I am using MediaPlayer
in a Service
component in my Project that is going to be a foregroundService while playing music. I have my music file(.mp3) in res/raw
folder of my apk.
To start playing, I know I have to prepare the MediaPlayer object. Because Services in android applications by default uses single process and main thread, I don't want my users get ANR
while MediaPlayer prepares itself(think if media file in raw folder has a big size).
Then I use prepareAsync
instead of prepare
(Sync). So I can not use:
mp = MediaPlayer.create(context, R.raw.myfile);
Because this already calls prepare()
internally but not prepareAsync()
.
So basically i have two options(two from four):
Uri myUri = Uri.parse("android.resource://" + context.getPackageName() + "/" + R.raw.myfile);
mp.setDataSource(context, myUri);
or
AssetFileDescriptor afd = context.getResources().openRawResourceFd(R.raw.myfile);
mp.setDataSource(fd.getFileDescriptor());
afd.close();
after using one of them I can simple use:
mp.prepareAsync();
And finally my questions arise that "including these different methods, which one is the best option? Are there any benefits one over the other? Do i missing something?"
There aren't any real benefits to the various ways of calling create
or setDataSource
. The static create
methods don't do much more than call setDataSource
and prepare
. The various setDataSource
methods call each other internally. Eventually they boil down to two possible native calls, one with a string describing a remote URI and another with a local file descriptor. There may be a very slight performance advantage to creating the file descriptor yourself, but it will not be appreciable in context.
For local file playback, as you are demonstrating in your code, simply calling prepare
(or the static create
methods) isn't a bad practice at all. The underlying player should have no problem determining the relevant metadata and returning quickly no matter the size of the file. The prepareAsync
method is more useful for network streams, where any number of situations might cause some unexpected delay. If you are designing a general purpose player, then using the prepareAsync
method would be the way to go, but if you are simply playing raw assets it shouldn't make any difference. The variety of methods provided is simply a matter of convenience (take note of the javadoc for create
).