关于android图片墙的学习

本文详细介绍了如何使用Android中的AsyncTask结合线程池来优化图片加载速度,并利用LruCache进行内存管理,有效避免内存溢出问题。同时,文章还讨论了软引用和弱引用的不稳定性及其对应用的影响。
public class Main extends Activity {
    
	/*LruCache,它的主要算法原理是把最近使用的对象用强引用存储在 LinkedHashMap 中,
	 * 并且把最近最少使用的对象在缓存值达到预设定值之前从内存中移除。
	 * 在过去,我们经常会使用一种非常流行的内存缓存技术的实现,即软引用或弱引用 (SoftReference or WeakReference)。
	 * 但是现在已经不再推荐使用这种方式了,因为从 Android 2.3 (API Level 9)开始,
	 * 垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用和弱引用变得不再可靠。
	 * 另外,Android 3.0 (API Level 11)中,图片的数据会存储在本地的内存当中,因而无法用一种可预见的方式将其释放,
	 * 这就有潜在的风险造成应用程序的内存溢出并崩溃。*/
	
	private GridView gridView;
	private String[] urls;
	private WallAdapter wallAdapter;
	private ExecutorService pool = Executors.newFixedThreadPool(5);//创建线程池开启10条
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		gridView=(GridView)this.findViewById(R.id.gridview);
		urls=ImagesUtil.imageThumbUrls;
		wallAdapter=new WallAdapter(Main.this, urls, gridView);
		gridView.setAdapter(wallAdapter);
	}
	
	public class WallAdapter extends BaseAdapter implements OnScrollListener{
		private LruCache<String, Bitmap> lruCache;//键String:代表图片的url,值Bitmap:存放的图片
		private Context context;
		private String[] urls;
		private boolean isFirstIn=true;//是否第一次进入
		private GridView gridView;
		private Set<BitmapWorkTask> tasks;//存储正在下载和等待下载的任务
		private int firstVisiableItemId;//可见区域的第一张图片的id
		private int visiableCount;//可见区域的图片张数和
		
        
		public WallAdapter(Context context,String[] urls,GridView gridView){
			this.context=context;
		    this.urls=urls;
		    this.gridView=gridView;
		    tasks=new HashSet<BitmapWorkTask>();
		    int maxMemorry=(int)Runtime.getRuntime().maxMemory();
		    int size=maxMemorry/8;//最大内存的八分之一
		    lruCache=new LruCache<String, Bitmap>(size){

				@Override
				protected int sizeOf(String key, Bitmap value) {
					Log.i("------------->", value.getByteCount()+"");
					return value.getByteCount();
				}
		    	
		    };
		    gridView.setOnScrollListener(this);
		    Log.i("------------>", "baseAdapter我在执行");
		}
		
		@Override
		public int getCount() {
			
			return urls.length;
		}

		@Override
		public Object getItem(int position) {
			
			return urls[position];
		}

		@Override
		public long getItemId(int position) {
			
			return position;
		}

		@Override
		public View getView(int position, View view, ViewGroup parent) {
			if (view==null) 
				view=LayoutInflater.from(context).inflate(R.layout.gridview_item, null);
				ImageView imageView=(ImageView)view.findViewById(R.id.imageview);
				//给imageview做标记,避免异步加载图片乱序
			    imageView.setTag(urls[position]);
			    //图片的显示
			    setImageView(urls[position], imageView);
			return view;
		}

		//监听GridView的状态,第一次进来的时候,不会调用
		@Override
		public void onScrollStateChanged(AbsListView view, int scrollState) {
			//处于停止状态才下载,滚动式停止下载
			if (scrollState==SCROLL_STATE_IDLE) {
				 loadBitmap(firstVisiableItemId, visiableCount);
			}else {
				if (tasks!=null) {
					taskCancel();//取消下载任务
				}
			}
		}

		//第一次进入,不会调用onScrollStateChanged方法
		@Override
		public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {
			Log.i("------------------>", "Onscroll在执行");
			Log.i("可见项的总数", visibleItemCount+"");
			this.firstVisiableItemId=firstVisibleItem;
			this.visiableCount=visibleItemCount;
				if (isFirstIn && visibleItemCount>0) {
					loadBitmap(firstVisibleItem, visibleItemCount);
					isFirstIn=false;
				}
			
		}
		
		/**取消下载任务*/
		private void taskCancel(){
			for (BitmapWorkTask task : tasks) {
			      task.cancel(false);
			}
		}
		
		/**图片的下载任务,只加载可见项*/
		private void loadBitmap( int firstVisiableItemId,int visiableCount){
			
			for (int i = firstVisiableItemId; i < firstVisiableItemId+visiableCount; i++) {
				  String imageurl=urls[i];
				  Bitmap bitmap=getBitmapFromLruCache(imageurl);
				  if (bitmap==null) {
					  BitmapWorkTask task=new BitmapWorkTask();
					  tasks.add(task);//将下载的任务保存至集合中,便于控制
//					  task.execute(imageurl);
					  task.executeOnExecutor(pool, imageurl);//结合线程池,提高加载速度
				}else {
					ImageView imageView=(ImageView)gridView.findViewWithTag(imageurl);
					if (imageView!=null && bitmap!=null) {
						 imageView.setImageBitmap(bitmap);
					}
				}
			}
		}
		
		/**异步类执行图片加载任务*/
		private class BitmapWorkTask extends AsyncTask<String, Void, Bitmap>{
	        String imageurl;
			@Override
			protected Bitmap doInBackground(String... params) {
				imageurl=params[0];
				Bitmap tempBitmap=downloadBitmap(imageurl);
				if (tempBitmap!=null) {
					addBitmapToLruCache(imageurl, tempBitmap);//下载后保存至缓存
				}
				return tempBitmap;
			}
			
			@Override
			protected void onPostExecute(Bitmap bitmap) {
				ImageView imageView=(ImageView)gridView.findViewWithTag(imageurl);//通过Tag找到对应的ImageView控件
				if (imageView!=null && bitmap!=null) {
					imageView.setImageBitmap(bitmap);
				}
				tasks.remove(this);//下载完后移除当前对象
			}
		}
		
		/**下载图片方法,返回Bitmap对象*/
		private Bitmap downloadBitmap(String imageUrl){
		  try {
			URL url=new URL(imageUrl);
			try {
				HttpURLConnection conn=(HttpURLConnection)url.openConnection();
				conn.setRequestMethod("GET");
				conn.setReadTimeout(5*1000);
				conn.setDoInput(true);
				conn.setDoOutput(true);
				InputStream inputStream=conn.getInputStream();
				Bitmap bitmap=BitmapFactory.decodeStream(inputStream);
				return bitmap;
			} catch (IOException e) {
				e.printStackTrace();
				System.out.println("图片加载失败");
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
			System.out.println("图片资源路径不存在");
		}
		  return null;
			
		}
		/**图片的显示*/
		private void setImageView(String imageUrl,ImageView imageView){
			Bitmap bitmap=getBitmapFromLruCache(imageUrl);
			if (bitmap!=null) {
				imageView.setImageBitmap(bitmap);
			}else {
				imageView.setImageResource(R.drawable.defualt);//默认图片
			}
		}
		
		/** 图片添加到LruCache中*/
		private void addBitmapToLruCache(String key,Bitmap bitmap){
			if (getBitmapFromLruCache(key)==null) {
				lruCache.put(key, bitmap);
			}
		}
		
		/**据图片key值(url)获得Bitmap对象*/
		private Bitmap getBitmapFromLruCache(String key){
			return lruCache.get(key);
		}
		
	}
	
   //退出结束所有下载任务
	@Override
	protected void onDestroy() {
		super.onDestroy();
		wallAdapter.taskCancel();
	}
}
以上是在看别人的博文所写的,但有所改进,AyncTask结合线程池运用加快加载速度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值