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加载网络图片的工具类的更多相关文章

  1. android html 图片处理类--加载富文本工具类

    在android开发中,一些资讯类页面,里面有html标签和图片,html 标签一般通过Html.fromHtml方法,即可以解决,但是如果html 有图片标签,那么,Html.fromHtml 好像 ...

  2. Android加载网络图片报android.os.NetworkOnMainThreadException异常

    Android加载网络图片大致可以分为两种,低版本的和高版本的.低版本比如4.0一下或者更低版本的API直接利用Http就能实现了: 1.main.xml <?xml version=" ...

  3. Java加载Properties配置文件工具类

    Java加载Properties配置文件工具类 import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; ...

  4. Android加载网络图片学习过程

    好多应用,像我们公司的<乘友>还有其他的<飞鸽><陌陌><啪啪>这些,几乎每一款应用都需要加载网络图片,那ToYueXinShangWan,这是比须熟练 ...

  5. android 加载网络图片

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  6. Android 加载网络图片设置到ImageView

    下载图片后显示在ImageView中 //1.定义全局变量 private Handler handler; private String image_url; private Bitmap bitm ...

  7. 加载Properties文件工具类:LoadConfig

    import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.Path; impor ...

  8. Android中用双缓存技术,加载网络图片

    最近在学校参加一个比赛,写的一个Android应用,里面要加载大量的网络图片,可是用传统的方法图片一多就会造成程序出现内存溢出而崩溃.因为自己也在学习中,所以看了很多博客和视频,然后参照这些大神的写源 ...

  9. Android Volley入门到精通:使用Volley加载网络图片

    在上一篇文章中,我们了解了Volley到底是什么,以及它的基本用法.本篇文章中我们即将学习关于Volley更加高级的用法,如何你还没有看过我的上一篇文章的话,建议先去阅读Android Volley完 ...

随机推荐

  1. POJ 3094 Quicksum 难度:0

    http://poj.org/problem?id=3094 #include<iostream> #include <string> using namespace std; ...

  2. windows-docker开发我常用命令 docker-machine ssh default

    docker-machine ssh default  docker logs test sudo systemctl start docker       docker tag IMAGEID ne ...

  3. BAT文件执行完成后如何删除自身的解决办法

    在BAT文件的最后加上一句 del %0,就可以在处理完后,删除自己了

  4. android开机启动过程

    Android系统开机主要经历三个阶段: bootloader启动 Linux启动 Android启动 启动文件: 对于机器从通电到加载Linux系统一般需要三个文件:bootloader(引导文件) ...

  5. mybatis写mapper文件注意事项(转)

    原文链接:http://wksandy.iteye.com/blog/1443133 xml中某些特殊符号作为内容信息时需要做转义,否则会对文件的合法性和使用造成影响 < < > & ...

  6. 分享我设计的iOS项目目录结构

    公司新项目就要着手研发了,希望能为这个项目多准备点知识.回想自己做过的项目,目录结构的划分总不如我的心意,有些目录命名不规范导致表达不明确,有些目录因为不具有代表性,导致在实际中不能充分发挥作用,导致 ...

  7. MongoDB数据访问[C#]附源码下载(查询增删改) 转载

    安装完MongoDBhttp://localhost:28017/监测是否成功! vs 2008 C# MongoDB 源代码下载地址:http://download.csdn.net/source/ ...

  8. 2013年8月份第1周51Aspx源码发布详情

    校企工作室OA源码  2013-8-9 [VS2010]源码描述:主要模块及系统管理功能说明:一.考勤功能模块:考勤分成三个功能,显示签到功能,查询功能,管理功能.1.签到功能分析:在签到功能中,我们 ...

  9. BI--SDN上收集到的SAP BI的极好文章的链接

    1)Overviewhttps://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/60981d00-ca87-2910-fdb ...

  10. 深入学习:如何实现不同Android设备之间相同应用程序的网络服务发现功能

    在我们的app中添加网络服务发现功能(NSD)以方便在不同的设备上响应局域网中的请求.这种功能对于多设备之间点对点服务来说很有用,例如多人游戏,多人通话,文件共享等. 一,在网络中注册你的服务 注意: ...