mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-12-24 00:50:32 +00:00
-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.os.Build;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
||||||
|
|
||||||
@ -80,7 +81,9 @@ public class App extends Application {
|
|||||||
initNotificationChannel();
|
initNotificationChannel();
|
||||||
|
|
||||||
// Initialize image loader
|
// Initialize image loader
|
||||||
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this).build();
|
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
|
||||||
|
.memoryCache(new WeakMemoryCache())
|
||||||
|
.build();
|
||||||
ImageLoader.getInstance().init(config);
|
ImageLoader.getInstance().init(config);
|
||||||
|
|
||||||
configureRxJavaErrorHandler();
|
configureRxJavaErrorHandler();
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
package org.schabi.newpipe.fragments.local;
|
package org.schabi.newpipe.fragments.local;
|
||||||
|
|
||||||
import android.content.Context;
|
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.ImageLoader;
|
||||||
|
import com.nostra13.universalimageloader.core.process.BitmapProcessor;
|
||||||
|
|
||||||
import org.schabi.newpipe.database.LocalItem;
|
import org.schabi.newpipe.database.LocalItem;
|
||||||
|
|
||||||
@ -42,8 +46,9 @@ public class LocalItemBuilder {
|
|||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageLoader getImageLoader() {
|
public void displayImage(final String url, final ImageView view,
|
||||||
return imageLoader;
|
final DisplayImageOptions options) {
|
||||||
|
imageLoader.displayImage(url, view, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OnLocalItemGesture<LocalItem> getOnItemSelectedListener() {
|
public OnLocalItemGesture<LocalItem> getOnItemSelectedListener() {
|
||||||
|
@ -69,10 +69,10 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
|
|||||||
localItemBuilder.setOnItemSelectedListener(listener);
|
localItemBuilder.setOnItemSelectedListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addInfoItemList(List<? extends LocalItem> data) {
|
public void addItems(List<? extends LocalItem> data) {
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "addInfoItemList() before > localItems.size() = " +
|
Log.d(TAG, "addItems() before > localItems.size() = " +
|
||||||
localItems.size() + ", data.size() = " + data.size());
|
localItems.size() + ", data.size() = " + data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
|
|||||||
localItems.addAll(data);
|
localItems.addAll(data);
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "addInfoItemList() after > offsetStart = " + offsetStart +
|
Log.d(TAG, "addItems() after > offsetStart = " + offsetStart +
|
||||||
", localItems.size() = " + localItems.size() +
|
", localItems.size() = " + localItems.size() +
|
||||||
", header = " + header + ", footer = " + footer +
|
", header = " + header + ", footer = " + footer +
|
||||||
", showFooter = " + showFooter);
|
", showFooter = " + showFooter);
|
||||||
@ -92,7 +92,7 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
|
|||||||
int footerNow = sizeConsideringHeader();
|
int footerNow = sizeConsideringHeader();
|
||||||
notifyItemMoved(offsetStart, footerNow);
|
notifyItemMoved(offsetStart, footerNow);
|
||||||
|
|
||||||
if (DEBUG) Log.d(TAG, "addInfoItemList() footer from " + offsetStart +
|
if (DEBUG) Log.d(TAG, "addItems() footer from " + offsetStart +
|
||||||
" to " + footerNow);
|
" to " + footerNow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,7 +349,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
|
|||||||
animateView(headerRootLayout, true, 100);
|
animateView(headerRootLayout, true, 100);
|
||||||
animateView(itemsList, true, 300);
|
animateView(itemsList, true, 300);
|
||||||
|
|
||||||
itemListAdapter.addInfoItemList(result);
|
itemListAdapter.addItems(result);
|
||||||
if (itemsListState != null) {
|
if (itemsListState != null) {
|
||||||
itemsList.getLayoutManager().onRestoreInstanceState(itemsListState);
|
itemsList.getLayoutManager().onRestoreInstanceState(itemsListState);
|
||||||
itemsListState = null;
|
itemsListState = null;
|
||||||
|
@ -119,7 +119,7 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
playlistAdapter.clearStreamItemList();
|
playlistAdapter.clearStreamItemList();
|
||||||
playlistAdapter.addInfoItemList(metadataEntries);
|
playlistAdapter.addItems(metadataEntries);
|
||||||
playlistRecyclerView.setVisibility(View.VISIBLE);
|
playlistRecyclerView.setVisibility(View.VISIBLE);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ public class BookmarkFragment extends BaseStateFragment<List<PlaylistMetadataEnt
|
|||||||
if (result.isEmpty()) {
|
if (result.isEmpty()) {
|
||||||
showEmptyState();
|
showEmptyState();
|
||||||
} else {
|
} else {
|
||||||
itemListAdapter.addInfoItemList(infoItemsOf(result));
|
itemListAdapter.addItems(infoItemsOf(result));
|
||||||
if (itemsListState != null) {
|
if (itemsListState != null) {
|
||||||
itemsList.getLayoutManager().onRestoreInstanceState(itemsListState);
|
itemsList.getLayoutManager().onRestoreInstanceState(itemsListState);
|
||||||
itemsListState = null;
|
itemsListState = null;
|
||||||
|
@ -249,7 +249,7 @@ public abstract class StatisticsPlaylistFragment
|
|||||||
animateView(headerRootLayout, true, 100);
|
animateView(headerRootLayout, true, 100);
|
||||||
animateView(itemsList, true, 300);
|
animateView(itemsList, true, 300);
|
||||||
|
|
||||||
itemListAdapter.addInfoItemList(processResult(result));
|
itemListAdapter.addItems(processResult(result));
|
||||||
if (itemsListState != null) {
|
if (itemsListState != null) {
|
||||||
itemsList.getLayoutManager().onRestoreInstanceState(itemsListState);
|
itemsList.getLayoutManager().onRestoreInstanceState(itemsListState);
|
||||||
itemsListState = null;
|
itemsListState = null;
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
package org.schabi.newpipe.fragments.local.holder;
|
package org.schabi.newpipe.fragments.local.holder;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.support.annotation.DimenRes;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
|
import com.nostra13.universalimageloader.core.process.BitmapProcessor;
|
||||||
|
|
||||||
import org.schabi.newpipe.database.LocalItem;
|
import org.schabi.newpipe.database.LocalItem;
|
||||||
import org.schabi.newpipe.fragments.local.LocalItemBuilder;
|
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 =
|
public static final DisplayImageOptions BASE_DISPLAY_IMAGE_OPTIONS =
|
||||||
new DisplayImageOptions.Builder()
|
new DisplayImageOptions.Builder()
|
||||||
.cacheInMemory(true)
|
.cacheInMemory(true)
|
||||||
|
.cacheOnDisk(true)
|
||||||
|
.bitmapConfig(Bitmap.Config.RGB_565)
|
||||||
|
.resetViewBeforeLoading(false)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
@ -43,8 +43,7 @@ public class LocalPlaylistItemHolder extends LocalItemHolder {
|
|||||||
itemStreamCountView.setText(String.valueOf(item.streamCount));
|
itemStreamCountView.setText(String.valueOf(item.streamCount));
|
||||||
itemUploaderView.setVisibility(View.INVISIBLE);
|
itemUploaderView.setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
itemBuilder.getImageLoader().displayImage(item.thumbnailUrl, itemThumbnailView,
|
itemBuilder.displayImage(item.thumbnailUrl, itemThumbnailView, DISPLAY_THUMBNAIL_OPTIONS);
|
||||||
DISPLAY_THUMBNAIL_OPTIONS);
|
|
||||||
|
|
||||||
itemView.setOnClickListener(view -> {
|
itemView.setOnClickListener(view -> {
|
||||||
if (itemBuilder.getOnItemSelectedListener() != null) {
|
if (itemBuilder.getOnItemSelectedListener() != null) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.schabi.newpipe.fragments.local.holder;
|
package org.schabi.newpipe.fragments.local.holder;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -8,6 +9,7 @@ import android.widget.ImageView;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
|
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.database.LocalItem;
|
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
|
// Default thumbnail is shown on error, while loading and if the url is empty
|
||||||
itemBuilder.getImageLoader().displayImage(item.thumbnailUrl, itemThumbnailView,
|
itemBuilder.displayImage(item.thumbnailUrl, itemThumbnailView, DISPLAY_THUMBNAIL_OPTIONS);
|
||||||
LocalPlaylistStreamItemHolder.DISPLAY_THUMBNAIL_OPTIONS);
|
|
||||||
|
|
||||||
itemView.setOnClickListener(view -> {
|
itemView.setOnClickListener(view -> {
|
||||||
if (itemBuilder.getOnItemSelectedListener() != null) {
|
if (itemBuilder.getOnItemSelectedListener() != null) {
|
||||||
|
@ -45,8 +45,8 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder {
|
|||||||
public final TextView itemDurationView;
|
public final TextView itemDurationView;
|
||||||
public final TextView itemAdditionalDetails;
|
public final TextView itemAdditionalDetails;
|
||||||
|
|
||||||
LocalStatisticStreamItemHolder(LocalItemBuilder infoItemBuilder, int layoutId, ViewGroup parent) {
|
public LocalStatisticStreamItemHolder(LocalItemBuilder infoItemBuilder, ViewGroup parent) {
|
||||||
super(infoItemBuilder, layoutId, parent);
|
super(infoItemBuilder, R.layout.list_stream_item, parent);
|
||||||
|
|
||||||
itemThumbnailView = itemView.findViewById(R.id.itemThumbnailView);
|
itemThumbnailView = itemView.findViewById(R.id.itemThumbnailView);
|
||||||
itemVideoTitleView = itemView.findViewById(R.id.itemVideoTitleView);
|
itemVideoTitleView = itemView.findViewById(R.id.itemVideoTitleView);
|
||||||
@ -55,10 +55,6 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder {
|
|||||||
itemAdditionalDetails = itemView.findViewById(R.id.itemAdditionalDetails);
|
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,
|
private String getStreamInfoDetailLine(final StreamStatisticsEntry entry,
|
||||||
final DateFormat dateFormat) {
|
final DateFormat dateFormat) {
|
||||||
final String watchCount = Localization.shortViewCount(itemBuilder.getContext(),
|
final String watchCount = Localization.shortViewCount(itemBuilder.getContext(),
|
||||||
@ -88,8 +84,7 @@ public class LocalStatisticStreamItemHolder extends LocalItemHolder {
|
|||||||
itemAdditionalDetails.setText(getStreamInfoDetailLine(item, dateFormat));
|
itemAdditionalDetails.setText(getStreamInfoDetailLine(item, dateFormat));
|
||||||
|
|
||||||
// Default thumbnail is shown on error, while loading and if the url is empty
|
// Default thumbnail is shown on error, while loading and if the url is empty
|
||||||
itemBuilder.getImageLoader().displayImage(item.thumbnailUrl, itemThumbnailView,
|
itemBuilder.displayImage(item.thumbnailUrl, itemThumbnailView, DISPLAY_THUMBNAIL_OPTIONS);
|
||||||
DISPLAY_THUMBNAIL_OPTIONS);
|
|
||||||
|
|
||||||
itemView.setOnClickListener(view -> {
|
itemView.setOnClickListener(view -> {
|
||||||
if (itemBuilder.getOnItemSelectedListener() != null) {
|
if (itemBuilder.getOnItemSelectedListener() != null) {
|
||||||
|
Loading…
Reference in New Issue
Block a user