coil
coil copied to clipboard
Why fetcher class mark as internal
Some times i have Image which like: 1.try first url,if success, use it 2.try second url, if success,use it 3.if all fail ,try other way
as i think, i should implement a Fetcher by myself , which may use HttpUriFetcher object. But HttpUriFetcher is internal class , i could't override it or create instance
It should be able to extend HttpUriFetcher
As i check history, there is some old issue about this. I think, if we use HttpUriFetcher just according Fetcher interface, you can still change the implement code as you wish
class SerialFetcher(
private val data: TestItem,
private val options: Options,
callFactory: Lazy<Call.Factory>,
diskCache: Lazy<DiskCache?>,
respectCacheHeaders: Boolean,
private val imageLoader: ImageLoader
) : Fetcher {
val httpUriFetcher = HttpUriFetcher.Factory(callFactory, diskCache, respectCacheHeaders)
override suspend fun fetch(): FetchResult? {
var urlFetcher = httpUriFetcher.create(Uri.parse(data.url), options, imageLoader)
var result = urlFetcher?.fetch()
if (result != null) {
return result
}
urlFetcher = httpUriFetcher.create(Uri.parse(data.url2), options, imageLoader)
result = urlFetcher?.fetch()
if (result != null) {
return result
}
//get file by serial
return null
}
class Factory(
private val callFactory: Lazy<Call.Factory>,
private val diskCache: Lazy<DiskCache?>,
private val respectCacheHeaders: Boolean
) : Fetcher.Factory<TestItem> {
override fun create(data: TestItem, options: Options, imageLoader: ImageLoader): Fetcher? {
return SerialFetcher(
data,
options,
callFactory,
diskCache,
respectCacheHeaders,
imageLoader
)
}
}
}
You should use delegation for this use case. HttpUriFetcher
is internal so the arguments it accepts can easily be changed in the future to add new functionality. Using delegation instead keeps the components decoupled. Inside your fetch
method you can do:
val mappedData = imageLoader.components.map(url, options)
val (fetcher) = checkNotNull(imageLoader.newFetcher(mappedData, options, imageLoader)) { "no fetcher to handle data: $data" }
fetcher.fetch() // will attempt to fetch the url
I'll add a section to the docs as well to better document this.
@colinrtwhite Is the solution documented now? I think https://coil-kt.github.io/coil/image_pipeline/
should mention it. Btw, the correct code should be imageLoader.components.newFetcher(mappedData, options, imageLoader)