Google I/O 2013: Volley加载图片添加缓存处理

嵌入式技术

1368人已加入

描述

Google I/O 2013已经结束,它让我们对Android将来的发展有了更大的期待。今年I/O大会上展示的令人激动的创新之一是名为Volley库。Volley是一个处理并缓存网络请求的库,它把开发者从不同的应用中编写相同代码的泥潭中拯救出来。编写相同代码从来都不是有趣的,还会增加开发者的错误几率。正式考虑了这一点,Google创造了Volley。

如果你没有看 Google I/O 上介绍Volley的视频,我建议你先去看一下,在对它有了基本了解后再继续后面的文章。

通过Google I/O介绍,Ficus Kirpatrick谈论了许多Volley如何有助于加载图片的内容。当使用Volley作为你的图片加载解决方案时,你会发现,尽管它自己处理L2缓存,它请求但不包含一个内存不足的L1图片缓存。很多人已经使用过例如Universal Image Loader或Square’s newer Picasso library来处理图片缓存;然而,这些库通常只处理图片的加载和缓存。那么,我们如何使用Volley替代它们来加载和缓存图片呢?首先,让我们看看Volley提供的加载功能,缓存功能稍后再讲。

ImageLoader

ImageLoader类需要一个请求的实例以及一个ImageCache类的实现。图片通过传递一个URL和一个ImageListener实例到get()方法进行加载。从那里,ImageLoader检查ImageCache,如果图像不是在缓存中,就从网络中加载图片。

NetworkImageView

这个类代替布局中的ImageViews类而且使用ImageLoader类。NetworkImageView类的setUrl()方法需要一个URL路径字符串和一个ImageLoader实例。然后,它使用ImageLoder的get()方法来取回图片数据。

Java

1

2

3

4

5

6

7

8

android:id="@+id/twitterUserImage"

android:layout_alignParentLeft="true"

android:layout_alignParentTop="true"

android:layout_width="40dp"

android:layout_height="40dp"

android:padding="5dp"

/>

ImageCache

Volley库的ImageCache接口允许你使用你喜好的L1缓存实现。不幸的是,Volley的缺点之一,没有默认的缓存实现。I/O大会上演示了一个BitmapLruCache的代码片段,但库本身没有包含任何实现。

ImageCache接口有两个方法,getBitmap(String url)和putBitmap(String url, Bitmap bitmap)。这些桩是非常简单的,它们可以添加到任何缓存实现里。

填补空白:向Volley增加一个图片缓存

例如,我已经创建了一个简单的应用,该应用通过Twitter搜索”CapTech”,并在一个列表视图中显示搜索到的结果,每一列包含用户名和图片。当向下滑动时,这个列表会自动加载旧的记录,还会从缓存中获取图片。

Google

CapTech

有两种可用的缓存实现。推荐的方法是在内存中使用一个基础的LRU缓存。对于硬盘的缓存实现,我选择使用Jack Wharton编写的DiskLruCache。我选择这个实现是因为它在Android社区中被频繁的使用,并且有人提供了一个改造自己的应用来适配Volley的用例。使用一个基于磁盘的L1缓存可能导致阻塞I/O问题。Volley已经有一个隐式的硬盘L2缓存。硬盘L1缓存已经被包含在内了,因为我最初并没有察觉Volley如果处理图片请求缓存。

以下是这个实现的主要组件:

RequestManager

RequestManager维护我们的RequestQueue的一个引用。Volley使用ResuestQueue来处理我们对Twitter数据和图片加载的请求。

GsonRequest

GsonRequest与图片加载没有直接联系,但它代表了如何扩展Volley请求类来处理JSON解析。该类用于对Twitter的GET请求和TwitterData对象的结果。

BitmapLruImageCache

该类是一个基本的“最近最少使用(LRU)”内存缓存实现。它速度快但不会阻塞I/O。这是推荐的方法。

DiskLruImageCache

DiskLruImageCache是一个位图版本的DiskLruCache封装。它从DiskLruCache中增加并检索位图,还处理缓存的实例化。硬盘缓存可能阻塞I/O。

ImageCacheManager

ImageCacheManager持有ImageCache和Volley ImageLoader引用。

在ImageCacheManager中,你可能注意到一点就是我们使用URL字符串的hashCode()作为缓存的键值。这是由于URL中的某些字符不能作为缓存的键值。

BuzzArrayAdapter

该适配器比较简单的。这里只需要注意一点,我们要实现Volley的Listener和ErrorListener接口,并且把该适配器作为Listener参数传递给了NetworkImageView 的 setUrl(String string , Listener listener, ErrorListener errorListener) 方法。这个适配器包含了一些额外代码用于滚动时加载旧的tweets。

Java

1

2

3

4

5

6

7

8

Tweet tweet = mData.get(position);

if(tweet != null){

viewHolder.twitterUserImage.setImageUrl(tweet.getUserImageUrl(), ImageCacheManager.getInstance().getImageLoader());

viewHolder.userNameTextView.setText("@" + tweet.getUsername());

viewHolder.messageTextView.setText(tweet.getMessage());

viewHolder.tweetTimeTextView.setText(formatDisplayDate(tweet.getCreatedDate()));

viewHolder.destinationUrl = tweet.getDestinationUrl();

}

信息汇总

有了所有这些部分,图像加载和缓存现在变得非常简单。启动时,应用程序在MainApplication类中初始化RequestManager和ImageCacheManager类。这里你可以声明你期望的L1缓存类型。默认实现是内存缓存。

在MainActivity中,我们首次调用TwitterManager并加载初始数据。一旦我们接收到返回数据,我们将它传递给BuzzArrayAdapter,并且把BuzzArrayAdapter设置到ListView中。

在以上的BuzzArrayAdapter代码中,NetworkImageView承担了所有繁重的图片加载操作,我们只需要将从ImageCacheManager得到的实例传达给图片加载器就可以了。

ImageCacheManager检查我们的LRU缓存实现,并返回可用的图片。如果图片不在缓存中,它就会到网络中获取。

当你滚动ListView时,BuzzArrayAdapter会加载更多的tweets和相应的图片,并重用已经在缓存中的图片。

结束时的思考

尽管Volley是用处大、速度快、容易实现;但现在还不是使用它的时候,原因如下:

这个库缺少任何说明文档和使用用例。

例如缓存配置组件,还不具有我期望的高可配置性。

如上所见,排除基本图片缓存实现看起来很奇怪。可能包含一个NoImageCache实现也许更加有用,或者使缓存变得可配置以满足只从网络上获取所有信息的需求。

在开发者社区有很多与Volley而令人激动的消息。给人的感觉是这个库应当已经被作为Android API,并且被引入了很长时间了。就像在I/O大会上宣布的新的Location API 那样。很显然,Google正在致力于通过移除一些对app开发的阻碍,从而使得开发者的生活变得更加轻松。



 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分