今天使用fresco时,项目中在加载图片时添加了防盗链,需要在获取图片时添加header信息,研究了下fresco如何添加header,解决方案如下:
1、新建一个类ElnImageDownloaderFetcher,继承HttpUrlConnectionNetworkFetcher
2、将HttpUrlConnectionNetworkFetcher类的代码拷贝到新类
3、重写HttpURLConnection的获取
4、将ElnImageDownloaderFetcher配置到ImagePipelineConfig
代码实现如下:
ElnImageDownloaderFetcher.java
public class ElnImageDownloaderFetcher extends HttpUrlConnectionNetworkFetcher {
private static final int NUM_NETWORK_THREADS = 3;
public static final int DEFAULT_HTTP_CONNECT_TIMEOUT = 5000;
public static final int DEFAULT_HTTP_READ_TIMEOUT = 20000;
private final ExecutorService mExecutorService;
public ElnImageDownloaderFetcher() {
mExecutorService = Executors.newFixedThreadPool(NUM_NETWORK_THREADS);
}
@Override
public void fetch(final FetchState fetchState, final Callback callback) {
final Future<?> future = mExecutorService.submit(
new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
Uri uri = fetchState.getUri();
String scheme = uri.getScheme();
String uriString = fetchState.getUri().toString();
while (true) {
String nextUriString;
String nextScheme;
InputStream is;
try {
connection = createConnection(uriString);
nextUriString = connection.getHeaderField("Location");
nextScheme = (nextUriString == null) ? null : Uri.parse(nextUriString).getScheme();
if (nextUriString == null || nextScheme.equals(scheme)) {
is = connection.getInputStream();
callback.onResponse(is, -1);
break;
}
uriString = nextUriString;
scheme = nextScheme;
} catch (Exception e) {
callback.onFailure(e);
break;
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
}
});
fetchState.getContext().addCallbacks(
new BaseProducerContextCallbacks() {
@Override
public void onCancellationRequested() {
if (future.cancel(false)) {
callback.onCancellation();
}
}
});
}
protected HttpURLConnection createConnection(String url) throws IOException {
String encodedUrl = Uri.encode(url, "@#&=*+-_.,:!?()/~\'%");
HttpURLConnection conn = (HttpURLConnection)(new URL(encodedUrl)).openConnection();
conn.setConnectTimeout(DEFAULT_HTTP_CONNECT_TIMEOUT);
conn.setReadTimeout(DEFAULT_HTTP_READ_TIMEOUT);
if (BaseRequest.REFERER_OPEN) {
conn.setRequestProperty(BaseRequest.getRefererKey(), BaseRequest.getRefererValue());
}
return conn;
}
}
重点在方法createConnection里,设置了referer信息
然后带配置初始化fresco:
private void initFresco(){
DiskCacheConfig diskCacheConfig = DiskCacheConfig.newBuilder()
.setBaseDirectoryPath(new File(MultiCard.getInstance(this).getRootDir()))
.setBaseDirectoryName("image_cache")
.setMaxCacheSize(50 * ByteConstants.MB)
.setMaxCacheSizeOnLowDiskSpace(10 * ByteConstants.MB)
.setMaxCacheSizeOnVeryLowDiskSpace(2 * ByteConstants.MB)
.build();
ImagePipelineConfig config = ImagePipelineConfig.newBuilder(this)
.setNetworkFetcher(new ElnImageDownloaderFetcher())
.setMainDiskCacheConfig(diskCacheConfig).build();
Fresco.initialize(this, config);
}
重点是给ImagePipelineConfig 配置了NetworkFetcher。
OK,解决,记录一下。