从RESTful API使用Spring Android Client消费图像附件

时间:2012-10-16 13:27:32

标签: android spring rest

我一直在搜索网络,试图找到一个从带有Android客户端的REST API下载文件附件的示例,即使用Spring for Android提供的其余模板。

我找不到任何有用的东西。服务器返回内容类型为image / jpeg或image / png的实体。返回的标头包括内容处置标头,如下所示:

内容 - 处置:附件;文件名=范例名称

我们不使用文件扩展名,因为我们在客户端协商并根据Android管理图片的方式处理它。我想我试图弄清楚Spring for Android框架是否可行,或者我是否需要构建自己的框架。

1 个答案:

答案 0 :(得分:0)

在我开始使用Spring之前,我自己实现了一个Web图像加载器。假设您不需要Spring用于图像或任何身份验证(后者可以添加),类似于我使用的以下类应该适合您。请注意,SimpleBitmapCache类只是LruCache的一个包装器(在支持包中提供),而getBitmapSafelyBitmapFactory.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;
        }
    }
}