Replace UniversalImageLoader with Picasso
This commit is contained in:
parent
9c5ac069d7
commit
fcef783bbb
32 changed files with 294 additions and 528 deletions
|
|
@ -18,6 +18,7 @@ import android.graphics.BitmapFactory;
|
|||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
|
|
@ -82,9 +83,9 @@ import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
|
|||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.android.exoplayer2.video.VideoListener;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
||||
import com.squareup.picasso.Picasso;
|
||||
import com.squareup.picasso.Target;
|
||||
import com.squareup.picasso.Transformation;
|
||||
|
||||
import org.schabi.newpipe.DownloaderImpl;
|
||||
import org.schabi.newpipe.MainActivity;
|
||||
|
|
@ -128,11 +129,11 @@ import org.schabi.newpipe.player.resolver.VideoPlaybackResolver;
|
|||
import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper;
|
||||
import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHolder;
|
||||
import org.schabi.newpipe.util.DeviceUtils;
|
||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
||||
import org.schabi.newpipe.util.external_communication.KoreUtils;
|
||||
import org.schabi.newpipe.util.ListHelper;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
import org.schabi.newpipe.util.PicassoHelper;
|
||||
import org.schabi.newpipe.util.SerializedCache;
|
||||
import org.schabi.newpipe.util.external_communication.KoreUtils;
|
||||
import org.schabi.newpipe.util.external_communication.ShareUtils;
|
||||
import org.schabi.newpipe.views.ExpandableSurfaceView;
|
||||
|
||||
|
|
@ -196,7 +197,6 @@ import static org.schabi.newpipe.util.Localization.containsCaseInsensitive;
|
|||
public final class Player implements
|
||||
EventListener,
|
||||
PlaybackListener,
|
||||
ImageLoadingListener,
|
||||
VideoListener,
|
||||
SeekBar.OnSeekBarChangeListener,
|
||||
View.OnClickListener,
|
||||
|
|
@ -250,6 +250,9 @@ public final class Player implements
|
|||
|
||||
private static final int RENDERER_UNAVAILABLE = -1;
|
||||
|
||||
private static final String PICASSO_PLAYER_TAG = "PICASSO_PLAYER_TAG";
|
||||
private static final String PICASSO_TRANSFORMATION_KEY = "PICASSO_TRANSFORMATION_KEY";
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Playback
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
|
@ -820,7 +823,7 @@ public final class Player implements
|
|||
|
||||
databaseUpdateDisposable.clear();
|
||||
progressUpdateDisposable.set(null);
|
||||
ImageLoader.getInstance().stop();
|
||||
PicassoHelper.cancelTag(PICASSO_PLAYER_TAG);
|
||||
|
||||
if (binding != null) {
|
||||
binding.endScreen.setImageBitmap(null);
|
||||
|
|
@ -1215,14 +1218,71 @@ public final class Player implements
|
|||
|
||||
private void initThumbnail(final String url) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Thumbnail - initThumbnail() called");
|
||||
Log.d(TAG, "Thumbnail - initThumbnail() called with url = ["
|
||||
+ (url == null ? "null" : url) + "]");
|
||||
}
|
||||
if (url == null || url.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ImageLoader.getInstance().resume();
|
||||
ImageLoader.getInstance()
|
||||
.loadImage(url, ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS, this);
|
||||
|
||||
// scale down the notification thumbnail for performance
|
||||
PicassoHelper.loadThumbnail(url)
|
||||
.tag(PICASSO_PLAYER_TAG)
|
||||
.transform(new Transformation() {
|
||||
@Override
|
||||
public Bitmap transform(final Bitmap source) {
|
||||
final float notificationThumbnailWidth = Math.min(
|
||||
context.getResources()
|
||||
.getDimension(R.dimen.player_notification_thumbnail_width),
|
||||
source.getWidth());
|
||||
return Bitmap.createScaledBitmap(
|
||||
source,
|
||||
(int) notificationThumbnailWidth,
|
||||
(int) (source.getHeight()
|
||||
/ (source.getWidth() / notificationThumbnailWidth)),
|
||||
true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String key() {
|
||||
return PICASSO_TRANSFORMATION_KEY;
|
||||
}
|
||||
})
|
||||
.into(new Target() {
|
||||
@Override
|
||||
public void onBitmapLoaded(final Bitmap bitmap, final Picasso.LoadedFrom from) {
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Thumbnail - onLoadingComplete() called with: "
|
||||
+ "url = [" + url + "], " + "loadedImage = [" + bitmap + " -> "
|
||||
+ bitmap.getWidth() + "x" + bitmap.getHeight()
|
||||
+ "], from = [" + from + "]");
|
||||
}
|
||||
|
||||
currentThumbnail = bitmap;
|
||||
NotificationUtil.getInstance()
|
||||
.createNotificationIfNeededAndUpdate(Player.this, false);
|
||||
// there is a new thumbnail, so changed the end screen thumbnail, too.
|
||||
updateEndScreenThumbnail();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBitmapFailed(final Exception e, final Drawable errorDrawable) {
|
||||
Log.e(TAG, "Thumbnail - onBitmapFailed() called with: url = ["
|
||||
+ url + "]", e);
|
||||
currentThumbnail = null;
|
||||
NotificationUtil.getInstance()
|
||||
.createNotificationIfNeededAndUpdate(Player.this, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareLoad(final Drawable placeHolderDrawable) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Thumbnail - onLoadingStarted() called with: url = ["
|
||||
+ url + "]");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1296,61 +1356,6 @@ public final class Player implements
|
|||
return Math.min(currentThumbnail.getHeight(), screenHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingStarted(final String imageUri, final View view) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Thumbnail - onLoadingStarted() called on: "
|
||||
+ "imageUri = [" + imageUri + "], view = [" + view + "]");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingFailed(final String imageUri, final View view,
|
||||
final FailReason failReason) {
|
||||
Log.e(TAG, "Thumbnail - onLoadingFailed() called on imageUri = [" + imageUri + "]",
|
||||
failReason.getCause());
|
||||
currentThumbnail = null;
|
||||
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingComplete(final String imageUri, final View view,
|
||||
final Bitmap loadedImage) {
|
||||
// scale down the notification thumbnail for performance
|
||||
final float notificationThumbnailWidth = Math.min(
|
||||
context.getResources().getDimension(R.dimen.player_notification_thumbnail_width),
|
||||
loadedImage.getWidth());
|
||||
currentThumbnail = Bitmap.createScaledBitmap(
|
||||
loadedImage,
|
||||
(int) notificationThumbnailWidth,
|
||||
(int) (loadedImage.getHeight()
|
||||
/ (loadedImage.getWidth() / notificationThumbnailWidth)),
|
||||
true);
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Thumbnail - onLoadingComplete() called with: "
|
||||
+ "imageUri = [" + imageUri + "], view = [" + view + "], "
|
||||
+ "loadedImage = [" + loadedImage + "], "
|
||||
+ loadedImage.getWidth() + "x" + loadedImage.getHeight()
|
||||
+ ", scaled notification width = " + notificationThumbnailWidth);
|
||||
}
|
||||
|
||||
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
|
||||
|
||||
// there is a new thumbnail, thus the end screen thumbnail needs to be changed, too.
|
||||
updateEndScreenThumbnail();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingCancelled(final String imageUri, final View view) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Thumbnail - onLoadingCancelled() called with: "
|
||||
+ "imageUri = [" + imageUri + "], view = [" + view + "]");
|
||||
}
|
||||
currentThumbnail = null;
|
||||
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
|
||||
}
|
||||
//endregion
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,11 +5,9 @@ import android.text.TextUtils;
|
|||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
||||
import org.schabi.newpipe.util.Localization;
|
||||
import org.schabi.newpipe.util.PicassoHelper;
|
||||
|
||||
public class PlayQueueItemBuilder {
|
||||
private static final String TAG = PlayQueueItemBuilder.class.toString();
|
||||
|
|
@ -35,8 +33,7 @@ public class PlayQueueItemBuilder {
|
|||
holder.itemDurationView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
ImageLoader.getInstance().displayImage(item.getThumbnailUrl(), holder.itemThumbnailView,
|
||||
ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS);
|
||||
PicassoHelper.loadThumbnail(item.getThumbnailUrl()).into(holder.itemThumbnailView);
|
||||
|
||||
holder.itemRoot.setOnClickListener(view -> {
|
||||
if (onItemClickListener != null) {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,18 @@
|
|||
package org.schabi.newpipe.player.seekbarpreview;
|
||||
|
||||
import static org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper.SeekbarPreviewThumbnailType;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Stopwatch;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
|
||||
import org.schabi.newpipe.extractor.stream.Frameset;
|
||||
import org.schabi.newpipe.util.ImageDisplayConstants;
|
||||
import org.schabi.newpipe.util.PicassoHelper;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
|
|
@ -21,11 +23,8 @@ import java.util.UUID;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper.SeekbarPreviewThumbnailType;
|
||||
|
||||
public class SeekbarPreviewThumbnailHolder {
|
||||
|
||||
// This has to be <= 23 chars on devices running Android 7 or lower (API <= 25)
|
||||
|
|
@ -174,6 +173,7 @@ public class SeekbarPreviewThumbnailHolder {
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Bitmap getBitMapFrom(final String url) {
|
||||
if (url == null) {
|
||||
Log.w(TAG, "url is null; This should never happen");
|
||||
|
|
@ -182,24 +182,11 @@ public class SeekbarPreviewThumbnailHolder {
|
|||
|
||||
final Stopwatch sw = Log.isLoggable(TAG, Log.DEBUG) ? Stopwatch.createStarted() : null;
|
||||
try {
|
||||
final SyncImageLoadingListener syncImageLoadingListener =
|
||||
new SyncImageLoadingListener();
|
||||
|
||||
Log.d(TAG, "Downloading bitmap for seekbarPreview from '" + url + "'");
|
||||
|
||||
// Ensure that everything is running
|
||||
ImageLoader.getInstance().resume();
|
||||
// Load the image
|
||||
// Impl-Note:
|
||||
// Gets the bitmap within the timeout of 15 seconds imposed by default by OkHttpClient
|
||||
// Ensure that your are not running on the main-Thread this will otherwise hang
|
||||
ImageLoader.getInstance().loadImage(
|
||||
url,
|
||||
ImageDisplayConstants.DISPLAY_SEEKBAR_PREVIEW_OPTIONS,
|
||||
syncImageLoadingListener);
|
||||
|
||||
// Get the bitmap within the timeout
|
||||
final Bitmap bitmap =
|
||||
syncImageLoadingListener.waitForBitmapOrThrow(30, TimeUnit.SECONDS);
|
||||
final Bitmap bitmap = PicassoHelper.loadSeekbarThumbnailPreview(url).get();
|
||||
|
||||
if (sw != null) {
|
||||
Log.d(TAG,
|
||||
|
|
|
|||
|
|
@ -1,87 +0,0 @@
|
|||
package org.schabi.newpipe.player.seekbarpreview;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.view.View;
|
||||
|
||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
||||
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
/**
|
||||
* Listener for synchronously downloading of an image/bitmap.
|
||||
*/
|
||||
public class SyncImageLoadingListener extends SimpleImageLoadingListener {
|
||||
|
||||
private final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
|
||||
private Bitmap bitmap;
|
||||
private boolean cancelled = false;
|
||||
private FailReason failReason = null;
|
||||
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
@Override
|
||||
public void onLoadingFailed(
|
||||
final String imageUri,
|
||||
final View view,
|
||||
final FailReason failReason) {
|
||||
|
||||
this.failReason = failReason;
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingComplete(
|
||||
final String imageUri,
|
||||
final View view,
|
||||
final Bitmap loadedImage) {
|
||||
|
||||
bitmap = loadedImage;
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingCancelled(final String imageUri, final View view) {
|
||||
cancelled = true;
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
|
||||
public Bitmap waitForBitmapOrThrow(final long timeout, final TimeUnit timeUnit)
|
||||
throws InterruptedException, TimeoutException {
|
||||
|
||||
// Wait for the download to finish
|
||||
if (!countDownLatch.await(timeout, timeUnit)) {
|
||||
throw new TimeoutException("Couldn't get the image in time");
|
||||
}
|
||||
|
||||
if (isCancelled()) {
|
||||
throw new CancellationException("Download of image was cancelled");
|
||||
}
|
||||
|
||||
if (getFailReason() != null) {
|
||||
throw new RuntimeException("Failed to download image" + getFailReason().getType(),
|
||||
getFailReason().getCause());
|
||||
}
|
||||
|
||||
if (getBitmap() == null) {
|
||||
throw new NullPointerException("Bitmap is null");
|
||||
}
|
||||
|
||||
return getBitmap();
|
||||
}
|
||||
|
||||
public Bitmap getBitmap() {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
public FailReason getFailReason() {
|
||||
return failReason;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue