Refactoring

This commit is contained in:
M66B 2019-11-12 14:20:21 +01:00
parent 2f41776fb5
commit ed569d0190
1 changed files with 102 additions and 88 deletions

View File

@ -313,13 +313,8 @@ class ImageHelper {
return d;
}
// Get cache file name
File dir = new File(context.getCacheDir(), "images");
if (!dir.exists())
dir.mkdir();
final File file = new File(dir, id + "_" + Math.abs(a.source.hashCode()) + ".png");
Drawable cached = getCachedImage(context, file);
// Check cache
Drawable cached = getCachedImage(context, id, a.source);
if (cached != null || view == null) {
if (view == null)
if (cached == null) {
@ -343,92 +338,16 @@ class ImageHelper {
@Override
public void run() {
try {
Drawable cached = getCachedImage(context, file);
// Check cache again
Drawable cached = getCachedImage(context, id, a.source);
if (cached != null) {
fitDrawable(cached, a, view);
post(cached, a.source);
return;
}
Bitmap bm;
HttpURLConnection urlConnection = null;
try {
int redirects = 0;
URL url = new URL(a.source);
while (true) {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(false);
urlConnection.setInstanceFollowRedirects(true);
urlConnection.connect();
int status = urlConnection.getResponseCode();
if (status == HttpURLConnection.HTTP_MOVED_PERM ||
status == HttpURLConnection.HTTP_MOVED_TEMP ||
status == HttpURLConnection.HTTP_SEE_OTHER ||
status == 307 /* Temporary redirect */ ||
status == 308 /* Permanent redirect */) {
if (++redirects > MAX_REDIRECTS)
throw new IOException("Too many redirects");
String header = urlConnection.getHeaderField("Location");
if (header == null)
throw new IOException("Location header missing");
String location = URLDecoder.decode(header, StandardCharsets.UTF_8.name());
url = new URL(url, location);
Log.i("Redirect #" + redirects + " to " + url);
urlConnection.disconnect();
continue;
}
if (status != HttpURLConnection.HTTP_OK)
throw new IOException("HTTP status=" + status);
break;
}
BufferedInputStream is = new BufferedInputStream(urlConnection.getInputStream());
Log.i("Probe " + a.source);
is.mark(64 * 1024);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);
int scaleTo = res.getDisplayMetrics().widthPixels;
int factor = 1;
while (options.outWidth / factor > scaleTo)
factor *= 2;
Log.i("Download " + a.source + " factor=" + factor);
is.reset();
if (factor > 1) {
options.inJustDecodeBounds = false;
options.inSampleSize = factor;
bm = BitmapFactory.decodeStream(is, null, options);
} else
bm = BitmapFactory.decodeStream(is);
} finally {
if (urlConnection != null)
urlConnection.disconnect();
}
if (bm == null)
throw new FileNotFoundException("Download image failed source=" + a.source);
Log.i("Downloaded image source=" + a.source);
try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) {
bm.compress(Bitmap.CompressFormat.PNG, 90, os);
}
// Create drawable from bitmap
Drawable d = new BitmapDrawable(res, bm);
DisplayMetrics dm = context.getResources().getDisplayMetrics();
d.setBounds(0, 0, Math.round(bm.getWidth() * dm.density), Math.round(bm.getHeight() * dm.density));
// Download image
Drawable d = downloadImage(context, id, a.source);
fitDrawable(d, a, view);
post(d, a.source);
} catch (Throwable ex) {
@ -533,7 +452,8 @@ class ImageHelper {
return d;
}
private static Drawable getCachedImage(Context context, File file) {
private static Drawable getCachedImage(Context context, long id, String source) {
File file = getCacheFile(context, id, source);
if (file.exists()) {
Log.i("Using cached " + file);
Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath());
@ -550,6 +470,100 @@ class ImageHelper {
return null;
}
@NonNull
private static Drawable downloadImage(Context context, long id, String source) throws IOException {
Resources res = context.getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Bitmap bm;
HttpURLConnection urlConnection = null;
try {
int redirects = 0;
URL url = new URL(source);
while (true) {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(false);
urlConnection.setInstanceFollowRedirects(true);
urlConnection.connect();
int status = urlConnection.getResponseCode();
if (status == HttpURLConnection.HTTP_MOVED_PERM ||
status == HttpURLConnection.HTTP_MOVED_TEMP ||
status == HttpURLConnection.HTTP_SEE_OTHER ||
status == 307 /* Temporary redirect */ ||
status == 308 /* Permanent redirect */) {
if (++redirects > MAX_REDIRECTS)
throw new IOException("Too many redirects");
String header = urlConnection.getHeaderField("Location");
if (header == null)
throw new IOException("Location header missing");
String location = URLDecoder.decode(header, StandardCharsets.UTF_8.name());
url = new URL(url, location);
Log.i("Redirect #" + redirects + " to " + url);
urlConnection.disconnect();
continue;
}
if (status != HttpURLConnection.HTTP_OK)
throw new IOException("HTTP status=" + status);
break;
}
BufferedInputStream is = new BufferedInputStream(urlConnection.getInputStream());
Log.i("Probe " + source);
is.mark(64 * 1024);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);
int scaleToPixels = dm.widthPixels;
int factor = 1;
while (options.outWidth / factor > scaleToPixels)
factor *= 2;
Log.i("Download " + source + " factor=" + factor);
is.reset();
if (factor > 1) {
options.inJustDecodeBounds = false;
options.inSampleSize = factor;
bm = BitmapFactory.decodeStream(is, null, options);
} else
bm = BitmapFactory.decodeStream(is);
} finally {
if (urlConnection != null)
urlConnection.disconnect();
}
if (bm == null)
throw new FileNotFoundException("Download image failed source=" + source);
Log.i("Downloaded image source=" + source);
File file = getCacheFile(context, id, source);
try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) {
bm.compress(Bitmap.CompressFormat.PNG, 90, os);
}
Drawable d = new BitmapDrawable(res, bm);
d.setBounds(0, 0, Math.round(bm.getWidth() * dm.density), Math.round(bm.getHeight() * dm.density));
return d;
}
@NonNull
private static File getCacheFile(Context context, long id, String source) {
File dir = new File(context.getCacheDir(), "images");
if (!dir.exists())
dir.mkdir();
return new File(dir, id + "_" + Math.abs(source.hashCode()) + ".png");
}
static Bitmap decodeImage(File file, int scaleToPixels) {
try {
return _decodeImage(file, scaleToPixels);