-Fixed memory leak due to image loader overusing memory cache.
-Added disk cache for local item loading.
This commit is contained in:
parent
d3160eed9d
commit
6f9deea873
|
@ -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();
|
||||
|
|
|
@ -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<LocalItem> getOnItemSelectedListener() {
|
||||
|
|
|
@ -69,10 +69,10 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
|
|||
localItemBuilder.setOnItemSelectedListener(listener);
|
||||
}
|
||||
|
||||
public void addInfoItemList(List<? extends LocalItem> data) {
|
||||
public void addItems(List<? extends LocalItem> 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<RecyclerView.View
|
|||
localItems.addAll(data);
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "addInfoItemList() after > 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<RecyclerView.View
|
|||
int footerNow = sizeConsideringHeader();
|
||||
notifyItemMoved(offsetStart, footerNow);
|
||||
|
||||
if (DEBUG) Log.d(TAG, "addInfoItemList() footer from " + offsetStart +
|
||||
if (DEBUG) Log.d(TAG, "addItems() footer from " + offsetStart +
|
||||
" to " + footerNow);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -349,7 +349,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
|
|||
animateView(headerRootLayout, true, 100);
|
||||
animateView(itemsList, true, 300);
|
||||
|
||||
itemListAdapter.addInfoItemList(result);
|
||||
itemListAdapter.addItems(result);
|
||||
if (itemsListState != null) {
|
||||
itemsList.getLayoutManager().onRestoreInstanceState(itemsListState);
|
||||
itemsListState = null;
|
||||
|
|
|
@ -119,7 +119,7 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
|
|||
}
|
||||
|
||||
playlistAdapter.clearStreamItemList();
|
||||
playlistAdapter.addInfoItemList(metadataEntries);
|
||||
playlistAdapter.addItems(metadataEntries);
|
||||
playlistRecyclerView.setVisibility(View.VISIBLE);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -239,7 +239,7 @@ public class BookmarkFragment extends BaseStateFragment<List<PlaylistMetadataEnt
|
|||
if (result.isEmpty()) {
|
||||
showEmptyState();
|
||||
} else {
|
||||
itemListAdapter.addInfoItemList(infoItemsOf(result));
|
||||
itemListAdapter.addItems(infoItemsOf(result));
|
||||
if (itemsListState != null) {
|
||||
itemsList.getLayoutManager().onRestoreInstanceState(itemsListState);
|
||||
itemsListState = null;
|
||||
|
|
|
@ -249,7 +249,7 @@ public abstract class StatisticsPlaylistFragment
|
|||
animateView(headerRootLayout, true, 100);
|
||||
animateView(itemsList, true, 300);
|
||||
|
||||
itemListAdapter.addInfoItemList(processResult(result));
|
||||
itemListAdapter.addItems(processResult(result));
|
||||
if (itemsListState != null) {
|
||||
itemsList.getLayoutManager().onRestoreInstanceState(itemsListState);
|
||||
itemsListState = null;
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
package org.schabi.newpipe.fragments.local.holder;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.support.annotation.DimenRes;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.process.BitmapProcessor;
|
||||
|
||||
import org.schabi.newpipe.database.LocalItem;
|
||||
import org.schabi.newpipe.fragments.local.LocalItemBuilder;
|
||||
|
@ -52,5 +56,8 @@ public abstract class LocalItemHolder extends RecyclerView.ViewHolder {
|
|||
public static final DisplayImageOptions BASE_DISPLAY_IMAGE_OPTIONS =
|
||||
new DisplayImageOptions.Builder()
|
||||
.cacheInMemory(true)
|
||||
.cacheOnDisk(true)
|
||||
.bitmapConfig(Bitmap.Config.RGB_565)
|
||||
.resetViewBeforeLoading(false)
|
||||
.build();
|
||||
}
|
||||
|
|
|
@ -43,8 +43,7 @@ public class LocalPlaylistItemHolder extends LocalItemHolder {
|
|||
itemStreamCountView.setText(String.valueOf(item.streamCount));
|
||||
itemUploaderView.setVisibility(View.INVISIBLE);
|
||||
|
||||
itemBuilder.getImageLoader().displayImage(item.thumbnailUrl, itemThumbnailView,
|
||||
DISPLAY_THUMBNAIL_OPTIONS);
|
||||
itemBuilder.displayImage(item.thumbnailUrl, itemThumbnailView, DISPLAY_THUMBNAIL_OPTIONS);
|
||||
|
||||
itemView.setOnClickListener(view -> {
|
||||
if (itemBuilder.getOnItemSelectedListener() != null) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue