我有一个自定义文件格式(类似于zip文件),它将小文件(小图像,mp3文件)打包成1个物理文件。我的Android应用程序下载此文件,它会显示一个图像。用户可以触摸图像,它将开始播放其中一个小mp3"文件"在打包文件中。他也可以向左或向右滑动,应用程序会显示上一张或下一张图片。
为了让事情变得更顺畅,我持有3"卡"在记忆中:当前显示的那个,以及前一个和下一个。这样,当它被刷过时,我可以立即显示下一张图像。为了做到这一点,我正在将图像和mp3预加载到MediaPlayer中。问题是因为它是多线程的,因为预加载是在后台完成的。我有一个错误:当我开始播放mp3时,在它播放过程中我会滑动,我preaload的图像在中间切割。经过大量调试后,我找到了原因:当我加载图像时,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();
答案 0 :(得分:1)
这对我有用:我创建一个文件,而不是创建一个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();
答案 1 :(得分:1)
对于API Level 13及更高版本,可以考虑ParcelFileDescriptor.dup
复制文件描述符。有关详细信息,请参阅此链接:http://androidxref.com/4.2.2_r1/xref/frameworks/base/core/java/android/app/ActivityThread.java#864