Skip to content

Commit 844b4ed

Browse files
Migrate to Coil from Picasso
1 parent 92a7f22 commit 844b4ed

25 files changed

Lines changed: 226 additions & 173 deletions

app/src/main/java/org/schabi/newpipe/App.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
import org.schabi.newpipe.ktx.ExceptionUtils;
2121
import org.schabi.newpipe.settings.NewPipeSettings;
2222
import org.schabi.newpipe.util.Localization;
23-
import org.schabi.newpipe.util.image.ImageStrategy;
24-
import org.schabi.newpipe.util.image.PicassoHelper;
2523
import org.schabi.newpipe.util.ServiceHelper;
2624
import org.schabi.newpipe.util.StateSaver;
25+
import org.schabi.newpipe.util.image.ImageStrategy;
26+
import org.schabi.newpipe.util.image.PicassoHelper;
2727
import org.schabi.newpipe.util.image.PreferredImageQuality;
2828

2929
import java.io.IOException;
@@ -32,6 +32,11 @@
3232
import java.util.List;
3333
import java.util.Objects;
3434

35+
import coil.ImageLoader;
36+
import coil.ImageLoaderFactory;
37+
import coil.disk.DiskCache;
38+
import coil.memory.MemoryCache;
39+
import coil.util.DebugLogger;
3540
import io.reactivex.rxjava3.exceptions.CompositeException;
3641
import io.reactivex.rxjava3.exceptions.MissingBackpressureException;
3742
import io.reactivex.rxjava3.exceptions.OnErrorNotImplementedException;
@@ -57,7 +62,7 @@
5762
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
5863
*/
5964

60-
public class App extends Application {
65+
public class App extends Application implements ImageLoaderFactory {
6166
public static final String PACKAGE_NAME = BuildConfig.APPLICATION_ID;
6267
private static final String TAG = App.class.toString();
6368

@@ -118,10 +123,25 @@ public void onCreate() {
118123
configureRxJavaErrorHandler();
119124
}
120125

126+
@NonNull
121127
@Override
122-
public void onTerminate() {
123-
super.onTerminate();
124-
PicassoHelper.terminate();
128+
public ImageLoader newImageLoader() {
129+
final var builder = new ImageLoader.Builder(this)
130+
.memoryCache(() -> new MemoryCache.Builder(this)
131+
.maxSizeBytes(10 * 1024 * 1024)
132+
.build())
133+
.diskCache(() -> new DiskCache.Builder()
134+
.maxSizeBytes(50 * 1024 * 1024)
135+
.build())
136+
.allowRgb565(true);
137+
138+
final var prefs = PreferenceManager.getDefaultSharedPreferences(this);
139+
if (MainActivity.DEBUG
140+
&& prefs.getBoolean(getString(R.string.show_image_indicators_key), false)) {
141+
builder.logger(new DebugLogger());
142+
}
143+
144+
return builder.build();
125145
}
126146

127147
protected Downloader getDownloader() {

app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@
116116
import org.schabi.newpipe.util.ThemeHelper;
117117
import org.schabi.newpipe.util.external_communication.KoreUtils;
118118
import org.schabi.newpipe.util.external_communication.ShareUtils;
119-
import org.schabi.newpipe.util.image.PicassoHelper;
119+
import org.schabi.newpipe.util.image.CoilHelper;
120120

121121
import java.util.ArrayList;
122122
import java.util.Iterator;
@@ -127,6 +127,7 @@
127127
import java.util.concurrent.TimeUnit;
128128
import java.util.function.Consumer;
129129

130+
import coil.util.CoilUtils;
130131
import icepick.State;
131132
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
132133
import io.reactivex.rxjava3.disposables.CompositeDisposable;
@@ -1471,7 +1472,10 @@ public void showLoading() {
14711472
}
14721473
}
14731474

1474-
PicassoHelper.cancelTag(PICASSO_VIDEO_DETAILS_TAG);
1475+
CoilUtils.dispose(binding.detailThumbnailImageView);
1476+
CoilUtils.dispose(binding.detailSubChannelThumbnailView);
1477+
CoilUtils.dispose(binding.overlayThumbnail);
1478+
14751479
binding.detailThumbnailImageView.setImageBitmap(null);
14761480
binding.detailSubChannelThumbnailView.setImageBitmap(null);
14771481
}
@@ -1562,8 +1566,8 @@ public void handleResult(@NonNull final StreamInfo info) {
15621566
binding.detailSecondaryControlPanel.setVisibility(View.GONE);
15631567

15641568
checkUpdateProgressInfo(info);
1565-
PicassoHelper.loadDetailsThumbnail(info.getThumbnails()).tag(PICASSO_VIDEO_DETAILS_TAG)
1566-
.into(binding.detailThumbnailImageView);
1569+
CoilHelper.INSTANCE.loadDetailsThumbnail(binding.detailThumbnailImageView,
1570+
info.getThumbnails());
15671571
showMetaInfoInTextView(info.getMetaInfo(), binding.detailMetaInfoTextView,
15681572
binding.detailMetaInfoSeparator, disposables);
15691573

@@ -1613,8 +1617,8 @@ private void displayUploaderAsSubChannel(final StreamInfo info) {
16131617
binding.detailUploaderTextView.setVisibility(View.GONE);
16141618
}
16151619

1616-
PicassoHelper.loadAvatar(info.getUploaderAvatars()).tag(PICASSO_VIDEO_DETAILS_TAG)
1617-
.into(binding.detailSubChannelThumbnailView);
1620+
CoilHelper.INSTANCE.loadAvatar(binding.detailSubChannelThumbnailView,
1621+
info.getUploaderAvatars());
16181622
binding.detailSubChannelThumbnailView.setVisibility(View.VISIBLE);
16191623
binding.detailUploaderThumbnailView.setVisibility(View.GONE);
16201624
}
@@ -1645,11 +1649,11 @@ private void displayBothUploaderAndSubChannel(final StreamInfo info) {
16451649
binding.detailUploaderTextView.setVisibility(View.GONE);
16461650
}
16471651

1648-
PicassoHelper.loadAvatar(info.getSubChannelAvatars()).tag(PICASSO_VIDEO_DETAILS_TAG)
1649-
.into(binding.detailSubChannelThumbnailView);
1652+
CoilHelper.INSTANCE.loadAvatar(binding.detailSubChannelThumbnailView,
1653+
info.getSubChannelAvatars());
16501654
binding.detailSubChannelThumbnailView.setVisibility(View.VISIBLE);
1651-
PicassoHelper.loadAvatar(info.getUploaderAvatars()).tag(PICASSO_VIDEO_DETAILS_TAG)
1652-
.into(binding.detailUploaderThumbnailView);
1655+
CoilHelper.INSTANCE.loadAvatar(binding.detailUploaderThumbnailView,
1656+
info.getUploaderAvatars());
16531657
binding.detailUploaderThumbnailView.setVisibility(View.VISIBLE);
16541658
}
16551659

@@ -2403,8 +2407,7 @@ private void updateOverlayData(@Nullable final String overlayTitle,
24032407
binding.overlayTitleTextView.setText(isEmpty(overlayTitle) ? "" : overlayTitle);
24042408
binding.overlayChannelTextView.setText(isEmpty(uploader) ? "" : uploader);
24052409
binding.overlayThumbnail.setImageDrawable(null);
2406-
PicassoHelper.loadDetailsThumbnail(thumbnails).tag(PICASSO_VIDEO_DETAILS_TAG)
2407-
.into(binding.overlayThumbnail);
2410+
CoilHelper.INSTANCE.loadDetailsThumbnail(binding.overlayThumbnail, thumbnails);
24082411
}
24092412

24102413
private void setOverlayPlayPauseImage(final boolean playerIsPlaying) {

app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,11 @@
5050
import org.schabi.newpipe.util.Localization;
5151
import org.schabi.newpipe.util.NavigationHelper;
5252
import org.schabi.newpipe.util.StateSaver;
53-
import org.schabi.newpipe.util.image.ImageStrategy;
54-
import org.schabi.newpipe.util.image.PicassoHelper;
5553
import org.schabi.newpipe.util.ThemeHelper;
5654
import org.schabi.newpipe.util.external_communication.ShareUtils;
55+
import org.schabi.newpipe.util.image.CoilHelper;
56+
import org.schabi.newpipe.util.image.ImageStrategy;
57+
import org.schabi.newpipe.util.image.PicassoHelper;
5758

5859
import java.util.List;
5960
import java.util.Queue;
@@ -587,17 +588,15 @@ public void handleResult(@NonNull final ChannelInfo result) {
587588
setInitialData(result.getServiceId(), result.getOriginalUrl(), result.getName());
588589

589590
if (ImageStrategy.shouldLoadImages() && !result.getBanners().isEmpty()) {
590-
PicassoHelper.loadBanner(result.getBanners()).tag(PICASSO_CHANNEL_TAG)
591-
.into(binding.channelBannerImage);
591+
CoilHelper.INSTANCE.loadBanner(binding.channelBannerImage, result.getBanners());
592592
} else {
593593
// do not waste space for the banner, if the user disabled images or there is not one
594594
binding.channelBannerImage.setImageDrawable(null);
595595
}
596596

597-
PicassoHelper.loadAvatar(result.getAvatars()).tag(PICASSO_CHANNEL_TAG)
598-
.into(binding.channelAvatarView);
599-
PicassoHelper.loadAvatar(result.getParentChannelAvatars()).tag(PICASSO_CHANNEL_TAG)
600-
.into(binding.subChannelAvatarView);
597+
CoilHelper.INSTANCE.loadAvatar(binding.channelAvatarView, result.getAvatars());
598+
CoilHelper.INSTANCE.loadAvatar(binding.subChannelAvatarView,
599+
result.getParentChannelAvatars());
601600

602601
binding.channelTitleView.setText(result.getName());
603602
binding.channelSubscriberView.setVisibility(View.VISIBLE);

app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
import org.schabi.newpipe.util.ExtractorHelper;
2424
import org.schabi.newpipe.util.Localization;
2525
import org.schabi.newpipe.util.NavigationHelper;
26+
import org.schabi.newpipe.util.image.CoilHelper;
2627
import org.schabi.newpipe.util.image.ImageStrategy;
27-
import org.schabi.newpipe.util.image.PicassoHelper;
2828
import org.schabi.newpipe.util.text.TextLinkifier;
2929

3030
import java.util.Queue;
@@ -82,7 +82,7 @@ protected Supplier<View> getListHeaderSupplier() {
8282
final CommentsInfoItem item = commentsInfoItem;
8383

8484
// load the author avatar
85-
PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(binding.authorAvatar);
85+
CoilHelper.INSTANCE.loadAvatar(binding.authorAvatar, item.getUploaderAvatars());
8686
binding.authorAvatar.setVisibility(ImageStrategy.shouldLoadImages()
8787
? View.VISIBLE : View.GONE);
8888

app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import org.schabi.newpipe.util.NavigationHelper;
5454
import org.schabi.newpipe.util.PlayButtonHelper;
5555
import org.schabi.newpipe.util.external_communication.ShareUtils;
56+
import org.schabi.newpipe.util.image.CoilHelper;
5657
import org.schabi.newpipe.util.image.PicassoHelper;
5758
import org.schabi.newpipe.util.text.TextEllipsizer;
5859

@@ -327,8 +328,8 @@ public void handleResult(@NonNull final PlaylistInfo result) {
327328
R.drawable.ic_radio)
328329
);
329330
} else {
330-
PicassoHelper.loadAvatar(result.getUploaderAvatars()).tag(PICASSO_PLAYLIST_TAG)
331-
.into(headerBinding.uploaderAvatarView);
331+
CoilHelper.INSTANCE.loadAvatar(headerBinding.uploaderAvatarView,
332+
result.getUploaderAvatars());
332333
}
333334

334335
streamCount = result.getStreamCount();
Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,51 @@
11
package org.schabi.newpipe.info_list
22

33
import android.view.View
4-
import android.widget.ImageView
5-
import android.widget.TextView
6-
import com.xwray.groupie.GroupieViewHolder
7-
import com.xwray.groupie.Item
4+
import com.xwray.groupie.viewbinding.BindableItem
5+
import com.xwray.groupie.viewbinding.GroupieViewHolder
86
import org.schabi.newpipe.R
7+
import org.schabi.newpipe.databinding.ItemStreamSegmentBinding
98
import org.schabi.newpipe.extractor.stream.StreamSegment
109
import org.schabi.newpipe.util.Localization
11-
import org.schabi.newpipe.util.image.PicassoHelper
10+
import org.schabi.newpipe.util.image.CoilHelper
1211

1312
class StreamSegmentItem(
1413
private val item: StreamSegment,
1514
private val onClick: StreamSegmentAdapter.StreamSegmentListener
16-
) : Item<GroupieViewHolder>() {
15+
) : BindableItem<ItemStreamSegmentBinding>() {
1716

1817
companion object {
1918
const val PAYLOAD_SELECT = 1
2019
}
2120

2221
var isSelected = false
2322

24-
override fun bind(viewHolder: GroupieViewHolder, position: Int) {
25-
item.previewUrl?.let {
26-
PicassoHelper.loadThumbnail(it)
27-
.into(viewHolder.root.findViewById<ImageView>(R.id.previewImage))
28-
}
29-
viewHolder.root.findViewById<TextView>(R.id.textViewTitle).text = item.title
23+
override fun bind(viewBinding: ItemStreamSegmentBinding, position: Int) {
24+
CoilHelper.loadThumbnail(viewBinding.previewImage, item.previewUrl)
25+
viewBinding.textViewTitle.text = item.title
3026
if (item.channelName == null) {
31-
viewHolder.root.findViewById<TextView>(R.id.textViewChannel).visibility = View.GONE
27+
viewBinding.textViewChannel.visibility = View.GONE
3228
// When the channel name is displayed there is less space
3329
// and thus the segment title needs to be only one line height.
3430
// But when there is no channel name displayed, the title can be two lines long.
3531
// The default maxLines value is set to 1 to display all elements in the AS preview,
36-
viewHolder.root.findViewById<TextView>(R.id.textViewTitle).maxLines = 2
32+
viewBinding.textViewTitle.maxLines = 2
3733
} else {
38-
viewHolder.root.findViewById<TextView>(R.id.textViewChannel).text = item.channelName
39-
viewHolder.root.findViewById<TextView>(R.id.textViewChannel).visibility = View.VISIBLE
34+
viewBinding.textViewChannel.text = item.channelName
35+
viewBinding.textViewChannel.visibility = View.VISIBLE
4036
}
41-
viewHolder.root.findViewById<TextView>(R.id.textViewStartSeconds).text =
37+
viewBinding.textViewStartSeconds.text =
4238
Localization.getDurationString(item.startTimeSeconds.toLong())
43-
viewHolder.root.setOnClickListener { onClick.onItemClick(this, item.startTimeSeconds) }
44-
viewHolder.root.setOnLongClickListener { onClick.onItemLongClick(this, item.startTimeSeconds); true }
45-
viewHolder.root.isSelected = isSelected
39+
viewBinding.root.setOnClickListener { onClick.onItemClick(this, item.startTimeSeconds) }
40+
viewBinding.root.setOnLongClickListener { onClick.onItemLongClick(this, item.startTimeSeconds); true }
41+
viewBinding.root.isSelected = isSelected
4642
}
4743

48-
override fun bind(viewHolder: GroupieViewHolder, position: Int, payloads: MutableList<Any>) {
44+
override fun bind(
45+
viewHolder: GroupieViewHolder<ItemStreamSegmentBinding>,
46+
position: Int,
47+
payloads: MutableList<Any>
48+
) {
4949
if (payloads.contains(PAYLOAD_SELECT)) {
5050
viewHolder.root.isSelected = isSelected
5151
return
@@ -54,4 +54,6 @@ class StreamSegmentItem(
5454
}
5555

5656
override fun getLayout() = R.layout.item_stream_segment
57+
58+
override fun initializeViewBinding(view: View) = ItemStreamSegmentBinding.bind(view)
5759
}

app/src/main/java/org/schabi/newpipe/info_list/holder/ChannelMiniInfoItemHolder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
import org.schabi.newpipe.extractor.utils.Utils;
1414
import org.schabi.newpipe.info_list.InfoItemBuilder;
1515
import org.schabi.newpipe.local.history.HistoryRecordManager;
16-
import org.schabi.newpipe.util.image.PicassoHelper;
1716
import org.schabi.newpipe.util.Localization;
17+
import org.schabi.newpipe.util.image.CoilHelper;
1818

1919
public class ChannelMiniInfoItemHolder extends InfoItemHolder {
2020
private final ImageView itemThumbnailView;
@@ -56,7 +56,7 @@ public void updateFromItem(final InfoItem infoItem,
5656
itemAdditionalDetailView.setText(getDetailLine(item));
5757
}
5858

59-
PicassoHelper.loadAvatar(item.getThumbnails()).into(itemThumbnailView);
59+
CoilHelper.INSTANCE.loadAvatar(itemThumbnailView, item.getThumbnails());
6060

6161
itemView.setOnClickListener(view -> {
6262
if (itemBuilder.getOnChannelSelectedListener() != null) {

app/src/main/java/org/schabi/newpipe/info_list/holder/CommentInfoItemHolder.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
import org.schabi.newpipe.util.Localization;
2828
import org.schabi.newpipe.util.NavigationHelper;
2929
import org.schabi.newpipe.util.external_communication.ShareUtils;
30+
import org.schabi.newpipe.util.image.CoilHelper;
3031
import org.schabi.newpipe.util.image.ImageStrategy;
31-
import org.schabi.newpipe.util.image.PicassoHelper;
3232
import org.schabi.newpipe.util.text.TextEllipsizer;
3333

3434
public class CommentInfoItemHolder extends InfoItemHolder {
@@ -82,14 +82,12 @@ public CommentInfoItemHolder(final InfoItemBuilder infoItemBuilder,
8282
@Override
8383
public void updateFromItem(final InfoItem infoItem,
8484
final HistoryRecordManager historyRecordManager) {
85-
if (!(infoItem instanceof CommentsInfoItem)) {
85+
if (!(infoItem instanceof CommentsInfoItem item)) {
8686
return;
8787
}
88-
final CommentsInfoItem item = (CommentsInfoItem) infoItem;
89-
9088

9189
// load the author avatar
92-
PicassoHelper.loadAvatar(item.getUploaderAvatars()).into(itemThumbnailView);
90+
CoilHelper.INSTANCE.loadAvatar(itemThumbnailView, item.getUploaderAvatars());
9391
if (ImageStrategy.shouldLoadImages()) {
9492
itemThumbnailView.setVisibility(View.VISIBLE);
9593
itemRoot.setPadding(commentVerticalPadding, commentVerticalPadding,

app/src/main/java/org/schabi/newpipe/info_list/holder/PlaylistMiniInfoItemHolder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
1010
import org.schabi.newpipe.info_list.InfoItemBuilder;
1111
import org.schabi.newpipe.local.history.HistoryRecordManager;
12-
import org.schabi.newpipe.util.image.PicassoHelper;
1312
import org.schabi.newpipe.util.Localization;
13+
import org.schabi.newpipe.util.image.CoilHelper;
1414

1515
public class PlaylistMiniInfoItemHolder extends InfoItemHolder {
1616
public final ImageView itemThumbnailView;
@@ -46,7 +46,7 @@ public void updateFromItem(final InfoItem infoItem,
4646
.localizeStreamCountMini(itemStreamCountView.getContext(), item.getStreamCount()));
4747
itemUploaderView.setText(item.getUploaderName());
4848

49-
PicassoHelper.loadPlaylistThumbnail(item.getThumbnails()).into(itemThumbnailView);
49+
CoilHelper.INSTANCE.loadPlaylistThumbnail(itemThumbnailView, item.getThumbnails());
5050

5151
itemView.setOnClickListener(view -> {
5252
if (itemBuilder.getOnPlaylistSelectedListener() != null) {

app/src/main/java/org/schabi/newpipe/info_list/holder/StreamMiniInfoItemHolder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
import org.schabi.newpipe.local.history.HistoryRecordManager;
1717
import org.schabi.newpipe.util.DependentPreferenceHelper;
1818
import org.schabi.newpipe.util.Localization;
19-
import org.schabi.newpipe.util.image.PicassoHelper;
2019
import org.schabi.newpipe.util.StreamTypeUtil;
20+
import org.schabi.newpipe.util.image.CoilHelper;
2121
import org.schabi.newpipe.views.AnimatedProgressBar;
2222

2323
import java.util.concurrent.TimeUnit;
@@ -87,7 +87,7 @@ public void updateFromItem(final InfoItem infoItem,
8787
}
8888

8989
// Default thumbnail is shown on error, while loading and if the url is empty
90-
PicassoHelper.loadThumbnail(item.getThumbnails()).into(itemThumbnailView);
90+
CoilHelper.INSTANCE.loadThumbnail(itemThumbnailView, item.getThumbnails());
9191

9292
itemView.setOnClickListener(view -> {
9393
if (itemBuilder.getOnStreamSelectedListener() != null) {

0 commit comments

Comments
 (0)