我有一个自定义文件格式(类似于 zip 文件),可以将小文件(小图像、mp3 文件)打包成 1 个物理文件。我的安卓应用程序下载了这个文件,并显示了其中的一张图片。用户可以触摸图像,它将开始播放打包文件中的一个小 mp3"file"。他还可以向左或向右滑动,应用会显示上一张或下一张图片。
为了让事情更顺利,我在内存中保存了 3 张“卡片”:当前显示的一张,以及上一张和下一张。这样,当它被滑动时,我可以立即显示下一张图片。为此,我将图像和 mp3 预加载到 MediaPlayer 中。问题是因为它是多线程的,因为预加载是在后台完成的。我有一个错误:当我开始播放 mp3 时,在播放过程中我滑动,我预加载的图像在中间被切掉了。经过大量调试,我找到了原因:当我加载图像时,MediaPlayer 正在移动文件描述符中的文件指针,这导致下一次读取从 mp3 的中间而不是图像读取。
代码如下:
InputStream imageStream = myPackedFile.getBaseStream("cat.jpg"); // this returns an InputStream representing "cat.jpg" from my packed file (which is based on a RandomAccessFile)
Drawable image = Drawable.createFromStream(imageStream, imagePath);
FileDescriptor fd = myPackedFile.getFD();
long pos = myPackedFile.getPos("cat.mp3");
long len = myPackedFile.getLength("cat.mp3");
player.setDataSource(fd, pos, len);
player.prepare();
最佳答案
这对我有用:我创建了一个文件,而不是创建一个 RandomAccessFile 并保存它,每次我需要将它作为 RandomAccessFile 访问时,我创建一个新文件:
public class PackagedFile {
private File file;
PackagedFile(String filename) {
file = new File(filename);
}
public RandomAccessFile getRandomAccessFile() {
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(file, "r");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return raf;
}
}
上面的代码变成了:
InputStream imageStream = myPackedFile.getBaseStream("cat.jpg"); // this returns an InputStream representing "cat.jpg" from my packed file (which is based on a RandomAccessFile)
Drawable image = Drawable.createFromStream(imageStream, imagePath);
FileDescriptor fd = myPackedFile.getRandomAccessFile().getFD();
long pos = myPackedFile.getPos("cat.mp3");
long len = myPackedFile.getLength("cat.mp3");
player.setDataSource(fd, pos, len);
player.prepare();
关于android - 当 MediaPlayer 在不同的位置播放时,如何从只读的 RandomAccessFile 中读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15571415/