From 6f9deea873d9504eb06182b12aef6f3f22cf2e39 Mon Sep 17 00:00:00 2001 From: John Zhen Mo Date: Mon, 29 Jan 2018 18:06:48 -0800 Subject: [PATCH] -Fixed memory leak due to image loader overusing memory cache. -Added disk cache for local item loading. --- app/src/main/java/org/schabi/newpipe/App.java | 5 ++++- .../newpipe/fragments/local/LocalItemBuilder.java | 9 +++++++-- .../newpipe/fragments/local/LocalItemListAdapter.java | 8 ++++---- .../fragments/local/LocalPlaylistFragment.java | 2 +- .../newpipe/fragments/local/PlaylistAppendDialog.java | 2 +- .../fragments/local/bookmark/BookmarkFragment.java | 2 +- .../local/bookmark/StatisticsPlaylistFragment.java | 2 +- .../fragments/local/holder/LocalItemHolder.java | 7 +++++++ .../local/holder/LocalPlaylistItemHolder.java | 3 +-- .../local/holder/LocalPlaylistStreamItemHolder.java | 5 +++-- .../local/holder/LocalStatisticStreamItemHolder.java | 11 +++-------- 11 files changed, 33 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/App.java b/app/src/main/java/org/schabi/newpipe/App.java index 49f73853b..c182bfcfe 100644 --- a/app/src/main/java/org/schabi/newpipe/App.java +++ b/app/src/main/java/org/schabi/newpipe/App.java @@ -10,6 +10,7 @@ import android.content.Intent; import android.os.Build; import android.util.Log; +import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; @@ -80,7 +81,9 @@ public class App extends Application { initNotificationChannel(); // Initialize image loader - ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this).build(); + ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this) + .memoryCache(new WeakMemoryCache()) + .build(); ImageLoader.getInstance().init(config); configureRxJavaErrorHandler(); diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/LocalItemBuilder.java b/app/src/main/java/org/schabi/newpipe/fragments/local/LocalItemBuilder.java index ca200cc8a..128daf435 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/local/LocalItemBuilder.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/local/LocalItemBuilder.java @@ -1,8 +1,12 @@ package org.schabi.newpipe.fragments.local; import android.content.Context; +import android.graphics.Bitmap; +import android.widget.ImageView; +import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; +import com.nostra13.universalimageloader.core.process.BitmapProcessor; import org.schabi.newpipe.database.LocalItem; @@ -42,8 +46,9 @@ public class LocalItemBuilder { return context; } - public ImageLoader getImageLoader() { - return imageLoader; + public void displayImage(final String url, final ImageView view, + final DisplayImageOptions options) { + imageLoader.displayImage(url, view, options); } public OnLocalItemGesture getOnItemSelectedListener() { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/LocalItemListAdapter.java b/app/src/main/java/org/schabi/newpipe/fragments/local/LocalItemListAdapter.java index 0e012aad7..35112a6a5 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/local/LocalItemListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/local/LocalItemListAdapter.java @@ -69,10 +69,10 @@ public class LocalItemListAdapter extends RecyclerView.Adapter data) { + public void addItems(List data) { if (data != null) { if (DEBUG) { - Log.d(TAG, "addInfoItemList() before > localItems.size() = " + + Log.d(TAG, "addItems() before > localItems.size() = " + localItems.size() + ", data.size() = " + data.size()); } @@ -80,7 +80,7 @@ public class LocalItemListAdapter extends RecyclerView.Adapter offsetStart = " + offsetStart + + Log.d(TAG, "addItems() after > offsetStart = " + offsetStart + ", localItems.size() = " + localItems.size() + ", header = " + header + ", footer = " + footer + ", showFooter = " + showFooter); @@ -92,7 +92,7 @@ public class LocalItemListAdapter extends RecyclerView.Adapter { if (itemBuilder.getOnItemSelectedListener() != null) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalPlaylistStreamItemHolder.java b/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalPlaylistStreamItemHolder.java index 712db8f8a..4fe577aaf 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalPlaylistStreamItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalPlaylistStreamItemHolder.java @@ -1,5 +1,6 @@ package org.schabi.newpipe.fragments.local.holder; +import android.graphics.Bitmap; import android.support.v4.content.ContextCompat; import android.view.MotionEvent; import android.view.View; @@ -8,6 +9,7 @@ import android.widget.ImageView; import android.widget.TextView; import com.nostra13.universalimageloader.core.DisplayImageOptions; +import com.nostra13.universalimageloader.core.assist.ImageScaleType; import org.schabi.newpipe.R; import org.schabi.newpipe.database.LocalItem; @@ -59,8 +61,7 @@ public class LocalPlaylistStreamItemHolder extends LocalItemHolder { } // Default thumbnail is shown on error, while loading and if the url is empty - itemBuilder.getImageLoader().displayImage(item.thumbnailUrl, itemThumbnailView, - LocalPlaylistStreamItemHolder.DISPLAY_THUMBNAIL_OPTIONS); + itemBuilder.displayImage(item.thumbnailUrl, itemThumbnailView, DISPLAY_THUMBNAIL_OPTIONS); itemView.setOnClickListener(view -> { if (itemBuilder.getOnItemSelectedListener() != null) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalStatisticStreamItemHolder.java b/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalStatisticStreamItemHolder.java index bce6bab76..cd0630b37 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalStatisticStreamItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/local/holder/LocalStatisticStreamItemHolder.java @@ -45,8 +45,8 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder { public final TextView itemDurationView; public final TextView itemAdditionalDetails; - LocalStatisticStreamItemHolder(LocalItemBuilder infoItemBuilder, int layoutId, ViewGroup parent) { - super(infoItemBuilder, layoutId, parent); + public LocalStatisticStreamItemHolder(LocalItemBuilder infoItemBuilder, ViewGroup parent) { + super(infoItemBuilder, R.layout.list_stream_item, parent); itemThumbnailView = itemView.findViewById(R.id.itemThumbnailView); itemVideoTitleView = itemView.findViewById(R.id.itemVideoTitleView); @@ -55,10 +55,6 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder { itemAdditionalDetails = itemView.findViewById(R.id.itemAdditionalDetails); } - public LocalStatisticStreamItemHolder(LocalItemBuilder infoItemBuilder, ViewGroup parent) { - this(infoItemBuilder, R.layout.list_stream_item, parent); - } - private String getStreamInfoDetailLine(final StreamStatisticsEntry entry, final DateFormat dateFormat) { final String watchCount = Localization.shortViewCount(itemBuilder.getContext(), @@ -88,8 +84,7 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder { itemAdditionalDetails.setText(getStreamInfoDetailLine(item, dateFormat)); // Default thumbnail is shown on error, while loading and if the url is empty - itemBuilder.getImageLoader().displayImage(item.thumbnailUrl, itemThumbnailView, - DISPLAY_THUMBNAIL_OPTIONS); + itemBuilder.displayImage(item.thumbnailUrl, itemThumbnailView, DISPLAY_THUMBNAIL_OPTIONS); itemView.setOnClickListener(view -> { if (itemBuilder.getOnItemSelectedListener() != null) {