貌似有2个月没写博客了,原因还跟以往一样,忙+懒,其实二者是相辅相成的,忙的时候要想抽点时间也还是有的,但一忙就懒得管工作以外的事情了,一来二去也就会拖延很久。最近把公司项目中的图片加载框架由Universal-Image-Loader换成了Fresco,感觉有必要做个记录。
一个内容充实的应用,图片是必不可少的。而图片往往体积比较大,从服务器下载图片那肯定是要用异步线程来做的,在UI主线程中尽量不做任何耗时操作是每个Android开发者应该遵循的准则。你可以自己来写如何加载图片,但多数开发者的能力可能不足以完成一个足够好的图片加载框架,好在网上资源丰富,已经有好几个开源的图片加载框架供我们选择,它们都能比较好的满足我们的需求,可以让开发者不用太专注于图片的处理。比较有名的有Universal-Image-Loader、Picasso、Volley,以及今天的主角——Fresco。
要说,我们项目中原来Universal-Image-Loader用的也好好的,没什么问题,但有更好的技术还是要及时跟进的。Fresco是Facebook发布的一款开源框架,号称是目前最强的Android图片加载库,在内存方面的表现极为优秀,既然有如此信心,那么至少我应该先尝试一下,若真的好用,就替换掉UIL了。
对于Fresco的一些介绍,就不多说了,如果你感兴趣肯定会到网上找一些相关的资料,建议你到官网查看:http://frescolib.org/。当然了,国内的大神也对这个网站进行了翻译,如果你英语水平比较捉急,请到http://fresco-cn.org/来进行观摩,不过还是建议到官网,因为你不知道什么时候会有更新,第三方的文档会不及时。
下面直接来一段代码吧,看过就知道Fresco用起来是多么简单了:
记住,要想在项目中引入Fresco,只需要在Module的build.gradle文件的dependencies中添加一句话:
|
compile
'com.facebook.fresco:fresco:0.7.0+'
|
至于Eclipse的用户,呃,请自己到官网进行观摩,有教程,但你真的还要对Android Studio视而不见继续用Eclipse么……
主Activity代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package
com
.
kaelli
.
frescodemo
;
import
android
.
app
.
Activity
;
import
android
.
net
.
Uri
;
import
android
.
os
.
Bundle
;
import
com
.
facebook
.
drawee
.
backends
.
pipeline
.
Fresco
;
import
com
.
facebook
.
drawee
.
view
.
SimpleDraweeView
;
public
class
MainActivity
extends
Activity
{
private
SimpleDraweeView
mSimpleDraweeView
;
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
)
;
Fresco
.
initialize
(
this
)
;
setContentView
(
R
.
layout
.
activity_main
)
;
mSimpleDraweeView
=
(
SimpleDraweeView
)
findViewById
(
R
.
id
.
simpleDraweeView
)
;
mSimpleDraweeView
.
setImageURI
(
Uri
.
parse
(
"http://f2.topit.me/2/79/0a/1175191760a730a792o.jpg"
)
)
;
}
}
|
相对应的布局文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<com.facebook.drawee.view.SimpleDraweeView
xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
xmlns
:
fresco
=
"http://schemas.android.com/apk/res-auto"
android
:
id
=
"@+id/simpleDraweeView"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"match_parent"
fresco
:
fadeDuration
=
"300"
fresco
:
actualImageScaleType
=
"fitCenter"
fresco
:
placeholderImage
=
"@drawable/image1"
fresco
:
placeholderImageScaleType
=
"fitCenter"
fresco
:
failureImage
=
"@drawable/image1"
fresco
:
failureImageScaleType
=
"fitCenter"
/>
|
程序的运行截图如下:
FrescoDemo运行图
看得出来,Fresco的一个很大的特点在于,它自定义了一个SimpleDraweeView,而不是直接在ImageView上进行操作。你可能会觉得这样有些麻烦,毕竟人家UIL是直接用普通的ImageView的,但Facebook这么做是有其道理的。如果你有兴趣,查看一下源码,看得出来目前SimpleDraweeView是继承自ImageView的,然而很多ImageView的方法已经被@Deprecated掉了,不建议使用,而且其开发人员也表示今后的版本中,Fresco的SimpleDraweeView将会直接继承自View,与ImageView再无关系。
使用Fresco有一些需要注意的地方:
1、一定不要忘了Fresco库的初始化:
|
Fresco
.
initialize
(
this
)
;
|
通常这一句将在Application的onCreate中是比较合适的,如果只有一个Activity,那么加在Activity里也可以,但要在setContentView之前,也就是要先初始化库,才能完成布局文件的加载。
- SimpleDraweeView的width和height属性必须是明确值,而不能直接用wrap_content这种内容填充的数值,当然有一种情况例外,就是宽度和高度有一个是固定的,然后设置了二者的比例,则另一个可以用wrap_content,其实相当于二者都是固定的。
|
mSimpleDraweeView
.
setAspectRatio
(
1.33f
)
;
// 设置宽高比为4:3
|
3、正常情况下,一个SimpleDraweeView的各种属性,既可以在布局文件里面设置(如上面的代码),也可以在Java代码里设置,作用是一样的。但既然提到了“正常情况”,那就必然有非正常情况了:当SimpleDraweeView被被一些第三方自定义View包裹的时候,比如最常见的,一个可下拉刷新的第三方ListView,则此时在布局文件中的一些属性居然是无效的!好吧,根本原因我并没有找到,只能在代码里面设置属性了,仍然没有任何难度:
|
GenericDraweeHierarchyBuilder
builder
=
new
GenericDraweeHierarchyBuilder
(
getResources
(
)
)
;
GenericDraweeHierarchy
hierarchy
=
builder
.
setActualImageScaleType
(
ScalingUtils
.
ScaleType
.
FIT_CENTER
)
.
setPlaceholderImage
(
getResources
(
)
.
getDrawable
(
R
.
drawable
.
image1
)
,
ScalingUtils
.
ScaleType
.
FIT_CENTER
)
.
setFailureImage
(
getResources
(
)
.
getDrawable
(
R
.
drawable
.
image1
)
,
ScalingUtils
.
ScaleType
.
FIT_CENTER
)
.
build
(
)
;
mSimpleDraweeView
.
setHierarchy
(
hierarchy
)
;
|
一般来说,安全起见,还是直接在Java代码里写比较好,布局文件里面只是声明一个SimpleDraweeView就足够了。
4、不要使用那些被@Deprecated的方法,尽管这些方法(如setImageResource或者setImageBitmap)是可用的,但在以后的版本中也许就作废了。Fresco的建议是,直接用setImageURI的方法来设置图片,即使是本地的图片也用这种方法。
今天只写了Fresco的最基本的用法,实际上可能很多人比较关心它的性能到底有多么出色,那么以后我会用它来跟Universal-Image-Loader还有Picasso进行对比,这样你就能知道,为什么要选择Fresco了。