码迷,mamicode.com
首页 > 移动开发 > 详细

Android加载网络图片的工具类

时间:2015-09-21 06:57:28      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:

ImageView加载网络的图片

HttpUtil.java

package com.eiice.httpuimagetils;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.graphics.Bitmap;
import android.util.Log;

/**
 * @author 与网络连接的工具类
 *
 */
public class HttpUtil {

    public static Bitmap download(String path){
        try{
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            InputStream in = conn.getInputStream();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int len = 0;
            byte buff[] = new byte[1024];
            while((len = in.read(buff)) > 0){
                out.write(buff, 0 ,len);
            }
            in.close();
            out.close();
            Log.e("test", "download:"+path);
            byte image[] = out.toByteArray();
            return ImageUtil.bytes2Bimap(image);
        }catch(Exception e){
            e.printStackTrace();
            return null;
        }
    }
}

 

ImageLoader.java

package com.eiice.httpuimagetils;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
import java.util.WeakHashMap;

import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.support.v4.util.LruCache;
import android.util.Log;
import android.widget.ImageView;

/**
 * 本地图片加载,没有获取到网络的图片数据,就先显示本地的。得到网络的数据,再显示最新的。
 */
public class ImageLoader {

    private static final String TAG = "ImageLoader";

    private ImageCache cache;

    private HashSet<String> cacheKeys = new HashSet<String>();
    
    private ImageDownloader downloader;
    
    private WeakHashMap<ImageView, String> imageView2FileMap = new WeakHashMap<ImageView, String>();
    private HashMap<String, HashSet<ImageViewReference>> file2ImageViewMap = new HashMap<String, HashSet<ImageViewReference>>();
    private HashSet<String> fileInLoadSet = new HashSet<String>();

    public ImageLoader(ImageDownloader downloader) {
        if(downloader == null){
            throw new RuntimeException("ImageDownloader can not be null");
        }
        this.cache = ImageCache.getInstance();
        this.downloader = downloader;
    }

    /**
     * @return 缓存中有,直接设置,并返回true,没有异步读取,读完再设置,返回false
     */
    public boolean loadImage(String filePath, int width, int height, ImageView imageView) {
        String filePathKey = getKeyForFilePath(filePath, width, height);
        Bitmap bmp = cache.get(filePathKey);
        if (bmp == null) {
            ImageViewReference imageViewRef = new ImageViewReference(imageView);
            // 更新imageView和filepath的最新的关系
            imageView2FileMap.put(imageView, filePathKey);
            HashSet<ImageViewReference> imageViewSet = file2ImageViewMap.get(filePathKey);
            if (imageViewSet == null) {
                imageViewSet = new HashSet<ImageViewReference>();
                file2ImageViewMap.put(filePathKey, imageViewSet);
            }
            imageViewSet.add(imageViewRef);
            // 防止重复下载
            if (fileInLoadSet.contains(filePathKey)) {
                return false;
            } else {
                fileInLoadSet.add(filePathKey);
            }
            Holder holder = new Holder();
            holder.width = width;
            holder.height = height;
            holder.filePath = filePath;
            holder.filePathKey = filePathKey;
            holder.imageViewRef = imageViewRef;
            new ImageLoadTask().execute(holder);
            return false;
        } else {
            imageView.setImageBitmap(bmp);
            return true;
        }

    }

    private class ImageLoadTask extends AsyncTask<Holder, Void, Holder> {

        @Override
        protected Holder doInBackground(Holder... params) {
            Holder holder = params[0];
            int width = holder.width;
            int height = holder.height;
            String filePath = holder.filePath;
            String filePathKey = holder.filePathKey;
            int count = getCountOfImageViewForKey(filePathKey);
            if (count <= 0) {
                return null;
            }
            try {
                Random rnd = new Random();
                Thread.sleep((int) (1000 * rnd.nextDouble()));
            } catch (Exception e) {
                e.printStackTrace();
            }
            if(downloader != null){
                Bitmap bmp = downloader.download(filePath, width, height);
                if(bmp != null){
                    cache.put(filePathKey, bmp);
                    cacheKeys.add(filePath);
                    holder.imageData = bmp;
                }
            }
            return holder;
        }

        @Override
        protected void onPostExecute(Holder holder) {
            super.onPostExecute(holder);
            String filePathKey = holder.filePathKey;
            fileInLoadSet.remove(filePathKey);
            
            Bitmap data = holder.imageData;
            if(data == null){
                return;
            }
            
            ArrayList<ImageView> imageViewArrayList = getImageViewListForKey(filePathKey);
            if (imageViewArrayList.size() == 0) {
                return;
            }
            for (ImageView imageView : imageViewArrayList) {
                String latestFilePathKey = imageView2FileMap.get(imageView);
                if (latestFilePathKey != null && latestFilePathKey.equals(filePathKey)) {
                    if (imageView != null) {
                        imageView.setImageBitmap(data);
                        Log.e(TAG, "设置图片 ");
                        /*
                         * boolean isSet; 
                         * try{ 
                         *         isSet=(Boolean)
                         *         imageView.getTag(); 
                         * }catch(Exception e) {
                         *         isSet=true; 
                         * } 
                         * if(isSet) {
                         *         imageView.setImageBitmap(result); 
                         *         Log.e(TAG,"设置图片 "); 
                         * }
                         */
                    }
                    imageView2FileMap.remove(imageView);
                } else {
                    
                }
            }
            file2ImageViewMap.remove(filePathKey);
        }
    }

    class Holder {
        int width,height;
        String filePath, filePathKey;
        Bitmap imageData;
        ImageViewReference imageViewRef;
    }

    private String getKeyForFilePath(String imagePath, int width, int height) {
        return imagePath + "_" + width + "_" + height;
    }

    /**
     * ????ImageLoader
     * 
     * */
    public void clear(){
        imageView2FileMap.clear();
        file2ImageViewMap.clear();
        fileInLoadSet.clear();
        for(String cacheKey : cacheKeys){
            cache.remove(cacheKey);
        }
        cacheKeys.clear();
        imageView2FileMap = null;
        file2ImageViewMap = null;
        fileInLoadSet = null;
        cacheKeys = null;
        downloader = null;
        cache = null;
    }
    
    /**
     * ImageLoader.java退出时调用
     * 
     * */
    public void destory() {
        clear();
        ImageCache.destroy();
    }
    
    
    public interface ImageDownloader{
        public Bitmap download(String path,int width, int height);
    }

    /**
     * 通过file2ImageViewMap获取filePath对应的所有imageView列表 同时删除被回收的imageView,
     * 
     * @param filePathKey
     * @return
     */
    private ArrayList<ImageView> getImageViewListForKey(String filePathKey) {
        ArrayList<ImageView> imageViewArrayList = new ArrayList<ImageView>();
        HashSet<ImageViewReference> imageViewReferences = file2ImageViewMap.get(filePathKey);
        if(imageViewReferences == null){
            return null;
        }
        Iterator<ImageViewReference> it = imageViewReferences.iterator();
        while (it.hasNext()) {
            ImageViewReference reference = it.next();
            if (reference.get() != null) {
                imageViewArrayList.add(reference.get());
            } else {
                it.remove();
            }
        }
        return imageViewArrayList;
    }

    /**
     * 获取指定的filePath对应的有效imageView的数据
     * 
     * @param filePathKey
     * @return
     */
    private int getCountOfImageViewForKey(String filePathKey) {
        ArrayList<ImageView> imageViewArrayList = getImageViewListForKey(filePathKey);
        if(imageViewArrayList == null){
            return 0;
        }else{
            return imageViewArrayList.size();
        }
    }
    
    private static class ImageCache extends LruCache<String, Bitmap> {
        private static final int cacheSize = 10 * 1024 * 1024;
        private static ImageCache instance = new ImageCache(cacheSize);
        public static ImageCache getInstance(){
            return instance;
        }
        private ImageCache(int maxSize) {
            super(maxSize);
        }
        @Override
        protected int sizeOf(String key, Bitmap value) {
            return value.getByteCount();
        }
        public static void destroy(){
            if(instance == null){
                return;
            }
            instance.evictAll();
            instance = null;
        }
    }
    
    private static class ImageViewReference extends WeakReference<ImageView> {
        public ImageViewReference(ImageView r) {
            super(r);
        }
        @Override
        public boolean equals(Object o) {
            ImageViewReference other=(ImageViewReference)o;
            return this.get()==other.get();
        }
        @Override
        public int hashCode() {
            ImageView imageView = this.get();
            if(imageView != null){
                return imageView.hashCode();
            }
            return 0;
        }
    }
    
}

ImageUtil.java

package com.eiice.httpuimagetils;

import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;

public class ImageUtil {
    
    static final String TAG="ImageUtil";
    
    public static Bitmap compressPic2Bitmap(String picfullname) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(picfullname, options); // 此时返回bm为空
        options.inJustDecodeBounds = false;
        int be = (int) (options.outHeight / (float) 200);
        if (be <= 0)
            be = 1;
        options.inSampleSize = be;
        bitmap = BitmapFactory.decodeFile(picfullname, options);
        return bitmap;
    }

    public static Drawable bitmap2Drawable(Bitmap bm) {
        BitmapDrawable bd = new BitmapDrawable(bm);
        return bd;
    }

    public static Drawable compressPic2Drawable(String picfullname) {
        return bitmap2Drawable(compressPic2Bitmap(picfullname));
    }

    public static Bitmap compressPic2Bitmap(Bitmap bitmap, int width, int height, boolean isAdjust) {
        if (bitmap.getWidth() < width && bitmap.getHeight() < height) {
            return bitmap;
        }
        float sx = new BigDecimal(width).divide(new BigDecimal(bitmap.getWidth()), 4, BigDecimal.ROUND_DOWN)
                .floatValue();
        float sy = new BigDecimal(height).divide(new BigDecimal(bitmap.getHeight()), 4, BigDecimal.ROUND_DOWN)
                .floatValue();
        if (isAdjust) {
            sx = (sx < sy ? sx : sy);
            sy = sx;
        }
        Matrix matrix = new Matrix();
        matrix.postScale(sx, sy);
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    }

    public static Drawable compressPic2Drawable(String picfullname, int width, int height) {
        // Bitmap bitmap = compressPic2Bitmap(picfullname);
        // bitmap = compressPic2Bitmap(bitmap, width, height, true);

        Bitmap bitmap = compressBitmap(picfullname, width, height);
        return new BitmapDrawable(bitmap);
    }

    public static Bitmap compressBitmap(String path, int sdwidth, int sdheight) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;

        BitmapFactory.decodeFile(path, options);
        options.inSampleSize = calculateSampleSize(options, sdwidth, sdheight);
        options.inJustDecodeBounds = false;
        options.inDither = false;
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        return BitmapFactory.decodeFile(path, options);
    }

    public static int calculateSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }
    /**
     * 有损压缩图片
     * @param filePath
     * @return
     */
    public static byte[] compressBitmap(String filePath) {
        Bitmap sourceBmp=BitmapFactory.decodeFile(filePath);
        if(sourceBmp!=null)
        {
            Log.e(TAG, "原大小"+sourceBmp.getByteCount());
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            sourceBmp.compress(Bitmap.CompressFormat.JPEG, 60, baos);
            sourceBmp.recycle();
            sourceBmp=null;
            //如果压缩后还大于10M,再压一次,这种情况一般不会出现
            if(baos.size()>10*1024*1024)
            {
                byte[] bytes=baos.toByteArray();
                Bitmap tempBmp=BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                baos.reset();
                tempBmp.compress(Bitmap.CompressFormat.JPEG, 30, baos);
                tempBmp.recycle();
                tempBmp=null;
            }
            byte[] bytes=baos.toByteArray();
            Log.e(TAG, "压缩后大小"+bytes.length);
            return bytes;
        }else{
            return null;
        }
    }
    
    public static Bitmap bytes2Bimap(byte[] b) {
         if (b.length != 0) {
             return BitmapFactory.decodeByteArray(b, 0, b.length);
         } else {
             return null;
         }
     }
}

 

 

测试代码:activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/imageview"
        android:layout_width="400dp"
        android:layout_height="400dp" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="show" />

</LinearLayout>

MainActivity.java

package com.eiice.cn;


import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

import com.eiice.httpuimagetils.HttpUtil;
import com.eiice.httpuimagetils.ImageLoader;
import com.eiice.httpuimagetils.ImageLoader.ImageDownloader;

public class MainActivity extends Activity {
    private ImageLoader imageLoader;
    private ImageView imageview;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageview = (ImageView) findViewById(R.id.imageview);
        imageLoader = new ImageLoader(new ImageDownloader(){
            @Override
            public Bitmap download(String path, int width, int height) {
                return HttpUtil.download(path);
            }
        });
    }
    
    public void show(View view){
        
        String imagepath = "http://img4.duitang.com/uploads/blog/201309/30/20130930115633_h8BEL.thumb.600_0.jpeg";
        imageLoader.loadImage(imagepath , 50, 50, imageview);
    }
    
    
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        imageLoader.destory();
    }


}

 

Android加载网络图片的工具类

标签:

原文地址:http://www.cnblogs.com/yaxiaoke/p/4825066.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!