aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo
diff options
context:
space:
mode:
authorbananeweizen <bananeweizen@gmx.de>2011-10-30 14:50:09 +0100
committerbananeweizen <bananeweizen@gmx.de>2011-10-30 14:50:09 +0100
commitd46438381be1e4bf4186e0a426ebed66655266b9 (patch)
treeb3aa7af3df4f33a7c9dda79148613db635144a33 /main/src/cgeo
parent6c74f71960125b5fefc6fbeb4b3d510ae2f921e8 (diff)
downloadcgeo-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.java5
-rw-r--r--main/src/cgeo/geocaching/cgeodetail.java9
-rw-r--r--main/src/cgeo/geocaching/cgeoimages.java3
-rw-r--r--main/src/cgeo/geocaching/cgeotrackable.java11
-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;
}