一、前言:
之前写过一个简单的网络图片读取工具,读取网络图片,在Android应用中经常可见,在ListView、GridView这些控件中尤其可见。而为了提高用户体验,这些控件图片的读取,一般都是采用异步加载的方式,而使用缓存则是必不可少的环节。 现在网络上已经出现了很多功能丰富、使用简单的图片下载框架,例如universalimageloader,使用只需要初始化并且传入参数即可。这里我打算自己实现一个功能简单的图片下载工具类,采取了内存缓存+磁盘缓存+网络获取的三级缓存方式。
二、思路:
三级缓存,在网上查阅过很多资料,个人所知,有两种实现方式:
1、软引用+SD卡缓存+网络获取
2、Lrucache+DiskLruCache+网络获取
因为从 android 2.3 (API Level 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用和弱引用变得不再可靠。所以本文的思路是:先从内存缓存中寻找需要的图片,如果内存中不存在该图片,再从磁盘缓存中查找,如果再查找为空,则开启网络获取。
三、相关技术:
这里主要使用第二种方式实现:
1、关于Lrucache:
Lrucache是Android自带的一个内存缓存类,专门用来做图片缓存处理的。它有一个特点,当缓存的图片达到了预先设定的值的时候,那么近期使用次数最少的图片就会被回收掉。
详细使用方法请自行百度。
2、关于DiskLruCache:
DiskLruCache是一个非Google官方编写,但获得官方认证的缓存类。它的作用是把图片(或者其他对象)保存到本地磁盘中,以便下次需要的时候,直接获取。
DiskLruCache并没有限制数据的缓存位置,可以自由地进行设定,但是通常情况下多数应用程序都会将缓存的位置选择为 /sdcard/Android/data/<application package>/cache 这个路径。选择在这个位置有两点好处:第一,这是存储在SD卡上的,因此即使缓存再多的数据也不会对手机的内置存储空间有任何影响,只要SD卡空间足够就行。第二,这个路径被Android系统认定为应用程序的缓存路径,当程序被卸载的时候,这里的数据也会一起被清除掉,这样就不会出现删除程序之后手机上还有很多残留数据的问题。
由于DiskLruCache并不是由Google官方编写的,所以这个类并没有被包含在Android API当中,我们需要将这个类从网上下载下来,然后手动添加到项目当中。DiskLruCache的源码在Google Source上,地址:android.googlesource.com/platform/libcore/+/jb-mr2-release/luni/src/main/java/libcore/io/DiskLruCache.java。
详细使用方法自行百度。
四、ImageLoad实现类:
- package com.zero.imageload;
- 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 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.URL;
- import java.security.MessageDigest;
- import java.security.NoSuchAlgorithmException;
- import java.util.HashSet;
- import java.util.Set;
- /**
- * @author Zero
- * @version 1.0
- * @date 2015/7/29
- */
- public class ImageLoad {
- private static ImageLoad mImageLoad = null;
- private static String CacheName = “image”; //图片缓存文件名
- /**
- * 获取唯一实例
- * @return
- */
- public static ImageLoad getInstance(Context context) {
- if (mImageLoad == null) {
- mImageLoad = new ImageLoad(context.getApplicationContext());
- }
- return mImageLoad;
- }
- /**
- * ImageLoad停止所有的任务
- * 通常在退出活动时,用于取消下载任务
- */
- public void ImageLoadCancel(){
- cancelAllTasks();
- }
- /**
- * ImageLoad输出到日志
- * 通常到活动暂停时,用于刷新cache
- */
- public void ImageLoadPause(){
- fluchCache();
- }
- /**
- * ImageLoad获取磁盘缓存的大小
- */
- public long ImageLoadCacheSize(){
- return mDiskLruCache.size();
- }
- /**
- * ImageLoad清理内存缓存
- */
- public void ImageLoadCacheClean(){
- //清理内存缓存
- clearCache();
- }
- /**
- * ImageLoad磁盘缓存清理
- */
- public void ImageLoadDiskCacheClean(){
- try {
- mDiskLruCache.delete();
- } catch (IOException e) {
- e.printStackTrace();
- }
- System.gc();
- }
- /**
- * ImageLoad清理所有的数据
- */
- public void ImageLoadCacheAllClean(){
- //清理内存缓存
- clearCache();
- //清理磁盘缓存
- try {
- mDiskLruCache.delete();
- } catch (IOException e) {
- e.printStackTrace();
- }
- System.gc();
- }
- /**
- * 加载Bitmap对象。此方法会在LruCache中检查所有屏幕中可见的ImageView的Bitmap对象,
- * 如果发现任何一个ImageView的Bitmap对象不在缓存中,就会开启异步线程去下载图片。
- * @param imageUrl
- * @param bitmapListener
- */
- public void loadBitmap(String imageUrl,BitmapListener bitmapListener) {
- //开启一个新的异步任务
- BitmapWorkerTask task = new BitmapWorkerTask(bitmapListener);
- //把任务加进任务集合
- taskCollection.add(task);
- //任务开始
- task.execute(imageUrl);
- }
- /**
- * 加载Bitmap对象
- * @param imageUrl
- * @param width
- * @param height
- * @param bitmapListener
- */
- public void loadBitmap(String imageUrl,int width,int height,BitmapListener bitmapListener){
- }
- /**
- * 加载Bitmap对象,由于图片占用内存过大,在这里直接跳过内存缓存,存到磁盘缓存
- * @param imageUrl
- * @param bitmapListener
- */
- public void loadBigBitmap(String imageUrl,BitmapListener bitmapListener){
- }
- /**
- * 记录所有正在下载或等待下载的任务。
- */
- private Set<BitmapWorkerTask> taskCollection;
- /**
- * 为每个任务定义一个接口
- */
- public interface BitmapListener{
- public void onFailure();
- public void onSuccess(Bitmap bitmap);
- }
- /**
- * 异步下载图片的任务。
- *
- * @author zero
- */
- class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
- /**
- * 图片的URL地址
- */
- private String imageUrl;
- /**
- * 绑定监听器
- */
- private BitmapListener mBitmapListener;
- /**
- * 构造方法
- * @param bitmapListener
- */
- public BitmapWorkerTask(BitmapListener bitmapListener){
- this.mBitmapListener = bitmapListener;
- }
- /**
- * 异步类执行
- * @param params
- * @return
- */
- @Override
- protected Bitmap doInBackground(String… params) {
- //获取URL
- imageUrl = params[0];
- Bitmap bitmap;
- //先从缓存中获取
- bitmap = mMemoryCache.get(imageUrl);
- if(bitmap != null)
- return bitmap;
- //再从磁盘缓存中获取
- FileDescriptor fileDescriptor = null;
- FileInputStream fileInputStream = null;
- DiskLruCache.Snapshot snapShot = null;
- try {
- // 生成图片URL对应的key
- final String key = hashKeyForDisk(imageUrl);
- // 查找key对应的缓存
- snapShot = mDiskLruCache.get(key);
- if (snapShot == null) {
- // 如果没有找到对应的缓存,则准备从网络上请求数据,并写入缓存
- DiskLruCache.Editor editor = mDiskLruCache.edit(key);
- if (editor != null) {
- OutputStream outputStream = editor.newOutputStream(0);
- if (downloadUrlToStream(imageUrl, outputStream)) {
- editor.commit();
- } else {
- editor.abort();
- }
- }
- // 缓存被写入后,再次查找key对应的缓存
- snapShot = mDiskLruCache.get(key);
- }
- if (snapShot != null) {
- fileInputStream = (FileInputStream) snapShot.getInputStream(0);
- fileDescriptor = fileInputStream.getFD();
- }
- if (fileDescriptor != null) {
- bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
- }
- if (bitmap != null) {
- // 将Bitmap对象添加到内存缓存当中
- addBitmapToMemoryCache(params[0], bitmap);
- }
- return bitmap;
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- if (fileDescriptor == null && fileInputStream != null) {
- try {
- fileInputStream.close();
- } catch (IOException e) {
- }
- }
- }
- return null;
- }
- /**
- * 异步类执行返回
- * @param bitmap
- */
- @Override
- protected void onPostExecute(Bitmap bitmap) {
- super.onPostExecute(bitmap);
- if(bitmap == null)
- mBitmapListener.onFailure();
- else mBitmapListener.onSuccess(bitmap);
- //移除任务
- taskCollection.remove(this);
- }
- }
- /**
- * 取消所有正在下载或等待下载的任务。
- */
- public void cancelAllTasks() {
- if (taskCollection != null) {
- for (BitmapWorkerTask task : taskCollection) {
- task.cancel(false);
- }
- }
- }
- /**
- * 构造方法,由于是单例,因此构造方法为私有
- */
- private ImageLoad(Context context) {
- // 初始化任务列表
- taskCollection = new HashSet<BitmapWorkerTask>();
- // 初始化内存缓存类
- // 获取应用程序最大可用内存
- int maxMemory = (int) Runtime.getRuntime().maxMemory();
- int cacheSize = maxMemory / 8;
- // 设置图片缓存大小为程序最大可用内存的1/8
- mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
- @Override
- protected int sizeOf(String key, Bitmap bitmap) {
- return bitmap.getByteCount();
- }
- };
- // 初始化磁盘缓存类
- try {
- // 获取图片缓存路径
- File cacheDir = getDiskCacheDir(context, CacheName);
- if (!cacheDir.exists()) {
- cacheDir.mkdirs();
- }
- // 创建DiskLruCache实例,初始化缓存数据
- mDiskLruCache = DiskLruCache.open(cacheDir, getAppVersion(context), 1, 10 * 1024 * 1024);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /**
- * 图片缓存技术的核心类,用于缓存所有下载好的图片,在程序内存达到设定值时会将最少最近使用的图片移除掉。
- */
- private LruCache<String, Bitmap> mMemoryCache;
- /**
- * 将一张图片存储到LruCache中。
- *
- * @param key LruCache的键,这里传入图片的URL地址。
- * @param bitmap LruCache的键,这里传入从网络上下载的Bitmap对象。
- */
- public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
- if (getBitmapFromMemoryCache(key) == null) {
- mMemoryCache.put(key, bitmap);
- }
- }
- /**
- * 从LruCache中获取一张图片,如果不存在就返回null。
- *
- * @param key LruCache的键,这里传入图片的URL地址。
- * @return 对应传入键的Bitmap对象,或者null。
- */
- public Bitmap getBitmapFromMemoryCache(String key) {
- return mMemoryCache.get(key);
- }
- /**
- * 删除bitmap
- *
- * @param key
- */
- public void deleteBitmapFromMemoryCache(String key) {
- mMemoryCache.remove(key);
- }
- /**
- * 清空内存缓存
- *
- * @return void
- */
- public void clearCache() {
- if (mMemoryCache != null) {
- if (mMemoryCache.size() > 0) {
- Log.d(”CacheUtils”, “mMemoryCache.size() ” + mMemoryCache.size());
- mMemoryCache.evictAll();
- Log.d(”CacheUtils”, “mMemoryCache.size()” + mMemoryCache.size());
- }
- // 初始化内存缓存类
- // 获取应用程序最大可用内存
- int maxMemory = (int) Runtime.getRuntime().maxMemory();
- int cacheSize = maxMemory / 8;
- // 设置图片缓存大小为程序最大可用内存的1/8
- mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
- @Override
- protected int sizeOf(String key, Bitmap bitmap) {
- return bitmap.getByteCount();
- }
- };
- }
- }
- /**
- * 图片硬盘缓存核心类, 用于缓存所有下载好的图片到本地
- */
- private DiskLruCache mDiskLruCache;
- /**
- * 获取当前应用程序的版本号。
- */
- public int getAppVersion(Context context) {
- try {
- PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
- return info.versionCode;
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return 1;
- }
- /**
- * 根据传入的uniqueName获取硬盘缓存的路径地址。
- */
- public File getDiskCacheDir(Context context, String uniqueName) {
- String cachePath;
- if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) {
- cachePath = context.getExternalCacheDir().getPath();
- } else {
- cachePath = context.getCacheDir().getPath();
- }
- return new File(cachePath + File.separator + uniqueName);
- }
- /**
- * 使用MD5算法对传入的key进行加密并返回。
- */
- public String hashKeyForDisk(String key) {
- String cacheKey;
- try {
- final MessageDigest mDigest = MessageDigest.getInstance(“MD5”);
- mDigest.update(key.getBytes());
- cacheKey = bytesToHexString(mDigest.digest());
- } catch (NoSuchAlgorithmException e) {
- cacheKey = String.valueOf(key.hashCode());
- }
- return cacheKey;
- }
- 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();
- }
- /**
- * 将缓存记录同步到journal文件中。
- */
- public void fluchCache() {
- if (mDiskLruCache != null) {
- try {
- mDiskLruCache.flush();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * 建立HTTP请求,并获取Bitmap对象。
- *
- * @param urlString 图片的URL地址
- * @return 解析后的Bitmap对象
- */
- private boolean downloadUrlToStream(String urlString, OutputStream outputStream) {
- HttpURLConnection urlConnection = null;
- BufferedOutputStream out = null;
- BufferedInputStream in = null;
- try {
- final URL url = new URL(urlString);
- urlConnection = (HttpURLConnection) url.openConnection();
- in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);
- out = new BufferedOutputStream(outputStream, 8 * 1024);
- int b;
- while ((b = in.read()) != -1) {
- out.write(b);
- }
- return true;
- } catch (final IOException e) {
- e.printStackTrace();
- } finally {
- if (urlConnection != null) {
- urlConnection.disconnect();
- }
- try {
- if (out != null) {
- out.close();
- }
- if (in != null) {
- in.close();
- }
- } catch (final IOException e) {
- e.printStackTrace();
- }
- }
- return false;
- }
- }
package com.zero.imageload;
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 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.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashSet;
import java.util.Set;
/**
* @author Zero
* @version 1.0
* @date 2015/7/29
*/
public class ImageLoad {
private static ImageLoad mImageLoad = null;
private static String CacheName = "image"; //图片缓存文件名
/**
* 获取唯一实例
* @return
*/
public static ImageLoad getInstance(Context context) {
if (mImageLoad == null) {
mImageLoad = new ImageLoad(context.getApplicationContext());
}
return mImageLoad;
}
/**
* ImageLoad停止所有的任务
* 通常在退出活动时,用于取消下载任务
*/
public void ImageLoadCancel(){
cancelAllTasks();
}
/**
* ImageLoad输出到日志
* 通常到活动暂停时,用于刷新cache
*/
public void ImageLoadPause(){
fluchCache();
}
/**
* ImageLoad获取磁盘缓存的大小
*/
public long ImageLoadCacheSize(){
return mDiskLruCache.size();
}
/**
* ImageLoad清理内存缓存
*/
public void ImageLoadCacheClean(){
//清理内存缓存
clearCache();
}
/**
* ImageLoad磁盘缓存清理
*/
public void ImageLoadDiskCacheClean(){
try {
mDiskLruCache.delete();
} catch (IOException e) {
e.printStackTrace();
}
System.gc();
}
/**
* ImageLoad清理所有的数据
*/
public void ImageLoadCacheAllClean(){
//清理内存缓存
clearCache();
//清理磁盘缓存
try {
mDiskLruCache.delete();
} catch (IOException e) {
e.printStackTrace();
}
System.gc();
}
/**
* 加载Bitmap对象。此方法会在LruCache中检查所有屏幕中可见的ImageView的Bitmap对象,
* 如果发现任何一个ImageView的Bitmap对象不在缓存中,就会开启异步线程去下载图片。
* @param imageUrl
* @param bitmapListener
*/
public void loadBitmap(String imageUrl,BitmapListener bitmapListener) {
//开启一个新的异步任务
BitmapWorkerTask task = new BitmapWorkerTask(bitmapListener);
//把任务加进任务集合
taskCollection.add(task);
//任务开始
task.execute(imageUrl);
}
/**
* 加载Bitmap对象
* @param imageUrl
* @param width
* @param height
* @param bitmapListener
*/
public void loadBitmap(String imageUrl,int width,int height,BitmapListener bitmapListener){
}
/**
* 加载Bitmap对象,由于图片占用内存过大,在这里直接跳过内存缓存,存到磁盘缓存
* @param imageUrl
* @param bitmapListener
*/
public void loadBigBitmap(String imageUrl,BitmapListener bitmapListener){
}
/**
* 记录所有正在下载或等待下载的任务。
*/
private Set<BitmapWorkerTask> taskCollection;
/**
* 为每个任务定义一个接口
*/
public interface BitmapListener{
public void onFailure();
public void onSuccess(Bitmap bitmap);
}
/**
* 异步下载图片的任务。
*
* @author zero
*/
class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
/**
* 图片的URL地址
*/
private String imageUrl;
/**
* 绑定监听器
*/
private BitmapListener mBitmapListener;
/**
* 构造方法
* @param bitmapListener
*/
public BitmapWorkerTask(BitmapListener bitmapListener){
this.mBitmapListener = bitmapListener;
}
/**
* 异步类执行
* @param params
* @return
*/
@Override
protected Bitmap doInBackground(String... params) {
//获取URL
imageUrl = params[0];
Bitmap bitmap;
//先从缓存中获取
bitmap = mMemoryCache.get(imageUrl);
if(bitmap != null)
return bitmap;
//再从磁盘缓存中获取
FileDescriptor fileDescriptor = null;
FileInputStream fileInputStream = null;
DiskLruCache.Snapshot snapShot = null;
try {
// 生成图片URL对应的key
final String key = hashKeyForDisk(imageUrl);
// 查找key对应的缓存
snapShot = mDiskLruCache.get(key);
if (snapShot == null) {
// 如果没有找到对应的缓存,则准备从网络上请求数据,并写入缓存
DiskLruCache.Editor editor = mDiskLruCache.edit(key);
if (editor != null) {
OutputStream outputStream = editor.newOutputStream(0);
if (downloadUrlToStream(imageUrl, outputStream)) {
editor.commit();
} else {
editor.abort();
}
}
// 缓存被写入后,再次查找key对应的缓存
snapShot = mDiskLruCache.get(key);
}
if (snapShot != null) {
fileInputStream = (FileInputStream) snapShot.getInputStream(0);
fileDescriptor = fileInputStream.getFD();
}
if (fileDescriptor != null) {
bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
}
if (bitmap != null) {
// 将Bitmap对象添加到内存缓存当中
addBitmapToMemoryCache(params[0], bitmap);
}
return bitmap;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileDescriptor == null && fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
}
}
}
return null;
}
/**
* 异步类执行返回
* @param bitmap
*/
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if(bitmap == null)
mBitmapListener.onFailure();
else mBitmapListener.onSuccess(bitmap);
//移除任务
taskCollection.remove(this);
}
}
/**
* 取消所有正在下载或等待下载的任务。
*/
public void cancelAllTasks() {
if (taskCollection != null) {
for (BitmapWorkerTask task : taskCollection) {
task.cancel(false);
}
}
}
/**
* 构造方法,由于是单例,因此构造方法为私有
*/
private ImageLoad(Context context) {
// 初始化任务列表
taskCollection = new HashSet<BitmapWorkerTask>();
// 初始化内存缓存类
// 获取应用程序最大可用内存
int maxMemory = (int) Runtime.getRuntime().maxMemory();
int cacheSize = maxMemory / 8;
// 设置图片缓存大小为程序最大可用内存的1/8
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getByteCount();
}
};
// 初始化磁盘缓存类
try {
// 获取图片缓存路径
File cacheDir = getDiskCacheDir(context, CacheName);
if (!cacheDir.exists()) {
cacheDir.mkdirs();
}
// 创建DiskLruCache实例,初始化缓存数据
mDiskLruCache = DiskLruCache.open(cacheDir, getAppVersion(context), 1, 10 * 1024 * 1024);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 图片缓存技术的核心类,用于缓存所有下载好的图片,在程序内存达到设定值时会将最少最近使用的图片移除掉。
*/
private LruCache<String, Bitmap> mMemoryCache;
/**
* 将一张图片存储到LruCache中。
*
* @param key LruCache的键,这里传入图片的URL地址。
* @param bitmap LruCache的键,这里传入从网络上下载的Bitmap对象。
*/
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemoryCache(key) == null) {
mMemoryCache.put(key, bitmap);
}
}
/**
* 从LruCache中获取一张图片,如果不存在就返回null。
*
* @param key LruCache的键,这里传入图片的URL地址。
* @return 对应传入键的Bitmap对象,或者null。
*/
public Bitmap getBitmapFromMemoryCache(String key) {
return mMemoryCache.get(key);
}
/**
* 删除bitmap
*
* @param key
*/
public void deleteBitmapFromMemoryCache(String key) {
mMemoryCache.remove(key);
}
/**
* 清空内存缓存
*
* @return void
*/
public void clearCache() {
if (mMemoryCache != null) {
if (mMemoryCache.size() > 0) {
Log.d("CacheUtils", "mMemoryCache.size() " + mMemoryCache.size());
mMemoryCache.evictAll();
Log.d("CacheUtils", "mMemoryCache.size()" + mMemoryCache.size());
}
// 初始化内存缓存类
// 获取应用程序最大可用内存
int maxMemory = (int) Runtime.getRuntime().maxMemory();
int cacheSize = maxMemory / 8;
// 设置图片缓存大小为程序最大可用内存的1/8
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getByteCount();
}
};
}
}
/**
* 图片硬盘缓存核心类, 用于缓存所有下载好的图片到本地
*/
private DiskLruCache mDiskLruCache;
/**
* 获取当前应用程序的版本号。
*/
public int getAppVersion(Context context) {
try {
PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
return info.versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return 1;
}
/**
* 根据传入的uniqueName获取硬盘缓存的路径地址。
*/
public File getDiskCacheDir(Context context, String uniqueName) {
String cachePath;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) {
cachePath = context.getExternalCacheDir().getPath();
} else {
cachePath = context.getCacheDir().getPath();
}
return new File(cachePath + File.separator + uniqueName);
}
/**
* 使用MD5算法对传入的key进行加密并返回。
*/
public String hashKeyForDisk(String key) {
String cacheKey;
try {
final MessageDigest mDigest = MessageDigest.getInstance("MD5");
mDigest.update(key.getBytes());
cacheKey = bytesToHexString(mDigest.digest());
} catch (NoSuchAlgorithmException e) {
cacheKey = String.valueOf(key.hashCode());
}
return cacheKey;
}
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();
}
/**
* 将缓存记录同步到journal文件中。
*/
public void fluchCache() {
if (mDiskLruCache != null) {
try {
mDiskLruCache.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 建立HTTP请求,并获取Bitmap对象。
*
* @param urlString 图片的URL地址
* @return 解析后的Bitmap对象
*/
private boolean downloadUrlToStream(String urlString, OutputStream outputStream) {
HttpURLConnection urlConnection = null;
BufferedOutputStream out = null;
BufferedInputStream in = null;
try {
final URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);
out = new BufferedOutputStream(outputStream, 8 * 1024);
int b;
while ((b = in.read()) != -1) {
out.write(b);
}
return true;
} catch (final IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (final IOException e) {
e.printStackTrace();
}
}
return false;
}
}
五、使用方法:- ImageLoad.getInstance(context).loadBitmap(imageurl, new BitmapListener() {
- @Override
- public void onSuccess(Bitmap bitmap) {
- // TODO 自动生成的方法存根
- ImageView image = (ImageView) v.findViewById(R.id.image);
- image.setImageBitmap(bitmap);
- }
- @Override
- public void onFailure() {
- // TODO 自动生成的方法存根
- }
- });
ImageLoad.getInstance(context).loadBitmap(imageurl, new BitmapListener() {
@Override
public void onSuccess(Bitmap bitmap) {
// TODO 自动生成的方法存根
ImageView image = (ImageView) v.findViewById(R.id.image);
image.setImageBitmap(bitmap);
}
@Override
public void onFailure() {
// TODO 自动生成的方法存根
}
});
六、不足之处
这个工具类目前只提供了一个图片下载方法,而且尚未做一些防止OOM发生的操作,尚有很多提高的地方,希望大家给些意见,大家一起互相交流,请狠狠得拍我。 - - 哈哈。
转载自: http://blog.csdn.net/z82367825/article/details/46509235