众所都知,现在的android APP基本上都存在很多图片展示模块,对于刚入门的小白来说要自己写个图片加载框架是很难的
,所以我今天出个简单的图片加载框架,希望看了这篇文章的小白们能够学会使用AsyncTask+DiskLruCache+LruCache,加载
图片。好啦,闲话少说开始进入代码块.
1.通过DiskLruCachede的open方法得到 DiskLruCachede对象第一个为图片缓存的文件,第二个为版本号,第三个传一个1就行,第四个为缓存的容量
mDisCache = DiskLruCache.open(file, getVersion(), 1, 10 * 1024 * 1024);
2.初始化LruCache对象.
<pre name="code" class="java"> try {
mDisCache = DiskLruCache.open(file, getVersion(), 1, 10 * 1024 * 1024);
Log.e("TAG","filed "+file.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
3.获取app的缓存路径和版本号.
/**
* 获取缓存路径
* @param uniName 文件名
* @return 返回路径
*/
private static String getCacheDir(String uniName){
String cache = "";
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
cache = Environment.getDownloadCacheDirectory().getAbsolutePath();
}
cache = context.getCacheDir().getAbsolutePath();
return cache+ File.separator+uniName;
}
/**
* 获取app的版本号
* @return
*/
private static int getVersion(){
int version = 1 ;
PackageManager packageManager = context.getPackageManager();
try {
PackageInfo packageInfo = packageManager.getPackageInfo("com.huangdi.pictureframework", PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
version = packageInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return version;
}
4.DiskLruCache的中其他两个需要使用的方法为
<span style="white-space:pre"> </span>DiskLruCache.Snapshot snapshot;
try {
snapshot = mDisCache.get(paramsms);
if(snapshot==null){
DiskLruCache.Editor edit = mDisCache.edit(paramsms);
if(edit!=null){
//请求网络下载图片
OutputStream outputStream = edit.newOutputStream(0);
if(downImageWithUrl(params[0],outputStream)){
edit.commit();
}else{
edit.abort();
}
}
}
//下载完后在次获取图片流
snapshot = mDisCache.get(paramsms);
if(snapshot!=null){
fileInputStream = (FileInputStream) snapshot.getInputStream(0);
fieds = fileInputStream.getFD();
}
Bitmap bitmap = null;
if(fieds!=null){
//从路径中得图片
bitmap = BitmapFactory.decodeFileDescriptor(fieds);
}
//将图片保存到LruCache中
if(bitmap!=null){
if(mLruCache.get(paramsms)==null){
mLruCache.put(paramsms,bitmap);
}
}
5.全部代码如下:
package com.huangdi.pictureframework.pirturesLoader;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.util.LruCache;
import android.widget.AbsListView;
import android.widget.ImageView;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashSet;
import java.util.Set;
/**
* Created by huangdi on 15/8/18.
*/
public class ImageLoaderUtils {
private ImageLoaderUtils(){};
private static ImageLoaderUtils imageLoaderUtils;
private static Context context;
//声明一个任务集合
private Set<LoadTasks> tasks = new HashSet<LoadTasks>();
//传入的listview或者gridview用来获取当前tag对应的ImageViewe
private static AbsListView mListView;
//声明Lru
private static LruCache<String ,Bitmap> mLruCache;
//声明硬盘缓存对象
private static DiskLruCache mDisCache;
public static ImageLoaderUtils getInstance(Context mContext,String uniName,AbsListView listView) {
if (imageLoaderUtils == null) {
synchronized (ImageLoaderUtils.class) {
context = mContext;
imageLoaderUtils = new ImageLoaderUtils();
mListView = listView;
long size = Runtime.getRuntime().maxMemory() / 8;
String cacheDir = getCacheDir(uniName);
File file = new File(cacheDir);
if (!file.exists()) {
file.mkdir();
}
try {
mDisCache = DiskLruCache.open(file, getVersion(), 1, 10 * 1024 * 1024);
Log.e("TAG","filed "+file.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
;
mLruCache = new LruCache<String ,Bitmap>((int) size){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();
}
};
}
}
return imageLoaderUtils;
}
/**
* 获取缓存路径
* @param uniName 文件名
* @return 返回路径
*/
private static String getCacheDir(String uniName){
String cache = "";
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
cache = Environment.getDownloadCacheDirectory().getAbsolutePath();
}
cache = context.getCacheDir().getAbsolutePath();
return cache+ File.separator+uniName;
}
/**
* 获取app的版本号
* @return
*/
private static int getVersion(){
int version = 1 ;
PackageManager packageManager = context.getPackageManager();
try {
PackageInfo packageInfo = packageManager.getPackageInfo("com.huangdi.pictureframework", PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
version = packageInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return version;
}
private ImageView imges;
public void loadImageByUrl(String url,ImageView imgeview){
Bitmap bitmap = mLruCache.get(Md5(url));
imges = imgeview;
if(bitmap==null){//说明lru没有
//那么得去硬盘加载如果硬盘也没有的话那就去网络请求
LoadTasks loadtask = new LoadTasks();
loadtask.execute(url) ;
tasks.add(loadtask);
}else{
if(bitmap!=null&&imgeview!=null){
Log.e("TAG","执行有");
imgeview.setImageBitmap(bitmap);
}
}
}
class LoadTasks extends AsyncTask<String,Void,Bitmap>{
private FileInputStream fileInputStream;
private FileDescriptor fieds;
private String str;
@Override
protected Bitmap doInBackground(String... params) {
String paramsms =Md5(params[0]);
str = params[0];
DiskLruCache.Snapshot snapshot;
try {
snapshot = mDisCache.get(paramsms);
if(snapshot==null){
DiskLruCache.Editor edit = mDisCache.edit(paramsms);
if(edit!=null){
//请求网络下载图片
OutputStream outputStream = edit.newOutputStream(0);
if(downImageWithUrl(params[0],outputStream)){
edit.commit();
}else{
edit.abort();
}
}
}
//下载完后在次获取图片流
snapshot = mDisCache.get(paramsms);
if(snapshot!=null){
fileInputStream = (FileInputStream) snapshot.getInputStream(0);
fieds = fileInputStream.getFD();
}
Bitmap bitmap = null;
if(fieds!=null){
//从路径中得图片
bitmap = BitmapFactory.decodeFileDescriptor(fieds);
}
//将图片保存到LruCache中
if(bitmap!=null){
if(mLruCache.get(paramsms)==null){
mLruCache.put(paramsms,bitmap);
}
}
return bitmap;
} catch (IOException e) {
e.printStackTrace();
}finally {
if(fieds !=null&&fileInputStream!=null ){
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
ImageView imageView = null;
if(mListView!=null){
imageView = (ImageView) mListView.findViewWithTag(str);
}
if(imageView!=null&&bitmap!=null){
imageView.setImageBitmap(bitmap);
}
tasks.remove(this);
}
}
//下载图片<span style="white-space:pre"> </span>
private boolean downImageWithUrl(String param, OutputStream outputStream) {
HttpURLConnection httpUrl = null;
URL url = null;
BufferedInputStream bis =null;
BufferedOutputStream bos= null;
try {
url = new URL(param);
httpUrl = (HttpURLConnection) url.openConnection();
bis = new BufferedInputStream(httpUrl.getInputStream(),10*1024);
bos = new BufferedOutputStream(outputStream,8*1024);
int b ;
while((b = bis.read())!=-1){
bos.write(b);
}
return true;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
httpUrl.disconnect();
e.printStackTrace();
}finally {
try {
if(bis!=null){
bis.close();
}
if(bos!=null){
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
private String Md5(String str){
String newsUrl;
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(str.getBytes());
newsUrl = bytesToHexString(messageDigest.digest());
} catch (NoSuchAlgorithmException e) {
newsUrl = String.valueOf(str.hashCode());
e.printStackTrace();
}
return newsUrl;
}
private String bytesToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(0xFF & bytes[i]);
if (hex.length() == 1) {
sb.append('0');
}
sb.append(hex);
}
return sb.toString();
}
}
总结:该加载框架的原理为首先我们需要从内存中加载图片,先从LruCache中拿图片如果没有那么就开启一个后台任务去下载或者从DisLruCache中下载 如果硬盘里面也没有的话那么将向网络请求。通过DiskLruCache中拿到写入流将其写入硬盘中.拿到图片后需要将其放入LruCache中.最后通过url 拿到 AbsListView中指定的ImgeView并展示图片