Fresco Tips

Universal-Image-Loader(目前作者已经停止维护) ,GlidePicasso,Fresco,在我使用过的这4款开源框架中,Fresco 算是当前最强大的。如果你还没接触或者了解过Fresco,那一定要去体验一下。推荐阅读官方英文文档,需要自备梯子,在使用过程中遇到问题可以去Fresco Github Issues查找,能解决绝大部分问题。如果觉得英文实在费神,也有中文文档,但中文是国内开发者对比翻译的,可能会有滞后的情况。

Fresco官方文档对于基本使用和配置已经介绍得非常详细,这就不细讲啦,主要介绍下面两点:

1、如何用自己定义的ImageView去加载图片而不是SimpleDraweeView
2、如何加载https图片

这就要用到Fresco中Image Pipeline这个类了,Image pipeline 负责完成加载图像,变成Android设备可呈现的形式所要做的每个事情,Image pipeline 可以从本地加载图片,也可以加载网络图片,下图包含了Image pipeline的逻辑流程,在子线程和主线程的任务罗列得很详细,借用一下中文文档的图:

那如何处理上面提到两个问题呢?我综合到了一个例子里进行说明。

首先切换到app目录下bulid.gradle文件,添加依赖

compile ‘com.facebook.fresco:fresco:1.7.1’
compile “com.facebook.fresco:imagepipeline-okhttp3:0.12.0+”

然后在Application中进行Fresco初始化,如果加载的是https图片,那么这里就要添加HttpClient进行Image pipeline的配置(关于如何使用OkHttpClient的证书配置,网上有很多Demo和代码,为了方便,我这里就信任所有证书了,来自CSDN)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//1.新建TrustAllcert类实现X509TrustManager接口:
public class TrustAllCerts implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {}

@Override
public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}
}

//2.方法createSSLSocketFactory()调用类TrustAllcert,获取SSLSocketFactory
private static SSLSocketFactory createSSLSocketFactory() {
SSLSocketFactory ssfFactory = null;

try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());

ssfFactory = sc.getSocketFactory();
} catch (Exception e) {
}

return ssfFactory;
}
}

接着配置ImagePipelineConfig,初始化Fresco:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
OkHttpClient.Builder builder = new OkHttpClient.Builder();  
builder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
builder.sslSocketFactory(createSSLSocketFactory());
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
OkHttpClient okHttpClient = builder.build();
ImagePipelineConfig config = OkHttpImagePipelineConfigFactory
.newBuilder(this, okHttpClient)
.build();
Fresco.initialize(this,config);

“万事俱备,只欠东风”,如果没有使用HTTPS的图片,可以跳过上面的大部分配置。使用步骤就很简单了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ImagePipeline imagePipeline = Fresco.getImagePipeline();
DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(ImageRequest.fromUri(图片地址),null);
dataSource.subscribe(new BaseBitmapDataSubscriber() {
@Override
protected void onNewResultImpl(Bitmap bitmap) {
final Drawable drawable = new BitmapDrawable(App.getContext().getResources(), bitmap);
//获取到drawable后,就可以使用自定义的ImageView加载图片了
ImageView.post(new Runnable() {
@Override
public void run() {

ImageView.setImageDrawable(drawable);
}
});
}

@Override
protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {

}
}, CallerThreadExecutor.getInstance());

这里有个重点需要注意,一定要开线程加载图片,否则会报错抛如下异常

E/unknown:: unhandled exception 
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.