diff options
| author | bananeweizen <bananeweizen@gmx.de> | 2011-10-30 14:50:09 +0100 |
|---|---|---|
| committer | bananeweizen <bananeweizen@gmx.de> | 2011-10-30 14:50:09 +0100 |
| commit | d46438381be1e4bf4186e0a426ebed66655266b9 (patch) | |
| tree | b3aa7af3df4f33a7c9dda79148613db635144a33 /main/src/cgeo | |
| parent | 6c74f71960125b5fefc6fbeb4b3d510ae2f921e8 (diff) | |
| download | cgeo-d46438381be1e4bf4186e0a426ebed66655266b9.zip cgeo-d46438381be1e4bf4186e0a426ebed66655266b9.tar.gz cgeo-d46438381be1e4bf4186e0a426ebed66655266b9.tar.bz2 | |
fix #731: OOM in images when downloading
Diffstat (limited to 'main/src/cgeo')
| -rw-r--r-- | main/src/cgeo/geocaching/cgBase.java | 5 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/cgeodetail.java | 9 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/cgeoimages.java | 3 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/cgeotrackable.java | 11 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/network/HtmlImage.java (renamed from main/src/cgeo/geocaching/cgHtmlImg.java) | 91 |
5 files changed, 62 insertions, 57 deletions
diff --git a/main/src/cgeo/geocaching/cgBase.java b/main/src/cgeo/geocaching/cgBase.java index 6d4c2f4..d1d4165 100644 --- a/main/src/cgeo/geocaching/cgBase.java +++ b/main/src/cgeo/geocaching/cgBase.java @@ -11,6 +11,7 @@ import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.files.LocParser; import cgeo.geocaching.geopoint.DistanceParser; import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.network.HtmlImage; import cgeo.geocaching.utils.BaseUtils; import cgeo.geocaching.utils.CancellableHandler; @@ -1659,7 +1660,7 @@ public class cgBase { final String profile = BaseUtils.replaceWhitespace(getResponseData(request("http://www.geocaching.com/my/", null, false))); final String avatarURL = BaseUtils.getMatch(profile, GCConstants.PATTERN_AVATAR_IMAGE, false, null); if (null != avatarURL) { - final cgHtmlImg imgGetter = new cgHtmlImg(context, "", false, 0, false, false); + final HtmlImage imgGetter = new HtmlImage(context, "", false, 0, false, false); return imgGetter.getDrawable(avatarURL); } // No match? There may be no avatar set by user. @@ -3009,7 +3010,7 @@ public class cgBase { return; } - final cgHtmlImg imgGetter = new cgHtmlImg(activity, cache.geocode, false, listId, true); + final HtmlImage imgGetter = new HtmlImage(activity, cache.geocode, false, listId, true); // store images from description if (StringUtils.isNotBlank(cache.getDescription())) { diff --git a/main/src/cgeo/geocaching/cgeodetail.java b/main/src/cgeo/geocaching/cgeodetail.java index b8920de..7d339f3 100644 --- a/main/src/cgeo/geocaching/cgeodetail.java +++ b/main/src/cgeo/geocaching/cgeodetail.java @@ -8,6 +8,7 @@ import cgeo.geocaching.compatibility.Compatibility; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.network.HtmlImage; import cgeo.geocaching.utils.CancellableHandler; import cgeo.geocaching.utils.CryptUtils; @@ -1037,7 +1038,7 @@ public class cgeodetail extends AbstractActivity { TextView descView = (TextView) findViewById(R.id.shortdesc); descView.setVisibility(View.VISIBLE); - descView.setText(Html.fromHtml(cache.shortdesc.trim(), new cgHtmlImg(this, geocode, true, cache.reason, false), null), TextView.BufferType.SPANNABLE); + descView.setText(Html.fromHtml(cache.shortdesc.trim(), new HtmlImage(this, geocode, true, cache.reason, false), null), TextView.BufferType.SPANNABLE); descView.setMovementMethod(LinkMovementMethod.getInstance()); } @@ -1179,7 +1180,7 @@ public class cgeodetail extends AbstractActivity { if (longDesc == null && cache != null) { String description = cache.getDescription(); if (description != null) { - longDesc = Html.fromHtml(description.trim(), new cgHtmlImg(this, geocode, true, cache.reason, false), new UnknownTagsHandler()); + longDesc = Html.fromHtml(description.trim(), new HtmlImage(this, geocode, true, cache.reason, false), new UnknownTagsHandler()); } } } @@ -1285,7 +1286,7 @@ public class cgeodetail extends AbstractActivity { } // avoid parsing HTML if not necessary if (containsHtml(log.log)) { - ((TextView) rowView.findViewById(R.id.log)).setText(Html.fromHtml(log.log, new cgHtmlImg(this, null, false, cache.reason, false), null), TextView.BufferType.SPANNABLE); + ((TextView) rowView.findViewById(R.id.log)).setText(Html.fromHtml(log.log, new HtmlImage(this, null, false, cache.reason, false), null), TextView.BufferType.SPANNABLE); } else { ((TextView) rowView.findViewById(R.id.log)).setText(log.log); @@ -1418,7 +1419,7 @@ public class cgeodetail extends AbstractActivity { String markerUrl = cgBase.urlencode_rfc3986("http://cgeo.carnero.cc/_markers/my_location_mdpi.png"); - cgHtmlImg mapGetter = new cgHtmlImg(cgeodetail.this, cache.geocode, false, 0, false); + HtmlImage mapGetter = new HtmlImage(cgeodetail.this, cache.geocode, false, 0, false); image = mapGetter.getDrawable("http://maps.google.com/maps/api/staticmap?center=" + latlonMap + "&zoom=15&size=" + width + "x" + height + "&maptype=terrain&markers=icon%3A" + markerUrl + "%7C" + latlonMap + "&sensor=false"); Message message = handler.obtainMessage(0, image); handler.sendMessage(message); diff --git a/main/src/cgeo/geocaching/cgeoimages.java b/main/src/cgeo/geocaching/cgeoimages.java index df5578c..ef3f1f8 100644 --- a/main/src/cgeo/geocaching/cgeoimages.java +++ b/main/src/cgeo/geocaching/cgeoimages.java @@ -2,6 +2,7 @@ package cgeo.geocaching; import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.files.LocalStorage; +import cgeo.geocaching.network.HtmlImage; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -89,7 +90,7 @@ public class cgeoimages extends AbstractActivity { @Override protected BitmapDrawable doInBackground(Void... params) { - final cgHtmlImg imgGetter = new cgHtmlImg(cgeoimages.this, geocode, true, offline ? 1 : 0, false, save); + final HtmlImage imgGetter = new HtmlImage(cgeoimages.this, geocode, true, offline ? 1 : 0, false, save); return imgGetter.getDrawable(img.url); } diff --git a/main/src/cgeo/geocaching/cgeotrackable.java b/main/src/cgeo/geocaching/cgeotrackable.java index 4037853..453be7b 100644 --- a/main/src/cgeo/geocaching/cgeotrackable.java +++ b/main/src/cgeo/geocaching/cgeotrackable.java @@ -1,6 +1,7 @@ package cgeo.geocaching; import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.network.HtmlImage; import org.apache.commons.lang3.StringUtils; @@ -226,7 +227,7 @@ public class cgeotrackable extends AbstractActivity { ((LinearLayout) findViewById(R.id.goal_box)).setVisibility(View.VISIBLE); TextView descView = (TextView) findViewById(R.id.goal); descView.setVisibility(View.VISIBLE); - descView.setText(Html.fromHtml(trackable.getGoal(), new cgHtmlImg(cgeotrackable.this, geocode, true, 0, false), null), TextView.BufferType.SPANNABLE); + descView.setText(Html.fromHtml(trackable.getGoal(), new HtmlImage(cgeotrackable.this, geocode, true, 0, false), null), TextView.BufferType.SPANNABLE); descView.setMovementMethod(LinkMovementMethod.getInstance()); } @@ -235,7 +236,7 @@ public class cgeotrackable extends AbstractActivity { ((LinearLayout) findViewById(R.id.details_box)).setVisibility(View.VISIBLE); TextView descView = (TextView) findViewById(R.id.details); descView.setVisibility(View.VISIBLE); - descView.setText(Html.fromHtml(trackable.getDetails(), new cgHtmlImg(cgeotrackable.this, geocode, true, 0, false), null), TextView.BufferType.SPANNABLE); + descView.setText(Html.fromHtml(trackable.getDetails(), new HtmlImage(cgeotrackable.this, geocode, true, 0, false), null), TextView.BufferType.SPANNABLE); descView.setMovementMethod(LinkMovementMethod.getInstance()); } @@ -273,7 +274,7 @@ public class cgeotrackable extends AbstractActivity { public void run() { BitmapDrawable image = null; try { - cgHtmlImg imgGetter = new cgHtmlImg(cgeotrackable.this, geocode, true, 0, false); + HtmlImage imgGetter = new HtmlImage(cgeotrackable.this, geocode, true, 0, false); image = imgGetter.getDrawable(trackable.getImage()); Message message = handler.obtainMessage(0, image); @@ -520,7 +521,7 @@ public class cgeotrackable extends AbstractActivity { }); } - ((TextView) rowView.findViewById(R.id.log)).setText(Html.fromHtml(log.log, new cgHtmlImg(cgeotrackable.this, null, false, 0, false), null), TextView.BufferType.SPANNABLE); + ((TextView) rowView.findViewById(R.id.log)).setText(Html.fromHtml(log.log, new HtmlImage(cgeotrackable.this, null, false, 0, false), null), TextView.BufferType.SPANNABLE); ((TextView) rowView.findViewById(R.id.author)).setOnClickListener(new userActions()); listView.addView(rowView); @@ -572,7 +573,7 @@ public class cgeotrackable extends AbstractActivity { BitmapDrawable image = null; try { - cgHtmlImg imgGetter = new cgHtmlImg(cgeotrackable.this, trackable.getGeocode(), false, 0, false); + HtmlImage imgGetter = new HtmlImage(cgeotrackable.this, trackable.getGeocode(), false, 0, false); image = imgGetter.getDrawable(url); Message message = handler.obtainMessage(0, image); diff --git a/main/src/cgeo/geocaching/cgHtmlImg.java b/main/src/cgeo/geocaching/network/HtmlImage.java index f264c51..4e996e3 100644 --- a/main/src/cgeo/geocaching/cgHtmlImg.java +++ b/main/src/cgeo/geocaching/network/HtmlImage.java @@ -1,5 +1,8 @@ -package cgeo.geocaching; +package cgeo.geocaching.network; +import cgeo.geocaching.R; +import cgeo.geocaching.Settings; +import cgeo.geocaching.cgBase; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.files.LocalStorage; @@ -7,7 +10,6 @@ import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpResponse; import org.apache.http.entity.BufferedHttpEntity; -import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -20,10 +22,9 @@ import android.view.Display; import android.view.WindowManager; import java.io.File; -import java.io.InputStream; import java.util.Date; -public class cgHtmlImg implements Html.ImageGetter { +public class HtmlImage implements Html.ImageGetter { private static final String[] BLOCKED = new String[] { "gccounter.de", @@ -36,33 +37,35 @@ public class cgHtmlImg implements Html.ImageGetter { }; final private Context context; final private String geocode; - final private boolean placement; + /** + * on error: return large error image, if <code>true</code>, otherwise empty 1x1 image + */ + final private boolean returnErrorImage; final private int reason; final private boolean onlySave; final private boolean save; final private BitmapFactory.Options bfOptions; - final private Display display; final private int maxWidth; final private int maxHeight; - public cgHtmlImg(Activity activityIn, String geocodeIn, boolean placementIn, int reasonIn, boolean onlySaveIn) { - this(activityIn, geocodeIn, placementIn, reasonIn, onlySaveIn, true); + public HtmlImage(final Context context, final String geocode, final boolean returnErrorImage, final int reason, final boolean onlySave) { + this(context, geocode, returnErrorImage, reason, onlySave, true); } - public cgHtmlImg(Context contextIn, String geocodeIn, boolean placementIn, int reasonIn, boolean onlySaveIn, boolean saveIn) { - context = contextIn; - geocode = geocodeIn; - placement = placementIn; - reason = reasonIn; - onlySave = onlySaveIn; - save = saveIn; + public HtmlImage(final Context contextIn, final String geocode, final boolean returnErrorImage, final int reason, final boolean onlySave, final boolean save) { + this.context = contextIn; + this.geocode = geocode; + this.returnErrorImage = returnErrorImage; + this.reason = reason; + this.onlySave = onlySave; + this.save = save; bfOptions = new BitmapFactory.Options(); bfOptions.inTempStorage = new byte[16 * 1024]; - display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); - maxWidth = display.getWidth() - 25; - maxHeight = display.getHeight() - 25; + final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); + this.maxWidth = display.getWidth() - 25; + this.maxHeight = display.getHeight() - 25; } @Override @@ -72,21 +75,11 @@ public class cgHtmlImg implements Html.ImageGetter { return null; } - final File file = LocalStorage.getStorageFile(geocode, url, true); - final File fileSec = LocalStorage.getStorageSecFile(geocode, url, true); - Bitmap imagePre = null; // Load image from cache if (!onlySave) { - try { - imagePre = loadCachedImage(file); - if (imagePre == null) { - imagePre = loadCachedImage(fileSec); - } - } catch (Exception e) { - Log.w(Settings.tag, "cgHtmlImg.getDrawable (reading cache): " + e.toString()); - } + imagePre = loadImageFromStorage(url); } // Download image and save it to the cache @@ -99,13 +92,6 @@ public class cgHtmlImg implements Html.ImageGetter { final HttpResponse httpResponse = cgBase.request(absoluteURL, null, false); if (httpResponse != null) { bufferedEntity = new BufferedHttpEntity(httpResponse.getEntity()); - setSampleSize(bufferedEntity.getContentLength()); - final InputStream is = bufferedEntity.getContent(); - try { - imagePre = BitmapFactory.decodeStream(is, null, bfOptions); - } finally { - is.close(); - } } } catch (Exception e) { Log.e(Settings.tag, "cgHtmlImg.getDrawable (downloading from web)", e); @@ -113,6 +99,7 @@ public class cgHtmlImg implements Html.ImageGetter { } if (save) { + final File file = LocalStorage.getStorageFile(geocode, url, true); LocalStorage.saveEntityToFile(bufferedEntity, file); } } @@ -121,11 +108,16 @@ public class cgHtmlImg implements Html.ImageGetter { return null; } + // now load the newly downloaded image + if (imagePre == null) { + imagePre = loadImageFromStorage(url); + } + // get image and return if (imagePre == null) { Log.d(Settings.tag, "cgHtmlImg.getDrawable: Failed to obtain image"); - if (placement) { + if (returnErrorImage) { imagePre = BitmapFactory.decodeResource(context.getResources(), R.drawable.image_not_loaded); } else { imagePre = BitmapFactory.decodeResource(context.getResources(), R.drawable.image_no_placement); @@ -139,13 +131,7 @@ public class cgHtmlImg implements Html.ImageGetter { int height; if (imgWidth > maxWidth || imgHeight > maxHeight) { - double ratio; - if ((maxWidth / imgWidth) > (maxHeight / imgHeight)) { - ratio = (double) maxHeight / (double) imgHeight; - } else { - ratio = (double) maxWidth / (double) imgWidth; - } - + final double ratio = Math.min((double) maxHeight / (double) imgHeight, (double) maxWidth / (double) imgWidth); width = (int) Math.ceil(imgWidth * ratio); height = (int) Math.ceil(imgHeight * ratio); @@ -166,6 +152,21 @@ public class cgHtmlImg implements Html.ImageGetter { return image; } + private Bitmap loadImageFromStorage(final String url) { + try { + final File file = LocalStorage.getStorageFile(geocode, url, true); + final Bitmap image = loadCachedImage(file); + if (image != null) { + return image; + } + final File fileSec = LocalStorage.getStorageSecFile(geocode, url, true); + return loadCachedImage(fileSec); + } catch (Exception e) { + Log.w(Settings.tag, "cgHtmlImg.getDrawable (reading cache): " + e.toString()); + } + return null; + } + private final String makeAbsoluteURL(final String url) { try { // Check if uri is absolute or not, if not attach the connector hostname @@ -173,7 +174,7 @@ public class cgHtmlImg implements Html.ImageGetter { if (Uri.parse(url).isAbsolute()) { return url; } else { - String host = ConnectorFactory.getConnector(geocode).getHost(); + final String host = ConnectorFactory.getConnector(geocode).getHost(); if (StringUtils.isNotEmpty(host)) { return "http://" + host + url; } |
