From e8b5e863dff14a39b34bf27fc2c82b9212586827 Mon Sep 17 00:00:00 2001 From: Florens Douwes Date: Wed, 7 May 2014 20:05:35 +0200 Subject: [PATCH] Fix issue with image decoder. Fixed issue where no max width/height would be given to the image decoder, that resulted in lots of empty imageviews and OOM errors. Also add filesize to post info. --- .../chan/core/manager/ThreadManager.java | 6 +-- .../src/org/floens/chan/core/model/Post.java | 3 +- .../chan/core/net/ChanReaderRequest.java | 4 +- .../chan/ui/fragment/ImageViewFragment.java | 41 ++++++++++++------- .../chan/ui/view/ThumbnailImageView.java | 24 ++++++++++- Clover/src/org/floens/chan/utils/Utils.java | 16 ++++++-- 6 files changed, 71 insertions(+), 23 deletions(-) diff --git a/Clover/src/org/floens/chan/core/manager/ThreadManager.java b/Clover/src/org/floens/chan/core/manager/ThreadManager.java index 33808c29..2a859ad1 100644 --- a/Clover/src/org/floens/chan/core/manager/ThreadManager.java +++ b/Clover/src/org/floens/chan/core/manager/ThreadManager.java @@ -293,8 +293,8 @@ public class ThreadManager implements Loader.LoaderListener { String text = ""; if (post.hasImage) { - text += "File: " + post.filename + "." + post.ext + " \nSize: " + post.imageWidth + "x" + post.imageHeight - + "\n\n"; + text += "File: " + post.filename + "." + post.ext + " \nDimensions: " + post.imageWidth + "x" + + post.imageHeight + "\nSize: " + Utils.getReadableFileSize(post.fileSize, false) + "\n\n"; } text += "Time: " + post.date; @@ -440,7 +440,7 @@ public class ThreadManager implements Loader.LoaderListener { /** * Open an url. - * + * * @param linkable * Linkable with an url. */ diff --git a/Clover/src/org/floens/chan/core/model/Post.java b/Clover/src/org/floens/chan/core/model/Post.java index 0db3bb7c..d2e22062 100644 --- a/Clover/src/org/floens/chan/core/model/Post.java +++ b/Clover/src/org/floens/chan/core/model/Post.java @@ -70,6 +70,7 @@ public class Post { public String email = ""; public boolean isSavedReply = false; public String title = ""; + public int fileSize; /** * This post replies to the these ids @@ -112,7 +113,7 @@ public class Post { /** * Finish up the data - * + * * @return false if this data is invalid */ public boolean finish(Loadable loadable) { diff --git a/Clover/src/org/floens/chan/core/net/ChanReaderRequest.java b/Clover/src/org/floens/chan/core/net/ChanReaderRequest.java index 1d884aff..24d3933f 100644 --- a/Clover/src/org/floens/chan/core/net/ChanReaderRequest.java +++ b/Clover/src/org/floens/chan/core/net/ChanReaderRequest.java @@ -42,7 +42,7 @@ public class ChanReaderRequest extends JsonReaderRequest> { /** * Creates a ChanReaderRequest with supplied params - * + * * @param mode * ThreadManager mode * @param board @@ -271,6 +271,8 @@ public class ChanReaderRequest extends JsonReaderRequest> { post.imageWidth = reader.nextInt(); } else if (key.equals("h")) { post.imageHeight = reader.nextInt(); + } else if (key.equals("fsize")) { + post.fileSize = reader.nextInt(); } else if (key.equals("sub")) { post.subject = reader.nextString(); } else if (key.equals("replies")) { diff --git a/Clover/src/org/floens/chan/ui/fragment/ImageViewFragment.java b/Clover/src/org/floens/chan/ui/fragment/ImageViewFragment.java index 685c07ef..8cb4bf4c 100644 --- a/Clover/src/org/floens/chan/ui/fragment/ImageViewFragment.java +++ b/Clover/src/org/floens/chan/ui/fragment/ImageViewFragment.java @@ -66,6 +66,7 @@ public class ImageViewFragment extends Fragment implements ThumbnailImageViewCal imageView = new ThumbnailImageView(context); imageView.setCallback(this); + imageView.setLayoutParams(Utils.MATCH_PARAMS); int padding = (int) context.getResources().getDimension(R.dimen.image_view_padding); imageView.setPadding(padding, padding, padding, padding); @@ -85,21 +86,33 @@ public class ImageViewFragment extends Fragment implements ThumbnailImageViewCal throw new IllegalArgumentException("Post has no image"); } - imageView.setThumbnail(post.thumbnailUrl); - - if (post.ext.equals("gif")) { - imageView.setGif(post.imageUrl); - } else if (post.ext.equals("webm")) { - isVideo = true; - activity.invalidateActionBar(); - showProgressBar(false); - - if (ChanPreferences.getVideoAutoPlay()) { - startVideo(); + // After layout has been done so getWidth & getHeight don't return 0 + imageView.post(new Runnable() { + @Override + public void run() { + // When the viewpager is created, it starts loading the first two views, + // then we set a position to the viewpager and it loads three more views! + // Check for these unused views here to avoid unnecessary loads + if (imageView.getWidth() == 0 || imageView.getHeight() == 0) + return; + + imageView.setThumbnail(post.thumbnailUrl); + + if (post.ext.equals("gif")) { + imageView.setGif(post.imageUrl); + } else if (post.ext.equals("webm")) { + isVideo = true; + activity.invalidateActionBar(); + showProgressBar(false); + + if (ChanPreferences.getVideoAutoPlay()) { + startVideo(); + } + } else { + imageView.setBigImage(post.imageUrl); + } } - } else { - imageView.setBigImage(post.imageUrl); - } + }); } } diff --git a/Clover/src/org/floens/chan/ui/view/ThumbnailImageView.java b/Clover/src/org/floens/chan/ui/view/ThumbnailImageView.java index 7441a881..d5b74883 100644 --- a/Clover/src/org/floens/chan/ui/view/ThumbnailImageView.java +++ b/Clover/src/org/floens/chan/ui/view/ThumbnailImageView.java @@ -23,6 +23,7 @@ import org.floens.chan.ChanApplication; import org.floens.chan.R; import org.floens.chan.core.net.FileRequest; import org.floens.chan.core.net.GIFRequest; +import org.floens.chan.utils.Logger; import org.floens.chan.utils.Utils; import uk.co.senab.photoview.PhotoViewAttacher; @@ -44,6 +45,8 @@ import com.android.volley.toolbox.ImageLoader.ImageContainer; import com.android.volley.toolbox.ImageLoader.ImageListener; public class ThumbnailImageView extends LoadView implements OnViewTapListener, View.OnClickListener { + private static final String TAG = "ThumbnailImageView"; + private ThumbnailImageViewCallback callback; /** @@ -82,6 +85,11 @@ public class ThumbnailImageView extends LoadView implements OnViewTapListener, V } public void setThumbnail(String thumbnailUrl) { + if (getWidth() == 0 || getHeight() == 0) { + Logger.e(TAG, "getWidth() or getHeight() returned 0, not loading"); + return; + } + ChanApplication.getImageLoader().get(thumbnailUrl, new ImageListener() { @Override public void onErrorResponse(VolleyError error) { @@ -101,8 +109,17 @@ public class ThumbnailImageView extends LoadView implements OnViewTapListener, V } public void setBigImage(String imageUrl) { + if (getWidth() == 0 || getHeight() == 0) { + Logger.e(TAG, "getWidth() or getHeight() returned 0, not loading"); + return; + } + callback.setProgress(true); + // 4096 is the max GPU upload size + int maxWidth = Math.min((int) (getWidth() * maxScale), 4096); + int maxHeight = Math.min((int) (getHeight() * maxScale), 4096); + imageContainerRequest = ChanApplication.getImageLoader().get(imageUrl, new ImageListener() { @Override public void onErrorResponse(VolleyError error) { @@ -127,10 +144,15 @@ public class ThumbnailImageView extends LoadView implements OnViewTapListener, V tapDismiss = true; } } - }, (int) (getWidth() * maxScale), (int) (getHeight() * maxScale)); + }, maxWidth, maxHeight); } public void setGif(String gifUrl) { + if (getWidth() == 0 || getHeight() == 0) { + Logger.e(TAG, "getWidth() or getHeight() returned 0, not loading"); + return; + } + callback.setProgress(true); imageRequest = ChanApplication.getVolleyRequestQueue().add( diff --git a/Clover/src/org/floens/chan/utils/Utils.java b/Clover/src/org/floens/chan/utils/Utils.java index 39d4875a..923adc63 100644 --- a/Clover/src/org/floens/chan/utils/Utils.java +++ b/Clover/src/org/floens/chan/utils/Utils.java @@ -61,7 +61,7 @@ public class Utils { /** * Sets the android.R.attr.selectableItemBackground as background drawable * on the view. - * + * * @param view */ @SuppressWarnings("deprecation") @@ -83,7 +83,7 @@ public class Utils { /** * Causes the runnable to be added to the message queue. The runnable will * be run on the ui thread. - * + * * @param runnable */ public static void runOnUiThread(Runnable runnable) { @@ -95,7 +95,8 @@ public class Utils { dialog.setOnShowListener(new OnShowListener() { @Override public void onShow(DialogInterface dialog) { - InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService( + Context.INPUT_METHOD_SERVICE); imm.showSoftInput(view, 0); } }); @@ -109,4 +110,13 @@ public class Utils { Toast.makeText(context, R.string.open_link_failed, Toast.LENGTH_LONG).show(); } } + + public static String getReadableFileSize(int bytes, boolean si) { + int unit = si ? 1000 : 1024; + if (bytes < unit) + return bytes + " B"; + int exp = (int) (Math.log(bytes) / Math.log(unit)); + String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); + return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); + } }