android加载图片,需要优化的地方,1.使用软引用,2.缓存到本地3.查看是否图片是否过期,这个就涉及到数据库了,下面把主要代码贴出来。
public class ImageUtil {
private static final String TAG = "ImageUtil";
private static int DayCount = 15;// 天数
private static final long CLEARTIME = DayCount * 24 * 60 * 60 * 1000;
/**
* 默认图片
*/
private final static int Default_Img = R.drawable.bg_load_default;
private static Object lock = new Object();
/**
* 内存图片软引用缓冲
*/
private static LinkedHashMap<String, SoftReference> imageCache = new LinkedHashMap<String, SoftReference>(
20);
/**
* 入口
*
* @param imageUrl
* @param iv_item_image
* @param context
* @param callback
* @param b
*/
public static void setThumbnailView(String imageUrl,
ImageView iv_item_image, Context context, ImageCallback callback,
boolean b) {
DBHelper dbHelper = DBHelper.getInstance(context);
String md5 = ImageUtil.md5(imageUrl);
// 缓存目录
if (!CommonUtil.sdCardIsAvailable())/* true 为可用 */{
String cachePath = context.getCacheDir().getAbsolutePath() + "/" + md5; // data里的缓存
setThumbnailImage(iv_item_image, imageUrl, cachePath, dbHelper,
callback, b);
iv_item_image.setTag(cachePath);
} else {
String imagePath = getExternalCacheDir(context) + File.separator + md5; // sd卡
setThumbnailImage(iv_item_image, imageUrl, imagePath, dbHelper,
callback, b);
iv_item_image.setTag(imagePath);
}
}
/**
* 获得程序在sd开上的cahce目录
*
* @param context
* The context to use
* @return The external cache dir
*/
@SuppressLint("NewApi")
public static String getExternalCacheDir(Context context) {
// android 2.2 以后才支持的特性
if (hasExternalCacheDir()) {
return context.getExternalCacheDir().getPath() + File.separator
+ "img";
}
// Before Froyo we need to construct the external cache dir ourselves
// 2.2以前我们需要自己构造
final String cacheDir = "/Android/data/" + context.getPackageName()
+ "/cache/img/";
return Environment.getExternalStorageDirectory().getPath() + cacheDir;
}
public static boolean hasExternalCacheDir() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO;
}
/**
* 设置图片函数
*
* @param view
* @param imageUrl
* @param cachePath
* @param callback
* @param b
*/
private static void setThumbnailImage(ImageView view, String imageUrl,
String cachePath, DBHelper dbHelper, ImageCallback callback,
boolean b) {
Bitmap bitmap = null;
bitmap = ImageUtil.loadThumbnailImage(cachePath, imageUrl, dbHelper,
callback, b);
if (bitmap == null) {// 先查找数据库,再查找本地sd卡,若没有.再从网站加载,若网站上没有图片或错误时返回null
// 设置默认图片
view.setImageResource(Default_Img);
} else {
// 设置本地SD卡缓存图片
view.setImageBitmap(bitmap);
}
}
private static Bitmap getImageFromDB(String imagePath, String imageUrl,
DBHelper dbHelper) {
Cursor cursor = queryFromDbByImgUrl(dbHelper, imageUrl);
if (cursor.moveToFirst()) {
long currTimestamp = (new Date()).getTime();
long timestamp = cursor.getLong(cursor
.getColumnIndex(ImageCacheColumn.TIMESTAMP));
long spanTime = currTimestamp - timestamp;
int Past_time = cursor.getInt(cursor
.getColumnIndex(ImageCacheColumn.PAST_TIME));
if (spanTime > Past_time * 24 * 60 * 60 * 1000) {
// 过期
// 删除本地文件
deleteImageFromLocal(imagePath);
return null;
} else {
// 没过期
return getImageFromLocal(imagePath);
}
} else {
return null;
}
}
private static Cursor queryFromDbByImgUrl(DBHelper dbHelper, String imageUrl) {
// return dbHelper.query(ImageCacheColumn.TABLE_NAME, null,
// ImageCacheColumn.Url + "=?", new String[] { imageUrl });
return dbHelper.rawQuery("select * from " + ImageCacheColumn.TABLE_NAME
+ " where " + ImageCacheColumn.Url + "='" + imageUrl + "'",
null);
}
/**
* 保存图片到SD卡
*
* @param imagePath
* @param buffer
* @throws IOException
*/
public static void saveImage(String imagePath, byte[] buffer)
throws IOException {
File f = new File(imagePath);
if (f.exists()) {
return;
} else {
File parentFile = f.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
f.createNewFile();
FileOutputStream fos = new FileOutputStream(imagePath);
fos.write(buffer);
fos.flush();
fos.close();
}
}
/**
* 保存图片到缓存
*
* @param imagePath
* @param bm
*/
public static void saveImage(String imagePath, Bitmap bm) {
if (bm == null || imagePath == null || "".equals(imagePath)) {
return;
}
File f = new File(imagePath);
if (f.exists()) {
return;
} else {
try {
File parentFile = f.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
f.createNewFile();
FileOutputStream fos;
fos = new FileOutputStream(f);
bm.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
} catch (FileNotFoundException e) {
f.delete();
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
f.delete();
}
}
}
private static void saveImageByDb(String imageUrl, DBHelper dbHelper) {
String sql = null;
if (queryFromDbByImgUrl(dbHelper, imageUrl).moveToFirst()) {
sql = "update " + ImageCacheColumn.TABLE_NAME + " set "
+ ImageCacheColumn.TIMESTAMP + "='"
+ (new Date().getTime()) + "' where "
+ ImageCacheColumn.Url + "='" + imageUrl + "'";
} else {
sql = "insert into " + ImageCacheColumn.TABLE_NAME + "("
+ ImageCacheColumn.Url + "," + ImageCacheColumn.TIMESTAMP
+ "," + ImageCacheColumn.PAST_TIME + ") values('"
+ imageUrl + "'," + (new Date().getTime()) + "," + DayCount
+ ")";
}
dbHelper.ExecSQL(sql);
}
/**
* 从SD卡加载图片
*
* @param imagePath
* @return
*/
public static Bitmap getImageFromLocal(String imagePath) {
File file = new File(imagePath);
if (file.exists()) {
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
file.setLastModified(System.currentTimeMillis());
return bitmap;
}
return null;
}
/**
* 从本地文件中删除文件
*
* @param imagePath
*/
private static void deleteImageFromLocal(String imagePath) {
File file = new File(imagePath);
if (file.exists()) {
file.delete();
}
}
/**
* 从本地或者服务端异步加载缩略图图片
*
* @return
* @param imagePath
* 本地缓存路径
* @param imgUrl
* 拼接后的请求路径
* @param callback
* 得到数据后的处理方法回调
* @throws IOException
*/
public static Bitmap loadThumbnailImage(final String imagePath,
final String imgUrl, final DBHelper dbHelper,
final ImageCallback callback, final boolean b) {
// 在软链接缓存中,则返回Bitmap对象
if (imageCache.containsKey(imgUrl)) {
SoftReference reference = imageCache.get(imgUrl);
Bitmap bitmap = (Bitmap) reference.get();
if (bitmap != null) {
return bitmap;
}
}
// 若软链接缓存没有
Bitmap bitmap = null;
// 查询数据库 返回bitmap
bitmap = getImageFromDB(imagePath, imgUrl, dbHelper);// 从本地加载
if (bitmap != null) {
return bitmap;
} else {
// 从网上加载
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.obj != null) {
Bitmap bitmap = (Bitmap) msg.obj;
callback.loadImage(bitmap, imagePath);
}
}
};
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
URL url = new URL(imgUrl);
URLConnection conn = url.openConnection();
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.connect();
InputStream in = conn.getInputStream();
BitmapFactory.Options options = new Options();
options.inSampleSize = 1;
Bitmap bitmap = BitmapFactory.decodeStream(in,
new Rect(0, 0, 0, 0), options);
imageCache.put(imgUrl, new SoftReference(bitmap));
Message msg = handler.obtainMessage();
msg.obj = bitmap;
handler.sendMessage(msg);
if (bitmap != null) {
// 保存文件到sd卡
saveImage(imagePath, bitmap);
// 保存到数据库
saveImageByDb(imgUrl, dbHelper);
}
} catch (MalformedURLException e) {
e.printStackTrace();
Log.e(ImageUtil.class.getName(), "图片url不存在");
} catch (IOException e) {
e.printStackTrace();
}
}
};
ThreadPoolManager.getInstance().addTask(runnable);
}
return null;
}
/**
* MD5
*
* @param paramString
* @return
*/
private static String md5(String paramString) {
return MD5.encode(paramString);
}
// ///////////////////////////////////////////////////////////////////////
// 公共方法
public interface ImageCallback {
public void loadImage(Bitmap bitmap, String imagePath);
}
/**
* 每次打开含有大量图片的activity时,开一个新线程,检查并清理缓存
*
* @param context
*/
public static void checkCache(final Context context) {
new Thread() {
public void run() {
int state = 0;// 记录清除结果 0为都没清除, 1为只清除了sd卡, 2为只清除了rom Cache ,3
// 为都清除了
String cacheS = "0M";
String cacheD = "0M";
File sdCache = new File(getExternalCacheDir(context)); // sd卡"mnt/sdcard/android/data/cn.eoe.app/cache/";
File cacheDir = context.getCacheDir(); // 手机data/data/com.mengniu.app/cache
try {
if (sdCache != null && sdCache.exists()) {
long sdFileSize = getFileSize(sdCache);
if (sdFileSize > 1024 * 1024 * 50) {
// SD需要清理
long clearFileSize = clear(sdCache);
state += 1;
cacheS = clearFileSize + "";
}
}
if (cacheDir != null && cacheDir.exists()) {
long cacheFileSize = getFileSize(cacheDir);
if (cacheFileSize > 1024 * 1024 * 50) {
// ROM需要清理
long clearFileSize = clear(cacheDir);
state += 2;
cacheD = clearFileSize + "";
}
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
/**
* 清除路径
*
* @param cacheDir
* @return
*/
public static long clear(File cacheDir) {
long clearFileSize = 0;
File[] files = cacheDir.listFiles();
if (files == null)
return 0;
for (File f : files) {
if (f.isFile()) {
if (System.currentTimeMillis() - f.lastModified() > CLEARTIME) {
long fileSize = f.length();
if (f.delete()) {
clearFileSize += fileSize;
}
}
} else {
clear(f);
}
}
return clearFileSize;
}
/**
* 取得文件大小
*
* @param f
* @return
* @throws Exception
*/
public static long getFileSize(File f) throws Exception {
long size = 0;
File flist[] = f.listFiles();
for (int i = 0; i < flist.length; i++) {
if (flist[i].isDirectory()) {
size = size + getFileSize(flist[i]);
} else {
size = size + flist[i].length();
}
}
return size;
}
/**
* 转换文件大小
*
* @param fileS
* @return
*/
public static String FormetFileSize(long fileS) {
DecimalFormat df = new DecimalFormat("#.00");
String fileSizeString = "";
if (fileS < 1024) {
fileSizeString = df.format((double) fileS) + "B";
} else if (fileS < 1048576) {
fileSizeString = df.format((double) fileS / 1024) + "K";
} else if (fileS < 1073741824) {
fileSizeString = df.format((double) fileS / 1048576) + "M";
} else {
fileSizeString = df.format((double) fileS / 1073741824) + "G";
}
return fileSizeString;
}
}