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(); } }