Android ListView&异步加载的学习(三)——AsyncTask加载图片&运用Lru算法优化图片加载
2015-08-06 20:17
489 查看
----新建showImageByAsyncTask()方法,新建一个NewsAsyncTask类继承AsyncTask类,实现类方法doInBackGround()和onPostExecue(),通过doInBackground()方法从url返回Bitmap,通过onPostExecue()方法将Bitmap传递给ImageView;在showImageByAsyncTask()方法中调用AsyncTask:
以上实现图片加载的功能。
但是发现AsyncTask和多线程存在相同的图片加载时序问题,需要进行完善:
----在NewsAsyncTask类中声明一个string类型的url来接收传进来的url,在将Bitmap传递给ImageView时进行判断,只有ImageView.getTag.equals(url)时才进行传递:
但是考虑到每次上下滑动ListView时,由于ListView的缓存特性,需要对滑出屏幕显示窗口的图片进行重新加载,这一举动会消耗掉很多流量来加载图片,同时在手机网速不好时ListView的滑动并不流畅,带来很不好的用户体验。因此需要进行进一步优化,使用缓存方法将加载过的图片进行缓存。
思想如下:
运用到Lru算法,即Least Resently Used,近期最少使用算法。
Android提供LruCache类来实现Lru算法,将内容缓存在内存中并以一定方法管理这些内容,将近期最少使用的内容从内存中剔除。
以下实现LruCache缓存:
----创建Cache:在ImageLoader中声明LruCache成员变量,LruCache<传入数据类型,传出数据类型>,此处显然传入的数据url为String类型,传出Bitmap
----初始化cache:通过写这个java文件的ImageLoader类的构造方法来初始化,需要获取最大内存,同时在每次存入缓存时调用cache的sizeOf方法告诉缓存当前存入的对象的大小:
在Adapter类中声明一个ImageLoader类对象,并在Adapter的构造方法中进行初始化:mImageLoader=new ImageLoader();
由此将图片的url传递给ImageView的方式也需要修改,在ListView缓存机制中若view存在则不需要新建一个ImageLoader类对象来加载图片,只需要调用cache中已经加载好的图片:mImageLoader.showImageByAsyncTask(viewHolder.ivIcon,mList.get(position).newsIconURL);
以上运用Cache完善了图片加载,使向下滑动初次加载完图片后再向上滑动加载图片时,不需要重新加载,只需要从cache中调用即可,节省了用户加载图片消耗的时间以及数据流量。
public void showImageByAsyncTask(ImageView imageView,String url){//调用AsyncTask new NewsAsyncTask(imageView, url).execute(url); } class NewsAsyncTask extends AsyncTask<String,Void,Bitmap>{ private ImageView mImageView; public NewsAsyncTask(ImageView imageView){ mImageView = imageView; } @Override protected Bitmap doInBackground(String... params) { return getBitmapFromURL(params[0]); } @Override protected void onPostExecute(Bitmap bitmap) {//将Bitmap传递给ImageView super.onPostExecute(bitmap); mImageView.setImageBitmap(bitmap); } }
以上实现图片加载的功能。
</pre><pre>
但是发现AsyncTask和多线程存在相同的图片加载时序问题,需要进行完善:
----在NewsAsyncTask类中声明一个string类型的url来接收传进来的url,在将Bitmap传递给ImageView时进行判断,只有ImageView.getTag.equals(url)时才进行传递:
protected void onPostExecute(Bitmap bitmap) {//将Bitmap传递给ImageView super.onPostExecute(bitmap); if (mImageView.getTag().equals(mUrl)) { mImageView.setImageBitmap(bitmap); } }以上完成图片加载的时序问题。
但是考虑到每次上下滑动ListView时,由于ListView的缓存特性,需要对滑出屏幕显示窗口的图片进行重新加载,这一举动会消耗掉很多流量来加载图片,同时在手机网速不好时ListView的滑动并不流畅,带来很不好的用户体验。因此需要进行进一步优化,使用缓存方法将加载过的图片进行缓存。
思想如下:
运用到Lru算法,即Least Resently Used,近期最少使用算法。
Android提供LruCache类来实现Lru算法,将内容缓存在内存中并以一定方法管理这些内容,将近期最少使用的内容从内存中剔除。
以下实现LruCache缓存:
----创建Cache:在ImageLoader中声明LruCache成员变量,LruCache<传入数据类型,传出数据类型>,此处显然传入的数据url为String类型,传出Bitmap
----初始化cache:通过写这个java文件的ImageLoader类的构造方法来初始化,需要获取最大内存,同时在每次存入缓存时调用cache的sizeOf方法告诉缓存当前存入的对象的大小:
public ImageLoader(){ //获取最大可用内存 int maxMemory= (int) Runtime.getRuntime().maxMemory(); int cacheSize=maxMemory/4; mCaches=new LruCache<String,Bitmap>(cacheSize){ @Override protected int sizeOf(String key, Bitmap value) { //每次存入缓存的时候调用 return value.getByteCount(); } }; }----使用cache:通过两个函数来讲图片存入缓存、从缓存中读取数据
public void addBitmapToCache(String url,Bitmap bitmap){ if (getBitmapFromCache(url)==null){//判断是否已经存入缓存 mCaches.put(url,bitmap); } } public Bitmap getBitmapFromCache(String url){ return mCaches.get(url); }修改showImageByAsyncTask方法来完善AsyncTask的调用,声明一个Bitmap变量来保存从cache中获取的数据,进行判断,若获取到的数据不存在于缓存中,则只能进行创建,否则只需要将从cache中获取的bitmap传递给imageView:
public void showImageByAsyncTask(ImageView imageView,String url){//调用AsyncTask Bitmap bitmap=getBitmapFromCache(url); if(bitmap==null) { new NewsAsyncTask(imageView, url).execute(url); }else{ imageView.setImageBitmap(bitmap); } }修改实现AsyncTask缓存机制的doInBackground方法,使从网络中下载的图片保存入cache中:
protected Bitmap doInBackground(String... params) { Bitmap bitmap=getBitmapFromUrl(params[0]); if (bitmap!=null){ addBitmapToCache(params[0],bitmap); } return bitmap; }以上实现了LruCache从创建到功能的实现,但是由于运用到了cache就不能使用原先适配器中showImageByAsyncTask()方法将url传递给ImageView,否则将会导致每次调用显示图片的方法都会创建一个cache:
在Adapter类中声明一个ImageLoader类对象,并在Adapter的构造方法中进行初始化:mImageLoader=new ImageLoader();
由此将图片的url传递给ImageView的方式也需要修改,在ListView缓存机制中若view存在则不需要新建一个ImageLoader类对象来加载图片,只需要调用cache中已经加载好的图片:mImageLoader.showImageByAsyncTask(viewHolder.ivIcon,mList.get(position).newsIconURL);
以上运用Cache完善了图片加载,使向下滑动初次加载完图片后再向上滑动加载图片时,不需要重新加载,只需要从cache中调用即可,节省了用户加载图片消耗的时间以及数据流量。
相关文章推荐
- Android Studio配置Github
- Android错误总结大全!
- android ScrollView fillViewport属性
- Android Design Support Library使用示例(一)
- Android代码内存优化建议-Java官方篇
- Android代码内存优化建议-Android官方篇
- Android代码内存优化建议-Android资源篇
- android侧滑菜单框架SlidingMenu的使用
- Android 消息推送
- Android学习路线——渐进
- Android aidl Binder框架浅析
- Android 开源框架之AndroidAnnotations快速入门
- Android studio SDK下载相应版本的Android源码
- Android系统中设置TextView的行间距
- Android ORM数据库框架对比
- Android onconfiguration属性
- Android 圆形滚动菜单
- Android中的布局优化方法
- 仿Android L 长按Home键显示最近使用应用信息及清理
- Android布局优化