【问题标题】:MediaPlayer setDataSource need best practice adviceMediaPlayer setDataSource 需要最佳实践建议
【发布时间】:2013-09-24 09:32:29
【问题描述】:

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

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

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();

最后我的问题是“包括这些不同的方法,哪一种是最好的选择?是否有任何好处?我错过了什么吗?”

【问题讨论】:

  • 我个人喜欢最后一种方法,因为它在代码中不使用字符串。不过,我现在不认为这算得上“好处”。
  • @Geobits,据我所知,避免在代码中使用常量字符串是一个好习惯,但 FileDescriptor 是 android 更喜欢本地文件。感谢您的评论。我建议您阅读我对已接受答案的评论。

标签: android media-player


【解决方案1】:

调用createsetDataSource 的各种方式没有任何实际好处。静态的create 方法除了调用setDataSourceprepare 之外没有什么作用。各种setDataSource 方法在内部相互调用。最终,它们归结为两种可能的本机调用,一种使用描述远程 URI 的字符串,另一种使用本地文件描述符。自己创建文件描述符可能会带来非常轻微的性能优势,但在上下文中并不明显。

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

【讨论】:

  • 阅读您的回答后,我查看了android framework 并了解您所说的内容。我看到了private native void _setDataSource 方法并注意到setDataSource(FileDescriptor fd, long offset, long length) 方法在本地访问中更常见。我大致推断出FileDescriptors 用于本地,Uris 用于远程(流)目的。
猜你喜欢
  • 1970-01-01
  • 2019-04-10
  • 1970-01-01
  • 2013-08-15
  • 1970-01-01
  • 1970-01-01
  • 2012-11-15
  • 2012-03-06
  • 1970-01-01
相关资源
最近更新 更多