732003684

导航

加载图片

/**
 * 
 */
package cn.etong.util;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.widget.ImageView;
import cn.etong.data.NetProtocol;

/**
 * @author jin001.wu@gmail.com <br>
 * @date 2012-9-4
 * 
 */
public class ImageLoader {
    private static final int MAX_THREAD = 5;
    private static final int MAX_IMAGE_QUEUE_SIZE = 20;
    private static final LinkedList<String> mFileWaitingList = new LinkedList<String>();
    private static final HashSet<String> mFileRunningSet = new HashSet<String>();
    private static final HashMap<String, Object> mFileWatitingValues = new HashMap<String, Object>();

    public final static String TAG = "ImageLoader";
    HashMap<String, SoftReference<Bitmap>> mImageBuffer = null;

    public final static String SDCARD_PICTURE_CACHE_PATH = "/com.etong.etong_cache/";
    private final static long FIFTEEN_DAYS = 10 * 24 * 60 * 60 * 1000;

    public ImageLoader() {
        mImageBuffer = new HashMap<String, SoftReference<Bitmap>>();

        // Create image cache directory in SDCard
        if (Util.checkSDCard()) {
            File file = new File(Environment.getExternalStorageDirectory()
                    + SDCARD_PICTURE_CACHE_PATH);
            if (file != null && !file.exists()) {
                file.mkdir();
            }
        }
        clearTempFiles();
    }

    public void clearTempFiles() {
        if (Util.checkSDCard()) {
            File file = new File(Environment.getExternalStorageDirectory()
                    + SDCARD_PICTURE_CACHE_PATH);

            if (file != null && file.exists()) {
                File[] filelist = file.listFiles();

                File tempfile = null;
                for (int i = 0; i < filelist.length; i++) {
                    tempfile = filelist[i];
                    // Delete the modified time is more than fifteen days
                    if (System.currentTimeMillis() - tempfile.lastModified() > FIFTEEN_DAYS) {
                        tempfile.delete();
                    }
                }
            }
        }
    }

    class CanvasImageTask extends AsyncTask<Object, Void, Bitmap> {
        /** After load picture, will set it to this view */
        private SoftReference<Object> gView;

        /** According to this URL to down load picture */
        private String url;

        /** Down load and generate bitmap object */
        Bitmap bmp = null;

        /** Whether need write picture to cache */
        private boolean mIsCache = true;

        public CanvasImageTask(boolean isCache) {
            mIsCache = isCache;
        }

        @Override
        protected Bitmap doInBackground(Object... str) {
            // Decode parameters
            url = str[0].toString();
            if (str[1] != null) {
                gView = new SoftReference<Object>(str[1]);
            }

            if (!mImageBuffer.containsKey(url)) {
                // Load picture from local, SDCard or cache
                String fileName = Util.getImageName(url);
                File file = null;
                if (mIsCache) {
                    file = new File(Global.G().getApp().getCacheDir(), fileName);
                } else {
                    if (Util.checkSDCard()) {
                        file = new File(
                                Environment.getExternalStorageDirectory()
                                        + SDCARD_PICTURE_CACHE_PATH, fileName);
                    }
                }

                // Decode bitmap according special director
                if (file != null && file.exists()) {
                    bmp = tryToDecodeImageFile(file.getPath(), 1, true);
                }

                if (bmp != null) {
                    mImageBuffer.put(url, new SoftReference<Bitmap>(bmp));
                } else if (null != (bmp = loadImageFromUrl(url, file))) { // Down
                                                                            // load
                    // from
                    // network
                    mImageBuffer.put(url, new SoftReference<Bitmap>(bmp));
                }
            }

            return bmp;
        }

        @Override
        protected void onPostExecute(Bitmap bm) {
            if (bm != null) {
                Object gv = gView != null ? gView.get() : null;
                if (gv instanceof ImageView) {
                    ImageView imageView = (ImageView) gv;
                    imageView.setImageBitmap(bmp);
                } else if (gv instanceof ImageLoadListener) {
                    ((ImageLoadListener) gv).onLoaded(url, bmp);
                }
            }

            mFileRunningSet.remove(url);
            if (mFileWaitingList.size() > 0) {
                for (;;) {
                    if (mFileWaitingList.size() > 0) {
                        String image = mFileWaitingList.removeFirst();
                        Object next = mFileWatitingValues.get(image);
                        mFileWatitingValues.remove(image);
                        if (next == null) {
                            continue;
                        }

                        Object[] obj = (Object[]) next;
                        Object gView = null;
                        if (obj.length >= 2) {
                            SoftReference<Object> ref = (SoftReference<Object>) obj[1];
                            if (ref != null) {
                                gView = ref.get();
                            }
                        }

                        if (gView != null) {
                            Object str[] = new Object[2];
                            str[0] = image;
                            str[1] = gView;
                            if (str != null) {
                                new CanvasImageTask(false).execute(obj);
                            }
                        }

                    } else {
                        break;
                    }
                }
            }
        }
    }

    public Bitmap getBitmap(String imageURL) {
        if (imageURL == null) {
            return null;
        }

        Bitmap bt = null;
        if (mImageBuffer.containsKey(imageURL)) {
            SoftReference<Bitmap> ref = mImageBuffer.get(imageURL);
            bt = ref.get();
        }

        return bt;
    }

    public Bitmap getBitmap(final Object view, final String imageURL) {

        if (Util.isEmpty(imageURL)) {
            return null;
        }
        Bitmap bmp = null;
        if (mImageBuffer.containsKey(imageURL)) {
            bmp = mImageBuffer.get(imageURL).get();
            if (bmp != null) {
                if (view instanceof ImageView) {
                    ImageView imageView = (ImageView) view;
                    imageView.setImageBitmap(bmp);
                } else if (view instanceof ImageLoadListener) {
                    ((ImageLoadListener) view).onLoaded(imageURL, bmp);
                } else {
                    Log.w(TAG, "Unkown view get bitmap!");
                }

                return bmp;
            }
        }

        if (mFileRunningSet.contains(imageURL)) {
            Log.e("ImageCache", "inRunningSet");
        } else if (mFileWaitingList.contains(imageURL)) {
            Log.e("ImageCache", "inWaitingSet");
        } else {
            if (mFileRunningSet.size() > MAX_THREAD) {
                Object str[] = new Object[2];
                str[0] = (imageURL);
                str[1] = new SoftReference<Object>(view);
                mFileWaitingList.add(imageURL);
                mFileWatitingValues.put(imageURL, str);
                if (mFileWaitingList.size() > MAX_IMAGE_QUEUE_SIZE) {
                    mFileWaitingList.removeLast();
                }
            } else {
                mFileRunningSet.add(imageURL);
                Object str[] = new Object[2];
                str[0] = imageURL;
                str[1] = view;
                new CanvasImageTask(false).execute(str);
            }
        }

        return null;
    }

    public Bitmap loadingBitBitmap(Context context, String url) {
        if (url == null || url.length() == 0) {
            return null;
        }

        Bitmap bt = null;
        if (mImageBuffer.containsKey(url)) {
            SoftReference<Bitmap> ref = mImageBuffer.get(url);
            if (ref != null) {
                bt = ref.get();
            }
        }
        if (bt != null) {
            return bt;
        }
        return readyLoad(context, url);
    }

    private Bitmap readyLoad(Context context, String url) {
        return readLoad(context, Environment.getExternalStorageDirectory()
                + SDCARD_PICTURE_CACHE_PATH, url);
    }

    private Bitmap readLoad(Context context, String path, String url) {
        Bitmap bmp = null;
        // Load picture from local, SDCard or cache
        String fileName = Util.getImageName(url);
        File file = null;
        file = new File(path, fileName);

        // Decode bitmap according special director
        if (file != null && file.exists()) {
            bmp = tryToDecodeImageFile(file.getPath(), 1, true);
        }

        if (bmp != null) {
            mImageBuffer.put(url, new SoftReference<Bitmap>(bmp));
        } else if (null != (bmp = loadImageFromUrl(url, file))) { // Down load
                                                                    // from
                                                                    // network
            mImageBuffer.put(url, new SoftReference<Bitmap>(bmp));
        }

        return bmp;
    }

    public void releaseBitmap(String url) {
        if (mImageBuffer.containsKey(url)) {
            Bitmap bmp = mImageBuffer.get(url).get();
            if (bmp != null) {

                try {
                    bmp.recycle();
                } catch (RuntimeException e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
            }

            bmp = null;
            mImageBuffer.remove(url);
        }
    }

    private Bitmap loadImageFromUrl(String urlString, File file) {
        urlString = NetProtocol.DOMAIN_URL + urlString;
        Bitmap bitmap = null;
        HttpURLConnection conn = null;
        InputStream is = null;

        try {
            URL url = new URL(urlString);
            conn = (HttpURLConnection) url.openConnection();
            is = conn.getInputStream();
            // Get the length
            int length = (int) conn.getContentLength();
            if (length != -1) {
                byte[] imgData = new byte[length];
                byte[] temp = new byte[1024];
                int readLen = 0;
                int destPos = 0;
                while ((readLen = is.read(temp)) > 0) {
                    System.arraycopy(temp, 0, imgData, destPos, readLen);
                    destPos += readLen;
                }

                bitmap = BitmapFactory.decodeByteArray(imgData, 0,
                        imgData.length);

                // Save to cache
                if (file != null) {
                    writeBitmapToCache(imgData, file);
                }
            } else {
                Log.i(TAG, "no length!");
                bitmap = BitmapFactory.decodeStream(is);
            }

            if (is != null) {
                is.close();
            }

            if (conn != null) {
                conn.disconnect();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        }

        return bitmap;
    }

    public void writeBitmap(Bitmap bit, String url) {
        if (bit == null || Util.isEmpty(url)) {
            return;
        }

        String fileName = Util.getImageName(url);
        File file = new File(Environment.getExternalStorageDirectory()
                + SDCARD_PICTURE_CACHE_PATH, fileName);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bit.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        writeBitmapToCache(baos.toByteArray(), file);
    }

    private void writeBitmapToCache(byte[] imgData, File file) {
        FileOutputStream fos = null;
        BufferedOutputStream outPutBuffer = null;

        if (file != null) {
            try {
                fos = new FileOutputStream(file);

                outPutBuffer = new BufferedOutputStream(fos);
                outPutBuffer.write(imgData);
                outPutBuffer.flush();
                fos.flush();

            } catch (IOException e) {
                Log.e(TAG, e.toString());
            } finally {
                try {
                    if (fos != null) {
                        fos.close();
                    }

                    if (outPutBuffer != null) {
                        outPutBuffer.close();
                    }
                } catch (IOException e) {
                    Log.e(TAG, e.toString());
                }
            }
        }
    }

    public static Bitmap tryToDecodeImageFile(String filePath, int quanlity,
            boolean autoCompress) {
        Bitmap bitmap = null;
        try {
            if (quanlity == 1) {
                bitmap = BitmapFactory.decodeFile(filePath);
            } else {
                BitmapFactory.Options options = new Options();
                options.inSampleSize = quanlity;
                bitmap = BitmapFactory.decodeFile(filePath, options);
            }
        } catch (OutOfMemoryError oe) {
            /*
             * if(autoCompress){ int rate = (quanlity >= 4) ? 2 : 4; Log.d(TAG,
             * "Decode the file automatically with quanlity :" + quanlity *
             * rate); bitmap = tryToDecodeImageFile(filePath, quanlity * rate,
             * false); }else{ Log.e(TAG,
             * "Decode the file failed!, out of memory!"); oe.printStackTrace();
             * }
             */
        } catch (Exception e) {
            e.printStackTrace();
        }

        return bitmap;
    }

    public static interface ImageLoadListener {
        void onLoaded(String url, Bitmap bt);
    }
}

(用法

if (!Util.isEmpty(image)) {
Global.G().getImageLoader().getBitmap(mWeatherImage, image);
}

posted on 2013-01-24 16:26  732003684  阅读(284)  评论(0)    收藏  举报