带图片的ListView(GridView)的图片异步加载、OOM处理以及图片和数据缓存策略的研究

如今,很多APP中都有带图片的ListView或GridView,如新浪微博、微信等,今天就研究下相关的技术实现。

若是第一次进入到某个界面,由于该界面的数据和图片还没有任何缓存,对于主界面,在进入主界面之前一般都会有一个引导界面,该界面一般会停留几秒钟(需要设置一个超时时间如8s,超过该时间不管数据请求是否成功都要跳到主界面中),这时可以在子线程中向服务器请求json数据(也可能是xml数据,本文假设是json格式),请求成功后将数据写到一个List<Bean>中(该Bean一般保存ListView每一个item的相关数据),同时将该json数据保存在本地,然后跳转到主界面;对于非主界面,在进入前一般会显示“加载中…”字样的旋转的圆形Progressbar,同时在子线程中请求服务器数据,若请求成功则将List<Bean>传递给ListView的Adapter,同时也要将该json数据保存在本地,若请求失败则提示“点击重新加载”。

当List<Bean>成功传递给ListView的Adapter,在Adapter的getView()方法中,对于普通数据则直接将Bean中的内容赋值给相关的TextView,普通数据的加载也就完成了;而对于图片,先判断内存缓存LruCache中是否有图片,有的话赋给ImageView,若没有则先将res/drawable文件夹中保存的默认图片赋给ImageView。

对于图片,还需要在ListView未滚动时或者第一次进来时(onScroll()方法、onScrollStateChanged()方法)先判断内存缓存LruCache中是否有图片,有的话则直接赋给ImageView,若没有则需判断本地缓存中是否有图片(可使用自己实现的文件保存方案或用开源的DiskLruCache方案,保存在本地缓存中的图片以图片URL的MD5值来命名),有的话直接赋给ImageView同时保存在内存缓存LruCache中,没有的话则用AsyncTask在后台异步请求图片URL,请求成功后先将图片缩小(使用BitmapFactory.Options以及inJustDecodeBounds = true,用来处理图片的OOM),并将缩小的bitmap图片赋给ImageView,同时将其保存在内存缓存和本地缓存中。

若不是第一次进入到某个界面,由于第一次已经保存了服务器的json数据,首先将该json数据读取到List<Bean>中,同样在Adapter的getView()方法中,对于普通数据直接将Bean中的内容赋值给相关的TextView,普通数据的加载则完成。而对于图片,先判断内存缓存LruCache中是否有图片,有的话赋给ImageView,若没有则先将res/drawable中保存的默认图片赋给ImageView。而对于图片,在ListView未滚动时或者第一次进来时(onScroll()方法、onScrollStateChanged()方法),先判断内存缓存LruCache中是否有图片,有的话则直接赋给ImageView,若没有则先判断本地缓存中是否有图片,而这时本地缓存中是有图片的,则可赋给ImageView。与此同时,客户端需要在子线程中请求服务器,看服务器端是否有新的数据。若没有新的数据,则无需进行更新。若有新的数据,则首先需将该新的json数据更新到本地,同时将新的json数据读取到List<Bean>中并重新设置Adapter,此时ListView的item中的普通数据会进行更新。对于图片,若图片的URL未改变则还是加载内存缓存LruCache和本地缓存中的图片;若图片的URL改变了说明图片有更新,则先使用AsyncTask在后台异步请求图片新的URL,若请求成功则先将图片缩小(使用BitmapFactory.Options以及inJustDecodeBounds = true,用来处理图片的OOM),并将缩小的bitmap图片赋给ImageView,同时更新内存缓存LruCache和本地缓存中的相关图片。

你可能感兴趣的:(android,ListView,oom,缓存机制,网络异步加载)