스프링을 사용하기 전에 웹 이미지 로더를 직접 구현했습니다. 당신이 이미지 나 어떤 인증 (후자를 추가 할 수있는)을 위해 Spring을 필요로하지 않는다고 가정하면, 다음 클래스와 비슷한 것이 당신을 위해 작동해야합니다. SimpleBitmapCache
클래스는 LruCache (지원 패키지에서 사용 가능)의 래퍼이며, getBitmapSafely
은 OutOfMemoryError
을 잡아서 처리하는 래퍼입니다 (특정 시점까지 반복적으로 inSampleSize
을 증가 시킴).
import android.graphics.Bitmap;
import android.graphics.drawable.AnimationDrawable;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;
@Singleton
public class WebImageLoader {
private static final String TAG = WebImageLoader.class.getSimpleName();
protected SimpleBitmapCache simpleBitmapCache;
protected Pattern cachedImagePattern;
@Inject
public WebImageLoader(SimpleBitmapCache simpleBitmapCache) {
this.simpleBitmapCache = simpleBitmapCache;
}
public void fetchImageForImageView(ImageView imageView, URL url,
int maxWidth, int maxHeight, ImageView.ScaleType scaleType) {
// Sanity check: Does the request make sense?
if (imageView == null)
Log.w(TAG, "imageView doesn't exist!", new Exception());
if (url == null)
Log.w(TAG, "No URL to load!", new Exception());
if (imageView == null || url == null)
return;
// Set a tag so the downloader will set the image automatically, and so that only the correct picture is shown.
imageView.setTag(url);
// We only need to start the Downloader if the Bitmap isn't cached
if (!isBitmapCached(url)) {
new Downloader(imageView, url, scaleType).execute();
} else {
imageView.setScaleType(scaleType);
imageView.setImageBitmap(getBitmapFromCache(url));
}
}
public void clearCache() {
simpleBitmapCache.clear();
}
private boolean isBitmapCached(URL url) {
return (simpleBitmapCache != null) && (simpleBitmapCache.contains(url));
}
private Bitmap getBitmapFromCache(URL url) {
return (Bitmap) simpleBitmapCache.get(url);
}
private void setBitmapIntoCache(Bitmap bitmap, URL url) {
if (simpleBitmapCache != null) {
simpleBitmapCache.put(url, bitmap);
}
}
private class Downloader extends AsyncTask<Void, Void, Bitmap> {
protected final static int DEFAULT_ATTEMPTS = 3;
protected final static long SLEEP_TIME = 3000;
private final static String TAG = Downloader.class.getSimpleName();
protected WeakReference<ImageView> imageViewRef;
protected ImageView.ScaleType finalScaleType;
protected URL url;
public Downloader(final ImageView imageView, URL url, ImageView.ScaleType scaleType) {
this.imageViewRef = new WeakReference<ImageView>(imageView);
this.url = url;
if (scaleType == null)
this.finalScaleType = ImageView.ScaleType.FIT_CENTER;
else
this.finalScaleType = scaleType;
// Set a download animation
imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setImageResource(android.R.drawable.stat_sys_download);
AnimationDrawable animation = (AnimationDrawable)imageView.getDrawable();
imageView.post(animation);
}
@Override
protected Bitmap doInBackground(Void... params) {
return downloadBitmap(url);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
// Update the cache
setBitmapIntoCache(bitmap, url);
ImageView imageView = imageViewRef.get();
if (imageView != null) {
// Let's verify if that ImageView wasn't recycled
if (imageView.getTag() != null && imageView.getTag().equals(url)) {
imageView.setScaleType(finalScaleType);
imageView.setImageBitmap(bitmap);
imageView.setTag(null); // because it WILL be recycled later
}
}
}
protected Bitmap downloadBitmap(URL url) {
return downloadBitmap(url, DEFAULT_ATTEMPTS);
}
protected Bitmap downloadBitmap(URL url, int attemptsLeft) {
Bitmap bitmap = null;
InputStream is = null;
HttpURLConnection connection = null;
int responseCode = -1;
attemptsLeft--;
//Log.v(TAG, "Downloading "+url);
try {
connection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
Log.e(TAG, "Failed to open HttpConnection for "+url.getPath(), e);
}
if (connection != null) {
try {
responseCode = connection.getResponseCode();
} catch (IOException e) {
Log.e(TAG, "Failed to get response code for "+connection.getURL(), e);
}
if (200 == responseCode) {
try {
is = connection.getInputStream();
} catch (IOException e) {
Log.e(TAG, "Failed to open InputStream for "+connection.getURL(), e);
}
// Finally create the bitmap from the InputStream
if (is != null) {
try {
bitmap = ImageUtil.getBitmapSafely(is, 1);
} catch (ImageUtil.BitmapTooLargeException e) {
Log.e(TAG, "Giving up on decoding "+connection.getURL());
}
}
} else if (responseCode != -1) {
if (responseCode == 404)
Log.d(TAG, "Image not found: "+url.toString());
else
Log.e(TAG, "Unexpected response code "+responseCode+" for "+connection.getURL());
}
}
if (bitmap == null && responseCode == -1 && attemptsLeft > 0) {
try {
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {
Log.w(TAG, "Download interrupted: "+url.getPath(), e);
return bitmap;
}
Log.d(TAG, "Retrying download of "+url.getPath());
return downloadBitmap(url, attemptsLeft);
}
return bitmap;
}
}
}
현재 비슷한 솔루션을 구현했지만 여전히 나머지 모든 템플릿을 사용하고 싶습니다. 나는 안드로이드 사용자들을 위해 Spring을 트위터로 만들었고, 그들은 아마 그것을 조사하고있다. –
그래, 내가이 포스팅을 본 곳이야. 나는 Spring을 사용하지 않기로 결정했다면 적어도 당신에게 탈출구를 줄 것이라고 생각했다. 나는 이미지 로딩에 대해 좀 더 구체적인 것을 가지고 있다고 느꼈다. – Keilaron