Glide使用Plus

Glide与RecyclerView结合的预加载器

Glide的RecyclerView

之前在写漫画阅读器的时候,用的是 RecyclerView + Glide + PhotoView 的方式来加载图片,RecyclerView 的可横可竖的特性非常适合用来写漫画的阅读器。而这个库作用就是通过监听RecyclerView的滑动来进行图片的预加载。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//glide 预加载
// 预加载需要先指定图片的大小才行,否则无效。size[0],size[1]分别指代图片的宽高
val sizeProvider = FixedPreloadSizeProvider<ComicUrlBean>(size[0], size[1])
// comicReader 为 RecyclerView,comicReaderAdapter需要继承ListPreloader.PreloadModelProvider<ComicUrlBean>来提供预加载的地址和动作
val preloader = RecyclerViewPreloader<ComicUrlBean>(Glide.with(this), comicReaderAdapter, sizeProvider, 5)
comicReader.addOnScrollListener(preloader)

//adapter继承的方法
override fun getPreloadItems(position: Int): MutableList<ComicUrlBean> {
return imgData.subList(position, position + 1)
}

override fun getPreloadRequestBuilder(item: ComicUrlBean): RequestBuilder<Drawable>? {
return Glide.with(context).load(item.imgUrl)
}

Glide添加解析的DNS

这个需求是在显示哔咔漫画图片时出现的问题,哔咔漫画显示图片时需要将域名替换成之前从服务器列表选择的ip地址,所以就需要通过往网络请求中添加解析DNS来实现。

首先要引入 Glide Okhttp 插件,这个插件允许开发者可以使用自定义的OkHttp3来替换Glide默认的Okhttp加载器。而 DNS的解析则是需要通过okhttp实现。

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class ComicModelLoader : ModelLoader<String, InputStream> {
var client = OkHttpClient.Builder()
.readTimeout(20, TimeUnit.SECONDS)
//.connectTimeout(20, TimeUnit.SECONDS)
.dns(PicaThumbDns())
.build()


private val okhttpLoader: OkHttpUrlLoader

init {
okhttpLoader = OkHttpUrlLoader(client)
}

override fun buildLoadData(model: String, width: Int, height: Int, options: Options): ModelLoader.LoadData<InputStream>? {
val glideUrl = GlideUrl(model, LazyHeaders.Builder().build())
return okhttpLoader.buildLoadData(glideUrl, width, height, options)
}

override fun handles(model: String): Boolean {
return true
}

class PicaThumbDns : Dns {

override fun lookup(hostname: String): MutableList<InetAddress> {
val address = ComicSettingManager.getInstance().getSetting(ComicSettingManager.KEYWORD_COMIC_PICA_ADDRESS_SET, mutableSetOf())
try {
val arrayList = arrayListOf<InetAddress>()
if (address.isEmpty()) {
return Dns.SYSTEM.lookup(hostname)
}
arrayList.addAll(Dns.SYSTEM.lookup(hostname))
for (add in address) {
arrayList.addAll(InetAddress.getAllByName(add))
}
//arrayList.addAll(Dns.SYSTEM.lookup(hostname))
return arrayList
} catch (e: Exception) {
e.printStackTrace()
return Dns.SYSTEM.lookup(hostname)
}
}
}
}

重点就是将 PicaThumbDns 加载到 OkClient 中。
至于 Glide的ModeLoader使用可以参考官方教程

Glide 使用 OSS 图片

除去使用 阿里OSS 提供的SDK之外,也可以通过在请求的header中添加 Authorization 来进行请求,基本使用方法也是通过自定义 ModelLoader 来实现。

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
@GlideModule
class BgmGlideModule : AppGlideModule() {

override fun applyOptions(context: Context, builder: GlideBuilder) {

}

override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
registry.append(OssCoverBean::class.java, InputStream::class.java, Factory())
}

class Factory : ModelLoaderFactory<OssCoverBean, InputStream> {
override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader<OssCoverBean, InputStream> {
return BgmModelLoader(multiFactory.build(GlideUrl::class.java,InputStream::class.java))
}

override fun teardown() {}
}

}


class BgmModelLoader(private val urlLoader: ModelLoader<GlideUrl?, InputStream>) : ModelLoader<OssCoverBean, InputStream> {

@SuppressLint("SimpleDateFormat")
override fun buildLoadData(model: OssCoverBean, width: Int, height: Int, options: Options): ModelLoader.LoadData<InputStream>? {
var cover = model.cover

val header = LazyHeaders.Builder()

val uri = URI(cover)
val path = uri.path
val headers: MutableMap<String, String> = HashMap()
val df = SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH)
df.timeZone = TimeZone.getTimeZone("GMT")
headers["Date"] = df.format(Date())

val auth =
SignV2Utils.sign(headers,
"bangumi",
path,
"access",
"screct")
header.addHeader(AUTHORIZATION, auth)
header.addHeader("Date", headers["Date"]!!)


val glideUrl = GlideUrl(cover, header.build())
return urlLoader.buildLoadData(glideUrl, width, height, options)
}

override fun handles(model: OssCoverBean): Boolean {
return model.cover.isNotEmpty()
}

}

在 Android 上获取GMT时需要指定 Locale.ENGLISH, 因为有些机型默认中文返回的日期是汉字年月日的格式,放在header上就是出错。

文章作者: cpacm
文章链接: http://www.cpacm.net/2020/01/07/Glide使用Plus/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 cpacm
打赏
  • 微信
  • 支付宝

评论