Android 图片加载ImageLoader
特点:
先从缓存中取图,有--->返回
无--->去SDCard中取图 --->有---->存入缓存---->返回
--->无---->网络下载---->成功---->存入SDCard和缓存--->返回
---->失败----->默认图
(1),缓存 LruCache
(2),文件存储
(3),网络获取
效果图:
使用方法:
1,Activity中使用Listview加载图片
public class MainActivity extends ActionBarActivity {
private ListView mListView;
private LImageLoader loader;
private void init() {
mListView = (ListView) findViewById(R.id.listView);
ArrayList<String>L=new ArrayList<String>();
//要下载的图片链接
L.add("http://img4.duitang.com/uploads/item/201210/17/20121017205706_EhTQY.jpeg");
L.add("http://ia.topit.me/a/a4/e2/1187548894fc3e2a4ao.jpg");
L.add("http://p1.qq181.com/cms/120509/2012050914104698028.jpg");
L.add("http://f9.topit.me/9/ea/f9/1188292031291f9ea9o.jpg");
L.add("http://www.onegreen.net/QQ/UploadFiles/201303/2013033012415080.jpg");
L.add("http://p1.qqhot.com/G1/M00/B7/F2/rBACE1Pls_awQhqiAACrn0jV34Q496.jpg");
L.add("http://e.hiphotos.baidu.com/zhidao/pic/item/9825bc315c6034a82a21aa02ca13495408237675.jpg");
L.add("http://i2.hoopchina.com.cn/user/235/3807235/13340168500.jpg");
L.add("http://fd.topit.me/d/0e/6a/11882912885f66a0edo.jpg");
L.add("http://img1.3lian.com/img013/v3/1/d/41.jpg");
L.add("http://img2.3lian.com/2014/f2/29/d/81.jpg");
L.add("http://img4.duitang.com/uploads/item/201202/26/20120226173858_x8uXc.jpg");
L.add("http://img.dapixie.com/uploads/allimg/120118/1-12011Q20352.jpg");
L.add("http://www.qqjia.com/z/04/tu5993_6.jpg");
L.add("http://img2.3lian.com/2014/f2/26/d/62.jpg");
L.add("http://pic26.nipic.com/20130122/9356147_132745206000_2.jpg");
L.add("http://img1.3lian.com/img013/v3/11/d/41.jpg");
L.add("http://img2.3lian.com/2014/f2/186/d/7.jpg");
L.add("http://img2.3lian.com/2014/c6/13/d/18.jpg");
L.add("http://images.ccoo.cn/ablum/20111224/20111224233830425.jpg");
L.add("http://img3.imgtn.bdimg.com/it/u=3837651252,548539279&fm=21&gp=0.jpg");
L.add("http://pic32.nipic.com/20130816/9106926_182057648111_2.jpg");
L.add("http://f5.topit.me/5/e8/52/11882923484b952e85o.jpg");
L.add("http://img.taopic.com/uploads/allimg/111028/6462-11102Q54A389.jpg");
L.add("http://pic.nipic.com/2008-01-03/200813145320942_2.jpg");
L.add("http://img1.3lian.com/gif/more/50/2012/03/76f5c3ef6b17f8490480d2758d555b91.jpg");
L.add("http://wenwen.soso.com/p/20110528/20110528145848-1249190377.jpg");
L.add("http://www.qqpk.cn/Article/UploadFiles/201310/20131031152332187.jpg");
L.add("http://img3.3lian.com/2014/s4/47/d/47.jpg");
L.add("http://www.qqpk.cn/Article/UploadFiles/201101/20110120184528397.jpg");
L.add("http://fe.topit.me/e/3d/87/11313104582e1873deo.jpg");
L.add("http://images.ccoo.cn/ablum/20120105/20120105202023054.jpg");
L.add("http://qqimg.glzy8.com/upfiles/qq/tp/123105838.jpg");
L.add("http://img.taopic.com/uploads/allimg/111230/2257-11123011311870.jpg");
L.add("http://wenwen.soso.com/p/20111229/20111229171042-1378508417.jpg");
L.add("http://img3.3lian.com/2014/f1/1/d/41.jpg");
L.add("http://img4.duitang.com/uploads/blog/201404/12/20140412211514_AJQJf.thumb.600_0.jpeg");
L.add("http://img4.duitang.com/uploads/item/201111/07/20111107004951_UEGcy.jpg");
L.add("http://picview01.baomihua.com/photos/20120629/m_14_634765711175468750_38901236.jpg");
L.add("http://img.51tietu.net/upload/200910/20091014233759444.jpg");
MyAdapter adapter=new MyAdapter(L);
mListView.setAdapter(adapter);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
loader = new LImageLoader(getApplicationContext());
}
class MyAdapter extends BaseAdapter {
private ArrayList<String> list = new ArrayList<String>();
private LayoutInflater mInflater;
public MyAdapter(ArrayList<String> l) {
this.list = l;
mInflater = LayoutInflater.from(getApplicationContext());
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return list.get(position).hashCode();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (null == convertView) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.image_list, null);
holder.m = (LImageViewT) convertView.findViewById(R.id.view);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//加载图片
<span style="color:#009900;">loader.display(holder.m, list.get(position), R.drawable.ic_launcher,200,200);</span>
return convertView;
}
class ViewHolder {
LImageViewT m;
}
}
}
2,贴上ImageLoader的代码
<pre name="code" class="java">/**
* Created by li'mingqi on 2014/12/18.
*/
public class LImageLoader {
public String TAG = LImageLoader.class.getSimpleName();
private Context mContext;
private Handler mHandler;
/** 加载图片成功 * */
private final int LOADING_IMAGE = 1;
/** 加载图片失败 * */
private final int LOADING_FAIL = 0;
/** 标记要加载图片的imageview * */
private HashMap<String, ImageView> currentLoading = new HashMap<String, ImageView>();
/**
* 是否下载图片(如果缓存和SD卡上都没有找到图片)
*/
private boolean loadImage = true;
/**SD卡文件操作**/
private LDiskClient mDiskClient;
/**缓存Lru操作**/
private LCacheBase mCacheClient;
public LImageLoader(Context context) {
this.mContext = context;
//
mDiskClient = new LDiskClient(mContext);
//
mCacheClient = new LCacheBase();
this.mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
int what = msg.what;
switch (what) {
case LOADING_IMAGE:
// 图片下载成功
String key1 = (String) msg.obj;
synchronized (currentLoading) {
if (currentLoading.containsKey(key1)) {
// 核对标记的要加载图片的imageview,并更新imageview
if (key1.equals((String) currentLoading.get(key1)
.getTag())) {
currentLoading.get(key1).setImageBitmap(
mCacheClient.findBitmapFromCache(key1));
currentLoading.get(key1).invalidate();
}
}
}
break;
case LOADING_FAIL:
// 图片下载失败
String key2 = (String) msg.obj;
synchronized (currentLoading) {
if (currentLoading.containsKey(key2)) {
// 核对标记的要加载图片的imageview,并更新imageview为默认图片
if (key2.equals((String) currentLoading.get(key2)
.getTag())) {
currentLoading.get(key2).setImageResource(
R.drawable.ic_launcher);
currentLoading.get(key2).invalidate();
}
}
}
break;
}
}
};
}
/**
* 加载图片
* @param imageView
* @param url
* @param defaultResId
*/
public void display(ImageView imageView, final String url, int defaultResId, final int width, final int height) {
//传入的url为空或者为null ---使用默认图片
if ("".equals(url) || null == url) {
imageView.setImageDrawable((mContext.getResources().getDrawable(defaultResId)));
return;
}
//标记要加载图片的imageview
synchronized (currentLoading) {
imageView.setTag(getFileName(url));
currentLoading.put(getFileName(url), imageView);
}
imageView.setImageDrawable((mContext.getResources().getDrawable(defaultResId)));
//从缓存中找图
Bitmap has = mCacheClient.findBitmapFromCache(getFileName(url));
if (null == has) {
//缓存中没有找到图片 ,接下来要到SD卡上找图
try {
has = ((BitmapDrawable) Drawable
.createFromPath(mDiskClient.getFolderPATH() + "/" + getFileName(url) + ".jpg")).getBitmap();
} catch (Exception e) {
Log.e(TAG, "BitmapFactory Parsing file failed");
new IOException("BitmapFactory Parsing file failed").printStackTrace();
}
if (null != has) {
//SD卡上找到了图片
currentLoading.remove(getFileName(url));
imageView.setImageBitmap(has);
imageView.invalidate();
//放入缓存
mCacheClient.saveBitmapToCache(getFileName(url), has);
} else {
// SD卡也没有找到图片
if (loadImage) {
// 开启网络下载新图
downLoadPicture(url, width, height);
} else {
// 使用默认图片
currentLoading.remove(getFileName(url));
imageView.setImageDrawable((mContext.getResources()
.getDrawable(defaultResId)));
}
}
} else {//缓存中找到了图片,则直接使用更新
currentLoading.remove(getFileName(url));
imageView.setImageBitmap(has);
imageView.invalidate();
}
}
// 下载网络图片
public void downLoadPicture(final String url, final int width, final int height) {
new Thread() {
@Override
public void run() {
try {
Bitmap bm = getImageStream(url, width, height);// Download network picture
Message msg = mHandler.obtainMessage();
if (null != bm) {
// 下载成功,将下载的新图放入缓存和SD卡保存
mCacheClient.saveBitmapToCache(getFileName(url), bm);
mDiskClient.savePicture(mDiskClient.getFolderPATH() + "/" + getFileName(url) + ".jpg", bm);
//通知更新
msg.what = LOADING_IMAGE;
} else {
msg.what = LOADING_FAIL;
}
// send handler
msg.obj = url;
mHandler.sendMessage(msg);
} catch (Exception e) {
Log.e(TAG, "downloading picture has problem");
new Exception("downloading picture has problem").printStackTrace();
}
}
;
}.start();
}
/**
* 从网络下载图片
*
* @param path
*
* @return
*
* @throws Exception
*/
public Bitmap getImageStream(String path, int width, int height)
throws Exception {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(path);
HttpResponse response = client.execute(get);
Bitmap bm = null;
try {
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
byte[] by = EntityUtils.toByteArray(entity);
bm = getBitmap(by, width, height);
}
} catch (OutOfMemoryError e) {
Log.e(TAG, "download picture Memory out off happened ");
new OutOfMemoryError("download picture Memory out off happened").printStackTrace();
}
return bm;
}
//图片压缩 (以原图的宽高比/传入的宽高比为缩放值)
public Bitmap getBitmap(byte[] data, int width, int height) {
//check
if (width < 0 || height < 0) {
width = 100;
height = 100;
}
BitmapFactory.Options opts = new BitmapFactory.Options();// setting
opts.inJustDecodeBounds = true;// setting enable
BitmapFactory.decodeByteArray(data, 0, data.length, opts);//get target bitmap width and height
// native bitmap params
int nativeWidth = opts.outWidth;
int nativeHeight = opts.outHeight;
int nativeScale = nativeWidth / nativeHeight;
// phone screen
int phoneWidth = width;
int phoneHeight = height;
int phoneScale = phoneWidth / phoneHeight;
//
int scale=nativeScale/phoneScale;
if (scale<1) {
scale = 1;
}
// scale
opts.inSampleSize = scale;
//config
opts.inPreferredConfig= Bitmap.Config.RGB_565;
// create a bitmap by input size
opts.inJustDecodeBounds = false;
return BitmapFactory.decodeByteArray(data, 0, data.length, opts);
}
/**
* @param key
* 截取要保存的文件名
* @return
*/
private String getFileName(String key) {
String result = "";
key = key.substring(0, key.lastIndexOf("."));
result = key.replace("/", "").replace(":", "").replace(".", "")
.replace("-", "");
return result;
}
}
最后附上源码:
http://download.csdn.net/detail/li352558693/8283063
https://github.com/tagmic/Android-ImageLoader