在阅读“Media Playback”和“MediaPlayer”Android文档后,我仍然感到困惑,需要有关setDataSource重载方法的经验丰富的建议。
我在我的项目中的MediaPlayer
组件中使用Service
,在播放音乐时将会是foregroundService。我在我的apk的res/raw
文件夹中有我的音乐文件(.mp3)。
要开始播放,我知道我必须准备MediaPlayer对象。因为Android应用程序中的服务默认使用单个进程和主线程,所以我不希望我的用户得到ANR
而MediaPlayer准备自己(想想原始文件夹中的媒体文件是否有大尺寸)。
然后我使用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();
最后我的问题出现了“包括这些不同的方法,哪一个是最好的选择?一方面有什么好处?我错过了什么吗?”
答案 0 :(得分:8)
调用create
或setDataSource
的各种方式没有任何实际好处。静态create
方法不仅仅是调用setDataSource
和prepare
。各种setDataSource
方法在内部相互调用。最终它们归结为两个可能的本机调用,一个带有描述远程URI的字符串,另一个带有本地文件描述符。自己创建文件描述符可能会有非常轻微的性能优势,但在上下文中它不会很明显。
对于本地文件播放,正如您在代码中演示的那样,简单地调用prepare
(或静态create
方法)根本不是一个坏习惯。无论文件大小如何,底层播放器都应该没有问题确定相关元数据并快速返回。 prepareAsync
方法对网络流更有用,其中任何数量的情况都可能导致一些意外延迟。如果您正在设计一个通用播放器,那么使用prepareAsync
方法将是可行的方法,但如果您只是在玩原始资产,它应该没有任何区别。提供的各种方法只是为了方便(请注意create
的javadoc)。