zoukankan      html  css  js  c++  java
  • Android加载网络图片的工具类

    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();
        }
    
    
    }
  • 相关阅读:
    从小知识开始练习
    shell的基本语法
    shell的一些简单用法
    HTML 父元素与子元素之间的margin-top问题
    HTML input文本框设置和移除默认值
    c# winform进入窗口后在文本框里的默认焦点
    c#面向对象基础 重写、虚方法、抽象类
    c#面向对象基础 封装、继承
    c#面向对象基础 静态成员、构造函数、命名空间与类库
    c#面向对象基础 类、方法、方法重载
  • 原文地址:https://www.cnblogs.com/yaxiaoke/p/4825066.html
Copyright © 2011-2022 走看看