Я столкнулся с ситуацией, когда мне приходится показывать изображения в слайд-шоу, которое очень быстро переключает изображение. Огромное количество изображений заставляет меня хотеть хранить данные JPEG в памяти и декодировать их, когда я хочу их отображать. Чтобы облегчить сборщик мусора, я использую BitmapFactory.Options.inBitmap для повторного использования растровых изображений.
К сожалению, это приводит к довольно сильному разрыву, я пробовал разные решения, такие как синхронизация, семафоры, чередующиеся между 2-3 растровыми изображениями, однако ни одна из них не устраняет проблему.
Я создал пример проекта, который демонстрирует эту проблему в GitHub; https://github.com/Berglund/android-tearing-example
У меня есть поток, который декодирует растровое изображение, устанавливает его в потоке пользовательского интерфейса и спит в течение 5 мс:
Runnable runnable = new Runnable() {
@Override
public void run() {
while(true) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1;
if(bitmap != null) {
options.inBitmap = bitmap;
}
bitmap = BitmapFactory.decodeResource(getResources(), images.get(position), options);
runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
try {
Thread.sleep(5);
} catch (InterruptedException e) {}
position++;
if(position >= images.size())
position = 0;
}
}
};
Thread t = new Thread(runnable);
t.start();
Моя идея заключается в том, что ImageView.setImageBitmap(Bitmap) рисует растровое изображение на следующем vsync, однако мы, вероятно, уже расшифровываем следующий битмап, когда это происходит, и поэтому мы начали изменять растровые пиксели. Думаю ли я в правильном направлении?
У кого-нибудь есть какие-то советы о том, куда идти отсюда?