Fix seekbar preview crashes (#11584)
Fixed crashes from recycled bitmaps by creating real copies of bitmaps if necessary + some minor refactoring
This commit is contained in:
parent
035c394cf6
commit
eb9f300e60
1 changed files with 29 additions and 11 deletions
|
@ -132,17 +132,8 @@ public class SeekbarPreviewThumbnailHolder {
|
||||||
|
|
||||||
// Get the bounds where the frame is found
|
// Get the bounds where the frame is found
|
||||||
final int[] bounds = frameset.getFrameBoundsAt(currentPosMs);
|
final int[] bounds = frameset.getFrameBoundsAt(currentPosMs);
|
||||||
generatedDataForUrl.put(currentPosMs, () -> {
|
generatedDataForUrl.put(currentPosMs,
|
||||||
// It can happen, that the original bitmap could not be downloaded
|
createBitmapSupplier(srcBitMap, bounds, frameset));
|
||||||
// In such a case - we don't want a NullPointer - simply return null
|
|
||||||
if (srcBitMap == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cut out the corresponding bitmap form the "srcBitMap"
|
|
||||||
return Bitmap.createBitmap(srcBitMap, bounds[1], bounds[2],
|
|
||||||
frameset.getFrameWidth(), frameset.getFrameHeight());
|
|
||||||
});
|
|
||||||
|
|
||||||
currentPosMs += frameset.getDurationPerFrame();
|
currentPosMs += frameset.getDurationPerFrame();
|
||||||
pos++;
|
pos++;
|
||||||
|
@ -165,6 +156,33 @@ public class SeekbarPreviewThumbnailHolder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Supplier<Bitmap> createBitmapSupplier(final Bitmap srcBitMap,
|
||||||
|
final int[] bounds,
|
||||||
|
final Frameset frameset) {
|
||||||
|
return () -> {
|
||||||
|
// It can happen, that the original bitmap could not be downloaded
|
||||||
|
// (or it was recycled though that should not happen)
|
||||||
|
// In such a case - we don't want a NullPointer/
|
||||||
|
// "cannot use a recycled source in createBitmap" Exception -> simply return null
|
||||||
|
if (srcBitMap == null || srcBitMap.isRecycled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cut out the corresponding bitmap form the "srcBitMap"
|
||||||
|
final Bitmap cutOutBitmap = Bitmap.createBitmap(srcBitMap, bounds[1], bounds[2],
|
||||||
|
frameset.getFrameWidth(), frameset.getFrameHeight());
|
||||||
|
|
||||||
|
// If the cut out bitmap is identical to its source,
|
||||||
|
// we need to copy the bitmap to create a new instance.
|
||||||
|
// createBitmap allows itself to return the original object that is was created with
|
||||||
|
// this leads to recycled bitmaps being returned (if they are identical)
|
||||||
|
// Reference: https://stackoverflow.com/a/23683075 + first comment
|
||||||
|
// Fixes: https://github.com/TeamNewPipe/NewPipe/issues/11461
|
||||||
|
return cutOutBitmap == srcBitMap
|
||||||
|
? cutOutBitmap.copy(cutOutBitmap.getConfig(), true) : cutOutBitmap;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Bitmap getBitMapFrom(final String url) {
|
private Bitmap getBitMapFrom(final String url) {
|
||||||
if (url == null) {
|
if (url == null) {
|
||||||
|
|
Loading…
Reference in a new issue