小さなファイル(小さな画像、mp3ファイル)を1つの物理ファイルにパックするカスタムファイル形式(zipファイルに似ています)があります。私のAndroidアプリはこのファイルをダウンロードし、そこから1つの画像を表示します。ユーザーは画像に触れることができ、パックされたファイル内の小さなmp3「ファイル」の1つを再生し始めます。彼は左または右にスワイプすることもでき、アプリは前または次の画像を表示します。
物事をスムーズにするために、私はメモリに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();