Skip to content

Commit 796c186

Browse files
committed
glide post added
1 parent c33d6fa commit 796c186

File tree

4 files changed

+211
-0
lines changed

4 files changed

+211
-0
lines changed

_drafts/2019-06-17-glide.md

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
---
2+
layout: post
3+
title: "Glide"
4+
date: 2019-06-17
5+
categories: ["Biblioteki"]
6+
image: libraries/glide
7+
github: libraries/tree/master/glide
8+
description: "Biblioteki"
9+
version: Glide 4.9
10+
keywords: "glide, image, imageview, bitmap, network, resources, memory, cache, disk, loader, imageloader, gif, transition, transformation, android, programowanie, programming"
11+
---
12+
13+
## Wstęp
14+
`Glide` jest wydajną biblioteką służącą do zarządzania multimediami, ich dekodowaniem i buforowaniem w pamięci oraz na dysku w celu ponownego szybkiego użycia. Skupia się przede wszystkim na płynnym i wydajnym wyświetlaniu, pobieraniu i modyfikowaniu obrazów. Ponadto obsługuje także obrazy animowane GIF oraz wideo. Zawiera elastyczne i prosty interfejs API, który umożliwia podłączanie niemal dowolnego klienta sieciowego (domyślnie jest to HttpUrlConnection).
15+
16+
## Ładowanie
17+
Pobieranie i ładowanie obrazów jest proste i może ograniczyć się zaledwie do jednego ciągu instrukcji. Wyrażenie with zwraca obiekt typu `RequestBuilder` na którym należy wskazać źródło (`load`) i typ zasobu, miejsce docelowe (`into`) oraz opcjonalnie dokonać konfiguracji żądania. Możliwe jest także pobranie zasobu do wskazanego typu obietku z pominięciem ładowania do kontrolki widoku przez wskazanie jako miejsca docelowego obiektu typu `Target`. Glide automatycznie wylicza rozmiar obrazu, aby dopasować go do widoku w którym będzie wyświetlany, jednakże jawnie ustawiony rozmiar przyspiesza proces przetwarzania. W trakcie niszczenia komponentu powiązane z nim zasoby są poddawane recyklingowi, a te nieużywany zostają usuwane.
18+
19+
{% highlight kotlin %}
20+
private fun loadImage() {
21+
//default load source as Drawable
22+
Glide.with(this) //pass Context - returns RequestBuilder
23+
.load(url) //pass url, file, drawable object, local resource etc
24+
//set some RequestListener if needed
25+
.into(imageView) //tell where to load image
26+
}
27+
28+
private fun loadImageIntoBitmapTarget() {
29+
val target = object: CustomTarget<Bitmap>() {
30+
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
31+
val bitmap = resource
32+
//do something with downloaded bitmap
33+
}
34+
override fun onLoadCleared(placeholder: Drawable?) {
35+
//action when loading canceled
36+
}
37+
//implement other callback methods like onLoadStarted, onLoadFailed
38+
}
39+
40+
//could be: asDrawable, asBitmap, asFile, asGif
41+
Glide.with(this).asBitmap().load(url).into(target)
42+
}
43+
44+
private fun clearData() {
45+
//manual loading data clear
46+
Glide.with(this).clear(imageView) //or pass target
47+
}
48+
{% endhighlight %}
49+
50+
## Symbol zastępczy
51+
Symbol zastępczy (`placeholder`) jest graficznym wyświetlanym w trakcie pobierania i przetwarzania obiektu źródłowego. Gdy żądanie zostaje ukończone pozytywnie wówczas placeholder jest zastępowany przez źródło. Ładowanie odbywa się na wątku głównym, a transformacje są niedozwolone. Dodatkowo możliwe jest ustawienie obiektu placeholder dla żądania zakończonego kodem błędu (`error` i `fallback`), jednakże gdy nie zostanie on ustawiony wówczas pozostanie wyświetlany bieżący placeholder (jeśli został ustawiony). Ponadto możliwe jest ustawienie miniatury (`thumbnail`), która jest pobierana równolegle z głównym żądaniem co pozwala na zwiększenie doświadczeń użytkownika przez wyświetlenia obrazu niższej rozdzielczości (zamiast zastępnika) w trakcie oczekiwania na pobranie pełnego obrazu.
52+
53+
{% highlight kotlin %}
54+
private fun loadWithPlaceholders() {
55+
Glide.with(this).load(url)
56+
.placeholder(R.drawable.placeholder) //main placeholder
57+
.error(R.drawable.placeholder_error) //placeholder when request permanently fails
58+
.fallback(R.drawable.placeholder_fallback) //placeholder when requested model is null
59+
.into(imageView)
60+
}
61+
62+
private fun loadWithThumbnail() {
63+
Glide.with(this).load(url)
64+
.thumbnail(Glide.with(this).load(url_miniature))
65+
.into(imageView)
66+
}
67+
{% endhighlight %}
68+
69+
## Opcje
70+
Glide oferuje wiele opcji przetwarzania i ładowania zasobów takich jak m.in. transformacje, przejścia, czy buforowanie które można zastosować dla wybranych żądań bezpośrednio na obiekcie `RequestBuilder`. Opcje mogą być także współdzielone przez instancję `RequestOptions` (transformacje i strategie buforowania) oraz `TransitionOptions` (przejścia). Transformacje (`transitions`) zwracają zmodyfikowany zasób i są używane przede wszystkim do przycinania obrazu i stosowania filtrów. Zastosowanie metody dowolnej transformacji zastępuje poprzednią dlatego w celu zaaplikowania kilku transformacji należy przekazać je do metody transform. Przejścia (`transformations`) działa w kontekście pojedynczego żądania i pozwalają zdefiniować w jaki sposób Glide powinien przejść z obiektu zastępczego czy miniatury do załadowanego docelowego obrazu. Ponadto użycie przejść wpływa na wydajność w związku z czym należy rozważyć unikanie animacji przejść szczególnie w przypadku kolekcji.
71+
72+
{% highlight kotlin %}
73+
private fun loadImageCustom() {
74+
//load image with some custom modifications
75+
Glide.with(this).load(url)
76+
.centerCrop() //apply some transforms
77+
.transition(withCrossFade())
78+
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
79+
.into(imageView)
80+
}
81+
82+
private fun loadImageCustomOptions() {
83+
//TransitionOptions are tied with specific type like DrawableTransitionOptions
84+
val transitionOptions = DrawableTransitionOptions()
85+
.crossFade()
86+
87+
//create RequestOptions and reuse it
88+
val requestOptions = RequestOptions()
89+
.centerCrop()
90+
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
91+
//add more transforms
92+
93+
Glide.with(this).load(url)
94+
.transition(transitionOptions)
95+
.apply(requestOptions).into(imageView)
96+
}
97+
98+
private fun loadImageMultipleTransforms() {
99+
Glide.with(this).load(url)
100+
.transform(FitCenter(), Rotate(90))
101+
.into(imageView)
102+
}
103+
{% endhighlight %}
104+
105+
## Pamięć
106+
Zanim Glide rozpocznie pobieranie nowego zasobu dokonuje sprawdzenia warstw pamięci w celu jego odnalezienia i ponownego użycia co przebiega w następujących krokach:
107+
108+
>**1. Aktywne zasoby** (obraz jest wyświetlany w innym widoku)
109+
>**2. Pamięc podręczna** (obraz został niedawno załadowany i pozostaje nadal w pamięci)
110+
>**3. Zasób** (obraz został wcześniej zdekodowany, przekształcony i zapisany w pamięci dysku)
111+
>**4. Dane** (dane z których uzyskano obraz zapisano wcześniej w pamięci podręcznej dysku)
112+
>
113+
114+
Jeśli zasób nie został odnaleziony w żadnej warstwie pamięci wówczas zostaje on pobrany z oryginalnego źródła. Weryfikacja istnienia zasobu w warstwach pamięci odbywa się na podstawie wyszukiwania klucza składającego się z modelu (`File`, `Uri`, `Url` itp.), opcjonalnej sygnatury dołączonej metodą `signature` oraz parametrów zasobów takich jak m.in. wielkość, transformacje, opcje czy typ (dla kroków 1-3). Glide pozwala na uwzględnienie (`onlyRetrieveFromCache`) lub pominięcie pamięci podręcznej (`skipMemoryCache`) oraz dostarcza kilka strategii dla pamięci dysku (`DiskCacheStrategy`), które umożliwiają wybór sposobu ładowania i zapisywania pobranych zasobów.
115+
116+
{% highlight kotlin %}
117+
private fun loadImageWithCustomSignature() {
118+
Glide.with(this).load(url)
119+
.signature(ObjectKey("version")) //custom metadata if possible like last modified time
120+
.into(imageView)
121+
}
122+
123+
private fun loadAndSaveImageBySomeStrategy() {
124+
Glide.with(this).load(url)
125+
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC) //is default
126+
.into(imageView)
127+
128+
/* use one of DiskStrategyCache:
129+
AUTOMATIC - optimal strategy based on data source
130+
DATA - stores original retrieved data in disk cache
131+
RESOURCE - stores data in disk cache after decoding
132+
ALL - remote data with both DATA and RESOURCE, local data only with RESOURCE
133+
NONE - saves no data to disk cache */
134+
}
135+
136+
private fun loadImageOnylIfExistsInCache() {
137+
Glide.with(this).load(url)
138+
.onlyRetrieveFromCache(true)
139+
.into(imageView)
140+
141+
//if image doesn't exists in memory or disk cache then load fail
142+
}
143+
144+
private fun loadImageSkippingCache() {
145+
Glide.with(this).load(url)
146+
.skipMemoryCache(true)
147+
.into(imageView)
148+
149+
//skip memory cache
150+
}
151+
{% endhighlight %}
152+
153+
Wielkość pamięci jest automatycznie ustalana i może być modyfikowana w oparciu o klasę `MemorySizeCalculator`. Tymczasowe zwiększenie pamięci podręcznej odbywa się za pomocą metody `setMemoryCategory`, a ręczne czyszczenie pamięci podręcznej i dysku przy użyciu `clearMemory` (na głównym wątku) oraz `clearDiskCache` (na wątku pobocznym).
154+
155+
## Interfejs API
156+
Glide pozwala na rozszerzenie interfejsu API dzięki czemu możliwe jest ustawienie i nadpisanie domyślnych opcji globalnych dla żądań oraz dołączenie bibliotek integracyjnych. Aby wygenerować interfejs należy stworzyć klasę modułu `AppGlideModule` opatrzoną adnotacją `@GlideModule` oraz opcjonalnie klasę rozszerzeń `@GlideExtension` z metodami statycznymi oznaczonymi jako `@GlideOption` i `@GlideType`.
157+
158+
{% highlight kotlin %}
159+
@GlideModule
160+
class CustomAppGlideModule : AppGlideModule() {
161+
162+
//this will apply as global settings
163+
override fun applyOptions(context: Context, builder: GlideBuilder) {
164+
//create custom options
165+
val requestOptions = RequestOptions()
166+
.circleCrop()
167+
.diskCacheStrategy(DiskCacheStrategy.DATA)
168+
169+
val transitionOptions = DrawableTransitionOptions()
170+
.crossFade()
171+
172+
//set custom memory size
173+
val customMemoryCacheSize = (MemorySizeCalculator.Builder(context)
174+
.build().memoryCacheSize * 1.1).toLong()
175+
176+
//apply some custom settings
177+
builder
178+
.setDefaultRequestOptions(requestOptions)
179+
.setDefaultTransitionOptions(Drawable::class.java, transitionOptions)
180+
.setLogLevel(Log.ERROR)
181+
.setMemoryCache(LruResourceCache(customMemoryCacheSize))
182+
}
183+
184+
//body can be also empty
185+
}
186+
187+
@GlideExtension
188+
object CustomGlideExtension {
189+
190+
//class with private constructor and static annotated methods
191+
192+
@GlideOption
193+
@JvmStatic
194+
fun smallCircle(options: BaseRequestOptions<*>): BaseRequestOptions<*> {
195+
return options.circleCrop().override(100)
196+
}
197+
198+
//more @GlideOption and @GlideType methods
199+
}
200+
{% endhighlight %}
201+
202+
Odwołanie do stworzonego modułu odbywa się domyślnie na instancji `GlideApp` tworzonej przy budowaniu projektu. Nie wyklucza to jednak użycia w standardowy sposób za pomocą instancji `Glide`.
203+
204+
{% highlight kotlin %}
205+
private fun loadImageByCustomModule() {
206+
//will draw circle crop 100px image with cross fade transition and custom log and cache settings
207+
GlideApp.with(this).load(url)
208+
.smallCircle() //new custom option
209+
.into(imageView)
210+
}
211+
{% endhighlight %}
675 KB
Loading
19.6 KB
Loading
53.3 KB
Loading

0 commit comments

Comments
 (0)