zoukankan      html  css  js  c++  java
  • 自己动手写android图片异步载入库

    尊重他人劳动成果,转载请说明出处:http://blog.csdn.net/bingospunky/article/details/44344085

    接触android有半年了。关于图片异步载入。一直仅仅用别人的框架,尽管特别方便,可是始终未见识到图片异步载入的庐山真面目。

    近期比較悠闲,研究一些高大上的东西。在这篇文章总结一下我对图片异步载入的一些学习心得。

    图片载入最重要的无非就是内存和线程。

    大家都知道关于内存溢出一般的解决方式就是LruCache,在我的这个demo里我仅仅要使用SoftReference实现了一个缓存类,SoftReference已经被遗弃了,这里仅仅为学习。

    代码

    com.example.qtdemo_oom.Cache<T, U>

    /**
     * 由SoftReference实现的内存缓存<br>
     * 此类仅供学习,因为Android 2.3開始,垃圾回收器倾向于回收软引用和弱引用对象。
     * @author qingtian 
     */
    public class Cache<T,U> {
    
    	private Hashtable<T, NewSoftReference> hashTable;// 用于Chche内容的存储
    	private ReferenceQueue<U> q;// 垃圾Reference的队列
    
    	/**
    	 * 继承SoftReference,使得每个实例都具有可识别的标识。

    */ private class NewSoftReference extends SoftReference<U> { public T key; public NewSoftReference(U em, ReferenceQueue<U> q) { super(em, q); } } /** * 构建一个缓存器实例 */ public Cache() { hashTable = new Hashtable<T, NewSoftReference>(); q = new ReferenceQueue<U>(); } /** * 保存一个实例 * @param t * @param u */ public void put(T t, U u) { cleanCache();// 清除垃圾引用 NewSoftReference ref = new NewSoftReference(u, q); ref.key = t; hashTable.put(t, ref); } /** * 通过uri获取实例 * @param t * @return */ public U get(T t) { U bm = null; if (hashTable.containsKey(t)) { NewSoftReference ref = (NewSoftReference) hashTable.get(t); bm = (U) ref.get(); } return bm; } /** * 在hashTable里里清除已经被回收了的对象的软引用对象 */ @SuppressWarnings("unchecked") private void cleanCache() { NewSoftReference ref = null; while ((ref = (NewSoftReference) q.poll()) != null) { hashTable.remove(ref.key); } } /** * 清除Cache内的所有内容 */ public void clearCache() { cleanCache(); hashTable.clear(); System.gc(); System.runFinalization(); } }


    com.example.qtdemo_oom.ImageLoader

    /**
     * 图片载入工具类
     * @author qingtian
     */
    public class ImageLoader {
    	
    	private static final String TAG = "qingtian" ;
    
    	//线程池
    	ExecutorService threadPool ;
    	//自己实现的缓存类
    	Cache<String, Bitmap> cache;
    	//也能够用v4包提供的缓存
    //	LruCache<String, Bitmap> cache;
    	
    	public ImageLoader() {
    		threadPool = new ThreadPoolExecutor(2, 2, 0, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
    		cache = new Cache<String, Bitmap>();
    //		int maxMemory = (int) Runtime.getRuntime().maxMemory();
    //		cache = new LruCache<String, Bitmap>(maxMemory/8){
    //			// 測量Bitmap的大小
    //			@Override
    //			protected int sizeOf(String key, Bitmap value) {
    //				return value.getRowBytes() * value.getHeight();
    //			}
    //		};
    	}
    
    	private int currentThreadNum = 0;
    	
    	class DownBitmapRunnable implements Runnable{
    		ImageView iv;  String uri;
    		public DownBitmapRunnable( ImageView iv,  String uri) {
    			this.iv = iv;
    			this.uri = uri;
    		}
    		@Override
    		public void run() {
    
    			currentThreadNum++;
    			
    			show();
    
    			Bitmap bm = cache.get(uri);
    			if (bm == null) {
    				Log.i(TAG, "下载");
    				bm = BitmapUtil.getImageBitmap(uri);
    			}else{
    				Log.i(TAG, "不下载");
    			}
    			if (bm != null) {
    				cache.put(uri, bm);
    				final Bitmap fBitmap = bm;
    				new Handler(Looper.getMainLooper()).post(new Runnable() {
    
    					@Override
    					public void run() {
    						iv.setImageBitmap(fBitmap);
    					}
    
    				});
    			}
    
    			currentThreadNum--;
    		}
    		
    	}
    
    	public void show( ImageView iv,  String uri) {
    
    		threadPool.execute(new DownBitmapRunnable(iv, uri));
    
    	}
    
    	public void show() {
    		Log.i(TAG, "currentThreadNum:" + currentThreadNum );
    	}
    }
    
    在这个类里。使用线程池管理线程。避免创建/取消线程时内存的浪费。第14行代码也提供了LruCache代码,我们也能够用LruCache来实现缓存。

    代码第54--61行,对于view的操作已经在主线程里了。

    com.example.qtdemo_oom.Adapter

    public class Adapter extends BaseAdapter {
    	public static final String[] uris = new String[] {
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img1b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img2b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img3b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img4b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img5b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img6b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img7b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img8b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img9b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img10b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img11b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img12b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img13b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img14b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img15b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img16b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img17b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img18b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img19b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img20b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img21b.jpg",
    			"http://mabinbin.com:8080/AndroidAsyncHttpService/image/img22b.jpg" };
    
    	public LayoutInflater mInflater;
    	public ImageLoader loader;
    
    	public Adapter(Context context) {
    		mInflater = LayoutInflater.from(context);
    		loader = new ImageLoader();
    	}
    
    	@Override
    	public int getCount() {
    		return uris.length;
    	}
    
    	@Override
    	public Object getItem(int arg0) {
    		return uris[arg0];
    	}
    
    	@Override
    	public long getItemId(int position) {
    		return position;
    	}
    
    	@Override
    	public View getView(int position, View convertView, ViewGroup parent) {
    
    		ViewHolder holder = null;
    		if (convertView == null) {
    			convertView = mInflater.inflate(R.layout.item, null);
    
    			holder = new ViewHolder();
    			holder.tv = (TextView) convertView.findViewById(R.id.tv);
    			holder.iv = (ImageView) convertView.findViewById(R.id.iv);
    			convertView.setTag(holder);
    		} else {
    			holder = (ViewHolder) convertView.getTag();
    		}
    
    		holder.tv.setText((String) getItem(position));
    
    		loader.show(holder.iv, uris[position]);
    
    		return convertView;
    	}
    
    	class ViewHolder {
    		TextView tv;
    		ImageView iv;
    	}
    
    }

    代码第66行,就能够异步载入图片了。


    com.example.qtdemo_oom.util.BitmapUtil

    public class BitmapUtil {
    	
    	public static Bitmap getImageBitmap(String uri) {
    		URL imgUrl = null;
    		Bitmap bitmap = null;
    		InputStream is = null;
    		try {
    			imgUrl = new URL(uri);
    			HttpURLConnection conn = (HttpURLConnection) imgUrl
    					.openConnection();
    			conn.setDoInput(true);
    			conn.connect();
    			is = conn.getInputStream();
    			bitmap = BitmapFactory.decodeStream(is);
    		} catch (MalformedURLException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			if (is != null) {
    				try {
    					is.close();
    					is = null;
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    		return bitmap;
    	}
    	
    }
    通过这个简单的demo,我见到了内存缓存的真面目。也学习了LruCache的源代码(这里没体现)。

    当然这是我学习异步图片载入的第一版,希望在后面的版本号里写的更成熟。

    源代码下载

  • 相关阅读:
    note:debugging requires the debug connect session system privilege
    jdk8 tomcat7
    idea git 整合使用
    connect: Address is invalid on local machine or port is not valid on remote
    mysql拒绝访问 Error 1044/1045 问题的解决
    mysql Error_code: 1593
    spring mvc 提交表单汉字乱码
    mysql 5.7.10 下互为主备配置
    Java开发笔记(七十四)内存溢出的两种错误
    Java开发笔记(七十三)常见的程序异常
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6767236.html
Copyright © 2011-2022 走看看