android异步加载图片类

android异步加载图片类,个人使用
有需要的话拿过来修改一下就可以了
//使用方法:


/**
 * 图片异步下载完成后回调
 * @author mzh
 *
 */
public interface OnImageDownload {
	void onDownloadSucc(Bitmap bitmap,String c_url,ImageView imageView);
}


//工具类
public class Util {
	private static Util util;
	public static int flag = 0;
	private Util(){
		
	}
	
	public static Util getInstance(){
		if(util == null){
			util = new Util();
		}
		return util;
	}
	
	/**
	 * 判断是否有sdcard
	 * @return
	 */
	public boolean hasSDCard(){
		boolean b = false;
		if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
			b = true;
		}
		return b;
	}
	
	/**
	 * 得到sdcard路径
	 * @return
	 */
	public String getExtPath(){
		String path = "";
		if(hasSDCard()){
			path = Environment.getExternalStorageDirectory().getPath();
		}
		return path;
	}
	
	/**
	 * 得到/data/data/yanbin.imagedownload目录
	 * @param mActivity
	 * @return
	 */
	public String getPackagePath(Activity mActivity){
		return mActivity.getFilesDir().toString();
	}

	/**
	 * 根据url得到图片名
	 * @param url
	 * @return
	 */
	public String getImageName(String url) {
		String imageName = "";
		if(url != null){
			imageName = url.substring(url.lastIndexOf("/") + 1);
		}
		return imageName;
	}
}



/**
 * 图片异步下载类,包括图片的软应用缓存以及将图片存放到SDCard或者文件中
 * @author mzh
 *
 */
public class ImageDownloader {
	private static final String TAG = "ImageDownloader";
	private HashMap map = new HashMap();
	private Map> imageCaches = new HashMap>();
	/**
	 * 
	 * @param url 该mImageView对应的url
	 * @param mImageView
	 * @param path 文件存储路径
	 * @param mActivity
	 * @param download OnImageDownload回调接口,在onPostExecute()中被调用
	 */
	public void imageDownload(String url,ImageView mImageView,String path,Activity mActivity,OnImageDownload download){
		SoftReference currBitmap = imageCaches.get(url);
		Bitmap softRefBitmap = null;
		if(currBitmap != null){
			softRefBitmap = currBitmap.get();
		}
		String imageName = "";
		if(url != null){
			imageName = Util.getInstance().getImageName(url);
		}
		//先从软引用中拿数据
		if(currBitmap != null && mImageView != null && softRefBitmap != null && url.equals(mImageView.getTag())){
			System.out.println("从软引用中拿数据--imageName==" + imageName);
			mImageView.setImageBitmap(softRefBitmap);
		}
		else if(mImageView != null && url.equals(mImageView.getTag())){
			//软引用中没有,从文件中拿数据
			Bitmap bitmap = getBitmapFromFile(mActivity,imageName,path);
			if(bitmap != null){
				mImageView.setImageBitmap(bitmap);
				//将读取的数据放入到软引用中
				imageCaches.put(url, new SoftReference(bitmap));
			}
			//文件中也没有,此时根据mImageView的tag,即url去判断该url对应的task是否已经在执行,如果在执行,本次操作不创建新的线程,否则创建新的线程。
			else if(url != null && needCreateNewTask(mImageView)){
				MyAsyncTask task = new MyAsyncTask(url, mImageView, path,mActivity,download);
				if(mImageView != null){
					Log.i(TAG, "执行MyAsyncTask --> " + Util.flag);
					Util.flag ++;
					task.execute();
					//将对应的url对应的任务存起来
					map.put(url, task);
				}
			}
		}
	}
	
	/**
	 * 判断是否需要重新创建线程下载图片,如果需要,返回值为true。
	 * @param url
	 * @param mImageView
	 * @return
	 */
	private boolean needCreateNewTask(ImageView mImageView){
		boolean b = true;
		if(mImageView != null){
			String curr_task_url = (String)mImageView.getTag();
			if(isTasksContains(curr_task_url)){
				b = false;
			}
		}
		return b;
	}
	
	/**
	 * 检查该url(最终反映的是当前的ImageView的tag,tag会根据position的不同而不同)对应的task是否存在
	 * @param url
	 * @return
	 */
	private boolean isTasksContains(String url){
		boolean b = false;
		if(map != null && map.get(url) != null){
			b = true;
		}
		return b;
	}
	
	/**
	 * 删除map中该url的信息,这一步很重要,不然MyAsyncTask的引用会“一直”存在于map中
	 * @param url
	 */
	private void removeTaskFormMap(String url){
		if(url != null && map != null && map.get(url) != null){
			map.remove(url);
			System.out.println("当前map的大小=="+map.size());
		}
	}
	
	/**
	 * 从文件中拿图片
	 * @param mActivity 
	 * @param imageName 图片名字
	 * @param path 图片路径
	 * @return
	 */
	private Bitmap getBitmapFromFile(Activity mActivity,String imageName,String path){
		Bitmap bitmap = null;
		if(imageName != null){
			File file = null;
			String real_path = "";
			try {
				if(Util.getInstance().hasSDCard()){
					real_path = Util.getInstance().getExtPath() + (path != null && path.startsWith("/") ? path : "/" + path);
				}else{
					real_path = Util.getInstance().getPackagePath(mActivity) + (path != null && path.startsWith("/") ? path : "/" + path);
				}
				file = new File(real_path, imageName);
				if(file.exists())
				bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
			} catch (Exception e) {
				e.printStackTrace();
				bitmap = null;
			}
		}
		return bitmap;
	}
	
	/**
	 * 将下载好的图片存放到文件中
	 * @param path 图片路径
	 * @param mActivity
	 * @param imageName 图片名字
	 * @param bitmap 图片
	 * @return
	 */
	private boolean setBitmapToFile(String path,Activity mActivity,String imageName,Bitmap bitmap){
		File file = null;
		String real_path = "";
		try {
			if(Util.getInstance().hasSDCard()){
				real_path = Util.getInstance().getExtPath() + (path != null && path.startsWith("/") ? path : "/" + path);
			}else{
				real_path = Util.getInstance().getPackagePath(mActivity) + (path != null && path.startsWith("/") ? path : "/" + path);
			}
			file = new File(real_path, imageName);
			if(!file.exists()){
				File file2 = new File(real_path + "/");
				file2.mkdirs();
			}
			file.createNewFile();
			FileOutputStream fos = null;
			if(Util.getInstance().hasSDCard()){
				fos = new FileOutputStream(file);
			}else{
				fos = mActivity.openFileOutput(imageName, Context.MODE_PRIVATE);
			}
			
			if (imageName != null && (imageName.contains(".png") || imageName.contains(".PNG"))){
				bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
			}
			else{
				bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
			}
			fos.flush();
			if(fos != null){
				fos.close();
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 辅助方法,一般不调用
	 * @param path
	 * @param mActivity
	 * @param imageName
	 */
	private void removeBitmapFromFile(String path,Activity mActivity,String imageName){
		File file = null;
		String real_path = "";
		try {
			if(Util.getInstance().hasSDCard()){
				real_path = Util.getInstance().getExtPath() + (path != null && path.startsWith("/") ? path : "/" + path);
			}else{
				real_path = Util.getInstance().getPackagePath(mActivity) + (path != null && path.startsWith("/") ? path : "/" + path);
			}
			file = new File(real_path, imageName);
			if(file != null)
			file.delete();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 异步下载图片的方法
	 * @author yanbin
	 *
	 */
	private class MyAsyncTask extends AsyncTask{
		private ImageView mImageView;
		private String url;
		private OnImageDownload download;
		private String path;
		private Activity mActivity;
		
		public MyAsyncTask(String url,ImageView mImageView,String path,Activity mActivity,OnImageDownload download){
			this.mImageView = mImageView;
			this.url = url;
			this.path = path;
			this.mActivity = mActivity;
			this.download = download;
		}

		@Override
		protected Bitmap doInBackground(String... params) {
			Bitmap data = null;
			if(url != null){
				try {
					URL c_url = new URL(url);
					InputStream bitmap_data = c_url.openStream();
					data = BitmapFactory.decodeStream(bitmap_data);
					String imageName = Util.getInstance().getImageName(url);
					if(!setBitmapToFile(path,mActivity,imageName, data)){
						removeBitmapFromFile(path,mActivity,imageName);
					}
					imageCaches.put(url, new SoftReference(data.createScaledBitmap(data, 100, 100, true)));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			return data;
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}

		@Override
		protected void onPostExecute(Bitmap result) {
			//回调设置图片
			if(download != null){
				download.onDownloadSucc(result,url,mImageView);
				//该url对应的task已经下载完成,从map中将其删除
				removeTaskFormMap(url);
			}
			super.onPostExecute(result);
		}
		
	}
}
内容概要:本文档主要展示了C语言中关于字符串处理、指针操作以及动态内存分配的相关代码示例。首先介绍了如何实现键值对(“key=value”)字符串的解析,包括去除多余空格和根据键获取对应值的功能,并提供了相应的测试用例。接着演示了从给定字符串中分离出奇偶位置字符的方法,并将结果分别存储到两个不同的缓冲区中。此外,还探讨了常量(const)修饰符在变量和指针中的应用规则,解释了不同型指针的区别及其使用场景。最后,详细讲解了如何动态分配二维字符数组,并实现了对这数组的排序与释放操作。 适合人群:具有C语言基础的程序员或计算机科学相关专业的学生,尤其是那些希望深入理解字符串处理、指针操作以及动态内存管理机制的学习者。 使用场景及目标:①掌握如何高效地解析键值对字符串并去除其中的空白字符;②学会编写能够正确处理奇偶索引字符的函数;③理解const修饰符的作用范围及其对程序逻辑的影响;④熟悉动态分配二维字符数组的技术,并能对其进行有效的排序和清理。 阅读建议:由于本资源涉及较多底层概念和技术细节,建议读者先复习C语言基础知识,特别是指针和内存管理部分。在学习过程中,可以尝试动手编写似的代码片段,以便更好地理解和掌握文中所介绍的各种技巧。同时,注意观察代码注释,它们对于理解复杂逻辑非常有帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值