我一直在搜索网络,试图找到一个从带有Android客户端的REST API下载文件附件的示例,即使用Spring for Android提供的其余模板。
我找不到任何有用的东西。服务器返回内容类型为image / jpeg或image / png的实体。返回的标头包括内容处置标头,如下所示:
内容 - 处置:附件;文件名=范例名称
我们不使用文件扩展名,因为我们在客户端协商并根据Android管理图片的方式处理它。我想我试图弄清楚Spring for Android框架是否可行,或者我是否需要构建自己的框架。
答案 0 :(得分:0)
在我开始使用Spring之前,我自己实现了一个Web图像加载器。假设您不需要Spring用于图像或任何身份验证(后者可以添加),类似于我使用的以下类应该适合您。请注意,SimpleBitmapCache
类只是LruCache的一个包装器(在支持包中提供),而getBitmapSafely
是BitmapFactory.decodeStream()
的包装器,用于捕获和处理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;
}
}
}