最近给一同学整网络图片异步加载的问题,于是拿出了以前做的项目异步加载图片的代码块,最后还是发现之前的代码还是存在很多问题,在之前的代码块中使用的是HashMap<String,Sofeware<Drawable>>这样的键值对还存放缓存下载过的图片的,但最终实现的效果不是很理想。所以就采用了使用file和sdcard个人开辟图片缓存文件的方式来存放图片。具体流程如下
但对于网络图片,我们都知道手机的内存比较小,对于加载一些网络大图是,我们需要对它进行一些图片,android中自带了一个对图片处理的类对象BItmapFactory.Options 它可以让我们的网络图片是否要读入当前手机内存,当我们无限立即获得图片是,而是单单想知道该图的宽高之类的我们 可以直接进行如下操作
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeStream(Inputsrean,null,opts);
int width = opts.outwidth;
int heigth = opts.outheight;
这样便获得了原图的高宽 并且不占内存。对于这些只是一点介绍
但在处理网络大图是我们是要对其进行压缩的,代码如下:
package com.ht.ce.asyncimage;
import java.io.IOException;
import java.io.InputStream;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.test.IsolatedContext;
import android.util.Log;
/**
*
*
* @author Administrator
*
*/
public class ReleaseResource {
//图片的压缩处理
public static Drawable getDrawableFromNet(InputStream instream) {
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm;
opts.inJustDecodeBounds = false;
opts.inSampleSize = 4; //缩放比例
bm = BitmapFactory.decodeStream(instream, null, opts);
Bitmap mBitmap = bm;
try {
instream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("<<<<<<>>>>>>=>"+opts.outWidth);
return new BitmapDrawable(mBitmap);
}
}
下面便是对于图片的下载存放和判断的代码块
package com.ht.ce.weidongTest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.ht.ce.asyncimage.ReleaseResource;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
/**
* 图片异步加载
*
* @author Administrator
*
*/
public class AsyncImageLoaderForPics {
private Handler hander = new Handler();
private ExecutorService executorService = Executors.newFixedThreadPool(5);
public AsyncImageLoaderForPics() {
}
public Drawable loadDrawable(final String imageurl,
final ImageCallback callback) {
if (PicIsContanted(imageurl)) {
// Log.d("is start clean!", IsStarClean(filesize)+"");
return getDrawableFromFile(weidongMain.instance, imageurl);
} else {
executorService.submit(new Runnable() {
public void run() {
// TODO Auto-generated method stub
try {
final Drawable drawable = ReleaseResource
.getDrawableFromNet(GetInternetData
.getInputStream(imageurl));
try {
if (drawable != null) {
//是否存在sdCard
if (!getSDCardState(weidongMain.instance)) {
//是否该清除缓存
if (IsStarClean(weidongMain.instance,filesize)){
CleanCache(weidongMain.instance);
}
FileSavePic(weidongMain.instance,
imageurl, drawable);
}else {
//是否该清除缓存
if (IsStarClean(weidongMain.instance,filesize)){
CleanCache(weidongMain.instance);
}
SDCardSavePic(imageurl, drawable);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
hander.post(new Runnable() {
public void run() {
// TODO Auto-generated method stub
callback.imageLoaded(drawable);
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
return null;
}
public interface ImageCallback {
public void imageLoaded(Drawable imageDrawable);
}
// ===============================================================
// 图片处理----------------------------
// 《-----把bitmap转换为byte[]----》
private byte[] getBitmapbyte(Bitmap bitmap) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
try {
out.flush();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return out.toByteArray();
}
// 将byte转换为inputsream
private InputStream getInputStream(byte[] bitmapforbyte) {
ByteArrayInputStream is = new ByteArrayInputStream(bitmapforbyte);
return is;
}
// 将drawable转换为bitmap
private Bitmap getBitmap(Drawable drawable) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, drawable
.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, width, height);
drawable.draw(canvas);
return bitmap;
}
// Bitmap格式转换为Inputstream
public InputStream BitmapForInputstream(Drawable drawable)
throws IOException {
InputStream is = getInputStream(getBitmapbyte(getBitmap(drawable)));
return is;
}
// File 存储文件
public void FileSavePic(Context context, String url, Drawable drawable)
throws Exception {
File file = context.getFilesDir();
String filename = file.getPath();
String path = filename + "/" + getfilePath(url)[path_len - 1];
File f = new File(path);
f.createNewFile();
FileOutputStream out = new FileOutputStream(f);
out.write(getBitmapbyte(getBitmap(drawable)));
out.flush();
out.close();
}
// 获得文件
public String[] GetFileList(Context context) {
File file = context.getFilesDir();
String[] names = file.list();
return names;
}
// 对图片url进行处理
private int path_len;
private String[] getfilePath(String url) {
String[] array = url.split("/");
path_len = array.length;
return array;
}
// 判断是否存在图片
String[] AllFile = null;
private boolean PicIsContanted(String url) {
if(getSDCardState(weidongMain.instance)){
try {
AllFile = getfilesformSDCard(weidongMain.instance);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else
AllFile = GetFileList(weidongMain.instance);
String name = getfilePath(url)[path_len - 1];
List<String> array = Arrays.asList(AllFile);
if (array.contains(name))
return true;
else
return false;
}
// 从file里获得以前存储的图片
private Drawable getDrawableFromFile(Context context, String path) {
File file = null;
if(getSDCardState(weidongMain.instance)){
File sdcardDir = Environment.getExternalStorageDirectory();
try {
file= new File(sdcardDir.getCanonicalPath() + CACHE_dir);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else
file = context.getFilesDir();
String filename = file.getPath();
String name = filename + "/" + getfilePath(path)[path_len - 1];
Bitmap bmp = BitmapFactory.decodeFile(name);
return new BitmapDrawable(bmp);
}
// 对缓存大小的判断
private static float filesize;
private static long sum = 0;
public static void getFilesSize(Context context) throws IOException{
File FatherFile = null;
if(!getSDCardState(context))
FatherFile = context.getFilesDir();
else{
System.out.println("=w=w=d=");
File sdcardDir = Environment.getExternalStorageDirectory();
FatherFile = new File(sdcardDir.getCanonicalPath() + CACHE_dir);
}
if(FatherFile!=null){
String[] names = FatherFile.list();
if(names!=null){
int len = names.length;
for (int index = 0; index < len; index++) {
File file = new File(names[index]);
try {
FileInputStream is = new FileInputStream(FatherFile.getPath()
+ "/" + file);
sum += (is.available()) / (1024);
is.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
}
}
filesize = sum / 1024;
}
}
}
// 判断是否该清除内存了 大于1.5M进行清除
private boolean IsStarClean(Context context,float size) {
try {
getFilesSize(context);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (size >= 1.5)
return true;
else
return false;
}
//对缓存图片的判断
public static void CleanCache(Context context) throws IOException{
long nowtime = System.currentTimeMillis();
File FatherFile = null;
//FatherFile = context.getFilesDir();
if(!getSDCardState(context))
FatherFile = context.getFilesDir();
else{
File sdcardDir = Environment.getExternalStorageDirectory();
FatherFile = new File(sdcardDir.getCanonicalPath() + CACHE_dir);
}
String[] names = FatherFile.list();
int len = names.length;
String nametemp;
for (int index = 0; index < len; index++) {
for (int index_j = index + 1; index < len; index_j++) {
File file1 = new File(names[index]);
File file2 = new File(names[index_j]);
long value_1 = nowtime - file1.lastModified();
long value_2 = nowtime - file2.lastModified();
if (value_2 > value_1) {
nametemp = names[index_j];
names[index_j] = names[index];
names[index] = nametemp;
}
}
}
// 删除 当缓存内存大小达到3m,那么将删掉内存区域的1/3的文件
for (int index = 0; index <= len / 3; index++) {
File file = new File(names[index]);
file.delete();
}
}
// =================SD卡的操作===========================
private static String CACHE_dir = "/CEPIC";
// 判断是否存在sd卡
private static boolean getSDCardState(Context context) {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
return true;
} else
return false;
}
// 在sdcard里存放图片
private void SDCardSavePic(String imgUrl, Drawable drawable)
throws IOException {
File cachefile = null;
File sdcardDir = Environment.getExternalStorageDirectory();
String name = getfilePath(imgUrl)[path_len - 1];
File dir = new File(sdcardDir.getCanonicalPath() +"/"+ CACHE_dir);
if (!dir.exists()) {
dir.mkdirs();
}
cachefile = new File(dir, name);
FileOutputStream out = new FileOutputStream(cachefile);
out.write(getBitmapbyte(getBitmap(drawable)));
out.flush();
out.close();
}
//获得sdcard下的文件列表
private String[] getfilesformSDCard(Context context) throws IOException{
File sdcardDir = Environment.getExternalStorageDirectory();
File dir = new File(sdcardDir.getCanonicalPath() + CACHE_dir);
Log.d("Path","/"+dir.getPath());
File[] files = dir.listFiles();
String[] names = new String[files.length];
int index = 0;
for(File file : files){
names[index] = file.getName();
index++;
}
return names;
}
}