1

小さなファイル(小さな画像、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();
4

2 に答える 2

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();
于 2013-03-23T19:31:53.600 に答える
1

APIレベル13以上の場合ParcelFileDescriptor.dup、ファイル記述子を複製することを検討できます。詳細については、次のリンクを参照してください:http: //androidxref.com/4.2.2_r1/xref/frameworks/base/core/java/android/app/ActivityThread.java#864

于 2013-03-24T00:21:25.197 に答える