当前位置: 代码迷 >> Android >> Android异步加载图片并缓存到内存和SD卡下
  详细解决方案

Android异步加载图片并缓存到内存和SD卡下

热度:12   发布时间:2016-05-01 12:25:45.0
Android异步加载图片并缓存到内存和SD卡上
* 异步加载图片 * 使用方法: * private AsyncImageLoader asyImg = new AsyncImageLoader(); * asyImg.LoadImage(productItems.get(position).getPic(), (ImageView)view.findViewById(R.id.pic)); */public class AsyncImageLoader {	// 为了加快速度,在内存中开启缓存(主要应用于重复图片较多时,或者同一个图片要多次被访问,比如在ListView时来回滚动)	public Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();	private ExecutorService executorService = Executors.newFixedThreadPool(5); // 固定五个线程来执行任务	private final Handler handler = new Handler();	// SD卡上图片储存地址	private final String path = Environment.getExternalStorageDirectory()			.getPath() + "/maiduo";	/**	 * 	 * @param imageUrl	 *            图像url地址	 * @param callback	 *            回调接口	 * @return 返回内存中缓存的图像,第一次加载返回null	 */	public Drawable loadDrawable(final String imageUrl,			final ImageCallback callback) {		// 如果缓存过就从缓存中取出数据		if (imageCache.containsKey(imageUrl)) {			SoftReference<Drawable> softReference = imageCache.get(imageUrl);			if (softReference.get() != null) {				return softReference.get();			}		} else if (useTheImage(imageUrl) != null) {			return useTheImage(imageUrl);		}		// 缓存中没有图像,则从网络上取出数据,并将取出的数据缓存到内存中		executorService.submit(new Runnable() {			public void run() {				try {					final Drawable drawable = Drawable.createFromStream(							new URL(imageUrl).openStream(), "image.png");					imageCache.put(imageUrl, new SoftReference<Drawable>(							drawable));					handler.post(new Runnable() {						public void run() {							callback.imageLoaded(drawable);						}					});					saveFile(drawable, imageUrl);				} catch (Exception e) {					throw new RuntimeException(e);				}			}		});		return null;	}	// 从网络上取数据方法	public Drawable loadImageFromUrl(String imageUrl) {		try {			return Drawable.createFromStream(new URL(imageUrl).openStream(),					"image.png");		} catch (Exception e) {			throw new RuntimeException(e);		}	}	// 对外界开放的回调接口	public interface ImageCallback {		// 注意 此方法是用来设置目标对象的图像资源		public void imageLoaded(Drawable imageDrawable);	}	// 引入线程池,并引入内存缓存功能,并对外部调用封装了接口,简化调用过程	public void LoadImage(final String url, final ImageView iv) {		if (iv.getImageMatrix() == null) {			iv.setImageResource(R.drawable.loading);		}		// 如果缓存过就会从缓存中取出图像,ImageCallback接口中方法也不会被执行		Drawable cacheImage = loadDrawable(url,				new AsyncImageLoader.ImageCallback() {					// 请参见实现:如果第一次加载url时下面方法会执行					public void imageLoaded(Drawable imageDrawable) {						iv.setImageDrawable(imageDrawable);					}				});		if (cacheImage != null) {			iv.setImageDrawable(cacheImage);		}	}	/**	 * 保存图片到SD卡上	 * 	 * @param bm	 * @param fileName	 * 	 */	public void saveFile(Drawable dw, String url) {		try {			BitmapDrawable bd = (BitmapDrawable) dw;			Bitmap bm = bd.getBitmap();			// 获得文件名字			final String fileNa = url.substring(url.lastIndexOf("/") + 1,					url.length()).toLowerCase();			File file = new File(path + "/image/" + fileNa);			// 创建图片缓存文件夹			boolean sdCardExist = Environment.getExternalStorageState().equals(					android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在			if (sdCardExist) {				File maiduo = new File(path);				File ad = new File(path + "/image");				// 如果文件夹不存在				if (!maiduo.exists()) {					// 按照指定的路径创建文件夹					maiduo.mkdir();					// 如果文件夹不存在				} else if (!ad.exists()) {					// 按照指定的路径创建文件夹					ad.mkdir();				}				// 检查图片是否存在				if (!file.exists()) {					file.createNewFile();				}			}			BufferedOutputStream bos = new BufferedOutputStream(					new FileOutputStream(file));			bm.compress(Bitmap.CompressFormat.JPEG, 100, bos);			bos.flush();			bos.close();		} catch (Exception e) {			// TODO: handle exception		}	}	/**	 * 使用SD卡上的图片	 * 	 */	public Drawable useTheImage(String imageUrl) {		Bitmap bmpDefaultPic = null;		// 获得文件路径		String imageSDCardPath = path				+ "/image/"				+ imageUrl.substring(imageUrl.lastIndexOf("/") + 1,						imageUrl.length()).toLowerCase();		File file = new File(imageSDCardPath);		// 检查图片是否存在		if (!file.exists()) {			return null;		}		bmpDefaultPic = BitmapFactory.decodeFile(imageSDCardPath, null);		if (bmpDefaultPic != null || bmpDefaultPic.toString().length() > 3) {			Drawable drawable = new BitmapDrawable(bmpDefaultPic);			return drawable;		} else			return null;	}}


  相关解决方案