package com.example.myapp.utils
import android.content.Context
import android.graphics.drawable.Drawable
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.example.myapp.R
object ImageLoader {
fun loadImage(
context: Context,
url: String?,
imageView: ImageView,
placeholder: Int = R.drawable.placeholder,
error: Int = R.drawable.error_image
) {
Glide.with(context)
.load(url)
.placeholder(placeholder)
.error(error)
.transition(DrawableTransitionOptions.withCrossFade())
.into(imageView)
}
fun loadCircularImage(
context: Context,
url: String?,
imageView: ImageView
) {
Glide.with(context)
.load(url)
.apply(RequestOptions.circleCropTransform())
.placeholder(R.drawable.placeholder_avatar)
.error(R.drawable.default_avatar)
.into(imageView)
}
fun loadRoundedImage(
context: Context,
url: String?,
imageView: ImageView,
cornerRadius: Int = 16
) {
val options = RequestOptions()
.transform(CenterCrop(), RoundedCorners(cornerRadius))
Glide.with(context)
.load(url)
.apply(options)
.into(imageView)
}
fun loadThumbnail(
context: Context,
url: String?,
imageView: ImageView
) {
Glide.with(context)
.load(url)
.thumbnail(0.1f) // Load 10% quality first
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView)
}
fun preloadImage(context: Context, url: String) {
Glide.with(context)
.load(url)
.preload()
}
fun loadImageWithCallback(
context: Context,
url: String,
onSuccess: (Drawable) -> Unit,
onError: () -> Unit = {}
) {
Glide.with(context)
.load(url)
.into(object : CustomTarget<Drawable>() {
override fun onResourceReady(
resource: Drawable,
transition: Transition<in Drawable>?
) {
onSuccess(resource)
}
override fun onLoadCleared(placeholder: Drawable?) {
// Clean up
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
onError()
}
})
}
fun clearCache(context: Context) {
Glide.get(context).clearMemory()
// Clear disk cache on background thread
Thread {
Glide.get(context).clearDiskCache()
}.start()
}
}
package com.example.myapp
import android.content.Context
import com.bumptech.glide.GlideBuilder
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory
import com.bumptech.glide.load.engine.cache.LruResourceCache
import com.bumptech.glide.module.AppGlideModule
import com.bumptech.glide.request.RequestOptions
@GlideModule
class MyGlideModule : AppGlideModule() {
override fun applyOptions(context: Context, builder: GlideBuilder) {
// Set memory cache size (25% of available memory)
val memoryCacheSizeBytes = 1024 * 1024 * 25L // 25 MB
builder.setMemoryCache(LruResourceCache(memoryCacheSizeBytes))
// Set disk cache size
val diskCacheSizeBytes = 1024 * 1024 * 100L // 100 MB
builder.setDiskCache(
InternalCacheDiskCacheFactory(context, diskCacheSizeBytes)
)
// Set default request options
builder.setDefaultRequestOptions(
RequestOptions()
.format(com.bumptech.glide.load.DecodeFormat.PREFER_ARGB_8888)
)
}
override fun isManifestParsingEnabled(): Boolean {
return false
}
}
Glide efficiently loads and caches images from network, disk, or resources. I use Glide.with(context).load(url).into(imageView) for basic loading. Transformations apply effects—centerCrop(), circleCrop(), RoundedCorners(). Placeholders show during loading, error images display on failure. RequestOptions configure size, format, caching. Glide automatically handles lifecycle, cancelling requests when views detach. Custom targets enable non-View loading. Generated API with annotations provides type-safe configuration. Preloading warms cache before display. Glide supports GIFs, SVGs, and video thumbnails. It's optimized for RecyclerView scrolling. The library reduces boilerplate and handles memory management automatically.
Related snips
module Api
module V1
class UsersController < BaseController
def show
user = User.includes(:profile).find(params[:id])
ETags for conditional requests and caching
package com.example.myapp
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
Dependency injection with Hilt
package com.example.myapp.ui
import androidx.lifecycle.*
import kotlinx.coroutines.launch
class UserViewModel(
LiveData transformations and mediators
json.array! @posts do |post|
json.cache! ['v1', post], expires_in: 1.hour do
json.id post.id
json.title post.title
json.excerpt post.excerpt
json.published_at post.published_at
Fragment caching for expensive JSON serialization
class Comment < ApplicationRecord
belongs_to :post, touch: true
belongs_to :author, class_name: "User"
validates :body, presence: true, length: { maximum: 10_000 }
Granular Cache Invalidation with touch: true
package com.example.myapp.utils
import android.os.Build
import android.os.StrictMode
import android.os.Trace
import timber.log.Timber
Performance optimization and profiling
Share this code
Here's the card — post it anywhere.