7

阅读“ Media Playback ”和“ MediaPlayer ”android 文档后,我仍然感到困惑,需要有关setDataSource重载方法的经验丰富的建议。

我在我的项目中使用MediaPlayer一个组件,该组件在播放音乐时Service将成为前台服务。res/raw我的 apk 文件夹中有我的音乐文件(.mp3) 。要开始播放,我知道我必须准备 MediaPlayer 对象。因为android应用程序中的服务默认使用单进程和主线程,所以我不希望我的用户在MediaPlayer自行准备时获得ANR (想想原始文件夹中的媒体文件是否很大)。然后我使用prepareAsync而不是prepare(同步)。所以我不能使用:

mp = MediaPlayer.create(context, R.raw.myfile);

因为这已经在内部调用prepare()但不是prepareAsync(). 所以基本上我有两个选择(四个中的两个):

Uri myUri = Uri.parse("android.resource://" + context.getPackageName() + "/" + R.raw.myfile);
mp.setDataSource(context, myUri);

或者

AssetFileDescriptor afd = context.getResources().openRawResourceFd(R.raw.myfile);
mp.setDataSource(fd.getFileDescriptor());
afd.close();

使用其中之一后,我可以简单地使用:

mp.prepareAsync();

最后我的问题出现了“包括这些不同的方法,哪一种是最好的选择?有没有比另一种更好的好处?我错过了什么吗?”

4

1 回答 1

8

create调用或的各种方式并没有任何真正的好处setDataSource。静态create方法除了 callsetDataSourceprepare. 各种setDataSource方法在内部相互调用。最终,它们归结为两种可能的本机调用,一种使用描述远程 URI 的字符串,另一种使用本地文件描述符。自己创建文件描述符可能会有非常小的性能优势,但在上下文中不会明显。

对于本地文件播放,正如您在代码中演示的那样,简单地调用prepare(或静态create方法)根本不是一个坏习惯。无论文件大小,底层播放器都应该可以毫无问题地确定相关元数据并快速返回。该prepareAsync方法对于网络流更有用,其中任何数量的情况都可能导致一些意外延迟。如果您正在设计通用播放器,那么使用该prepareAsync方法将是可行的方法,但如果您只是在播放原始资产,则应该没有任何区别。提供的各种方法只是为了方便(注意 javadoc for create)。

于 2013-09-27T16:45:08.190 回答