aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Jackson <daneren2005@gmail.com>2015-11-09 17:35:11 -0800
committerScott Jackson <daneren2005@gmail.com>2015-11-09 17:35:11 -0800
commitd396e0120e6d8a910e2e36e80c2656c83b80d745 (patch)
treed0445ec63f0dcf7df2c81946eaa1cb9a8f899838
parentae77659307ef8b9dfadf2eb3dae0e406ddae7903 (diff)
downloaddsub-d396e0120e6d8a910e2e36e80c2656c83b80d745.tar.gz
dsub-d396e0120e6d8a910e2e36e80c2656c83b80d745.tar.bz2
dsub-d396e0120e6d8a910e2e36e80c2656c83b80d745.zip
#296 Improve low memory handling
-rw-r--r--app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java1
-rw-r--r--app/src/main/java/github/daneren2005/dsub/adapter/EntryGridAdapter.java3
-rw-r--r--app/src/main/java/github/daneren2005/dsub/adapter/SettingsAdapter.java9
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java12
-rw-r--r--app/src/main/java/github/daneren2005/dsub/service/DownloadService.java6
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/ImageLoader.java16
-rw-r--r--app/src/main/java/github/daneren2005/dsub/view/RecyclingImageView.java22
7 files changed, 58 insertions, 11 deletions
diff --git a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java
index 25acdd02..e055983e 100644
--- a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java
+++ b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java
@@ -216,6 +216,7 @@ public class SubsonicActivity extends AppCompatActivity implements OnItemSelecte
}
populateTabs();
+ getImageLoader().onUIVisible();
UpdateView.addActiveActivity();
}
diff --git a/app/src/main/java/github/daneren2005/dsub/adapter/EntryGridAdapter.java b/app/src/main/java/github/daneren2005/dsub/adapter/EntryGridAdapter.java
index d1ee4bea..38931482 100644
--- a/app/src/main/java/github/daneren2005/dsub/adapter/EntryGridAdapter.java
+++ b/app/src/main/java/github/daneren2005/dsub/adapter/EntryGridAdapter.java
@@ -117,6 +117,9 @@ public class EntryGridAdapter extends SectionAdapter<Entry> {
this.header = header;
this.singleSectionHeader = true;
}
+ public View getHeader() {
+ return header;
+ }
public void setShowArtist(boolean showArtist) {
this.showArtist = showArtist;
diff --git a/app/src/main/java/github/daneren2005/dsub/adapter/SettingsAdapter.java b/app/src/main/java/github/daneren2005/dsub/adapter/SettingsAdapter.java
index 0328e607..1cb9c34e 100644
--- a/app/src/main/java/github/daneren2005/dsub/adapter/SettingsAdapter.java
+++ b/app/src/main/java/github/daneren2005/dsub/adapter/SettingsAdapter.java
@@ -28,6 +28,7 @@ import java.util.List;
import github.daneren2005.dsub.R;
import github.daneren2005.dsub.domain.User;
import github.daneren2005.dsub.util.ImageLoader;
+import github.daneren2005.dsub.view.RecyclingImageView;
import github.daneren2005.dsub.view.SettingView;
import github.daneren2005.dsub.view.UpdateView;
@@ -63,8 +64,14 @@ public class SettingsAdapter extends SectionAdapter<Setting> {
public void onBindHeaderHolder(UpdateView.UpdateViewHolder holder, String description) {
View header = holder.getView();
- ImageView coverArtView = (ImageView) header.findViewById(R.id.user_avatar);
+ RecyclingImageView coverArtView = (RecyclingImageView) header.findViewById(R.id.user_avatar);
imageLoader.loadAvatar(context, coverArtView, user.getUsername());
+ coverArtView.setOnInvalidated(new RecyclingImageView.OnInvalidated() {
+ @Override
+ public void onInvalidated(RecyclingImageView imageView) {
+ imageLoader.loadAvatar(context, imageView, user.getUsername());
+ }
+ });
TextView usernameView = (TextView) header.findViewById(R.id.user_username);
usernameView.setText(user.getUsername());
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
index 98467a2c..9bffbdfd 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
@@ -63,6 +63,7 @@ import github.daneren2005.dsub.util.Util;
import github.daneren2005.dsub.view.FastScroller;
import github.daneren2005.dsub.view.GridSpacingDecoration;
import github.daneren2005.dsub.view.MyLeadingMarginSpan2;
+import github.daneren2005.dsub.view.RecyclingImageView;
import github.daneren2005.dsub.view.UpdateView;
import java.util.ArrayList;
@@ -1112,8 +1113,10 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Section
}
private void setupCoverArt(View header) {
+ setupCoverArtImpl((RecyclingImageView) header.findViewById(R.id.select_album_art));
+ }
+ private void setupCoverArtImpl(RecyclingImageView coverArtView) {
final ImageLoader imageLoader = getImageLoader();
- View coverArtView = header.findViewById(R.id.select_album_art);
// Try a few times to get a random cover art
if(artistInfo != null) {
@@ -1164,6 +1167,13 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Section
});
imageLoader.loadImage(coverArtView, albumRep, false, true);
}
+
+ coverArtView.setOnInvalidated(new RecyclingImageView.OnInvalidated() {
+ @Override
+ public void onInvalidated(RecyclingImageView imageView) {
+ setupCoverArtImpl(imageView);
+ }
+ });
}
private void setupTextDisplay(final View header) {
final TextView titleView = (TextView) header.findViewById(R.id.select_album_title);
diff --git a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
index 7275e447..bfc9c5d6 100644
--- a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
+++ b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java
@@ -283,9 +283,9 @@ public class DownloadService extends Service {
@Override
public void onTrimMemory(int level) {
- Log.w(TAG, "Level: " + level);
ImageLoader imageLoader = SubsonicActivity.getStaticImageLoader(this);
if(imageLoader != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ Log.i(TAG, "Memory Trim Level: " + level);
if (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL) {
imageLoader.onLowMemory(0.75f);
@@ -294,8 +294,10 @@ public class DownloadService extends Service {
} else if(level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE) {
imageLoader.onLowMemory(0.25f);
}
- } else if (level >= TRIM_MEMORY_MODERATE) {
+ } else if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
imageLoader.onLowMemory(0.25f);
+ } else if(level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
+ imageLoader.onLowMemory(0.75f);
}
}
}
diff --git a/app/src/main/java/github/daneren2005/dsub/util/ImageLoader.java b/app/src/main/java/github/daneren2005/dsub/util/ImageLoader.java
index 7ae1648f..c10158d2 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/ImageLoader.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/ImageLoader.java
@@ -116,7 +116,14 @@ public class ImageLoader {
}.execute();
}
public void onLowMemory(float percent) {
- cache.trimToSize(Math.round(cacheSize * percent));
+ Log.i(TAG, "Cache size: " + cache.size() + " => " + Math.round(cacheSize * (1 - percent)) + " out of " + cache.maxSize());
+ cache.resize(Math.round(cacheSize * (1 - percent)));
+ }
+ public void onUIVisible() {
+ if(cache.maxSize() != cacheSize) {
+ Log.i(TAG, "Returned to full cache size");
+ cache.resize(cacheSize);
+ }
}
private Bitmap getUnknownImage(MusicDirectory.Entry entry, int size) {
@@ -388,10 +395,11 @@ public class ImageLoader {
private void setImage(MusicDirectory.Entry entry, RemoteControlClientBase remoteControl, Drawable drawable) {
if(remoteControl != null && drawable != null) {
Bitmap origBitmap = ((BitmapDrawable)drawable).getBitmap();
- if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && origBitmap != null) {
- origBitmap = origBitmap.copy(origBitmap.getConfig(), false);
- }
if ( origBitmap != null && !origBitmap.isRecycled()) {
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && origBitmap != null) {
+ origBitmap = origBitmap.copy(origBitmap.getConfig(), false);
+ }
+
remoteControl.updateAlbumArt(entry, origBitmap);
} else {
if(origBitmap != null) {
diff --git a/app/src/main/java/github/daneren2005/dsub/view/RecyclingImageView.java b/app/src/main/java/github/daneren2005/dsub/view/RecyclingImageView.java
index a7208cee..501b363d 100644
--- a/app/src/main/java/github/daneren2005/dsub/view/RecyclingImageView.java
+++ b/app/src/main/java/github/daneren2005/dsub/view/RecyclingImageView.java
@@ -28,6 +28,7 @@ import android.widget.ImageView;
public class RecyclingImageView extends ImageView {
private boolean invalidated = false;
+ private OnInvalidated onInvalidated;
public RecyclingImageView(Context context) {
super(context);
@@ -53,7 +54,7 @@ public class RecyclingImageView extends ImageView {
if(drawable instanceof BitmapDrawable) {
if (isBitmapRecycled(drawable)) {
this.setImageDrawable(null);
- invalidated = true;
+ setInvalidated(true);
}
} else if(drawable instanceof TransitionDrawable) {
TransitionDrawable transitionDrawable = (TransitionDrawable) drawable;
@@ -62,7 +63,7 @@ public class RecyclingImageView extends ImageView {
Drawable lastDrawable = transitionDrawable.getDrawable(transitionDrawable.getNumberOfLayers() - 1);
if(isBitmapRecycled(lastDrawable)) {
this.setImageDrawable(null);
- invalidated = true;
+ setInvalidated(true);
} else {
// Go through earlier bitmaps and make sure that they are not recycled
for (int i = 0; i < transitionDrawable.getNumberOfLayers(); i++) {
@@ -83,7 +84,7 @@ public class RecyclingImageView extends ImageView {
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
- invalidated = false;
+ setInvalidated(false);
}
private boolean isBitmapRecycled(Drawable drawable) {
@@ -99,7 +100,22 @@ public class RecyclingImageView extends ImageView {
}
}
+ public void setInvalidated(boolean invalidated) {
+ this.invalidated = invalidated;
+
+ if(invalidated && onInvalidated != null) {
+ onInvalidated.onInvalidated(this);
+ }
+ }
public boolean isInvalidated() {
return invalidated;
}
+
+ public void setOnInvalidated(OnInvalidated onInvalidated) {
+ this.onInvalidated = onInvalidated;
+ }
+
+ public interface OnInvalidated {
+ void onInvalidated(RecyclingImageView imageView);
+ }
}