android之图片异步加载

最近给一同学整网络图片异步加载的问题,于是拿出了以前做的项目异步加载图片的代码块,最后还是发现之前的代码还是存在很多问题,在之前的代码块中使用的是HashMap<String,Sofeware<Drawable>>这样的键值对还存放缓存下载过的图片的,但最终实现的效果不是很理想。所以就采用了使用file和sdcard个人开辟图片缓存文件的方式来存放图片。具体流程如下

android之图片异步加载_第1张图片
但对于网络图片,我们都知道手机的内存比较小,对于加载一些网络大图是,我们需要对它进行一些图片,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;
	}

}



     

你可能感兴趣的:(android之图片异步加载)