Coil হল Android-এ ইমেজ লোড করারための একটি লাইব্রেরি, যা Kotlin-এ লেখা এবং coroutines-এর উপর নির্মিত। অফিসিয়াল ডকুমেন্টেশন অনুযায়ী, লাইব্রেরিটি Memory Cache, Disk Cache এবং হার্ডওয়্যার-ত্বরিত ট্রান্সফর্মেশন সমর্থন করে। Coil তার ন্যূনতম APK আকার (প্রায় 150 KB) এবং Jetpack Compose-এর সাথে সম্পূর্ণ সামঞ্জস্যের জন্য আলাদা।
মূল পয়েন্ট
Coil (Coroutine Image Loader) Android-এ ইমেজ লোড করার জন্য একটি লাইব্রেরি, যা সম্পূর্ণরূপে Kotlin-এ লেখা এবং অ্যাসিনক্রোনাস অপারেশনের জন্য coroutines ব্যবহার করে। এটি নেটওয়ার্ক, রিসোর্স, ফাইল সিস্টেম এবং Content Provider থেকে বিটম্যাপ ইমেজ লোড করার জন্য একটি ইউনিফাইড API প্রদান করে, স্বয়ংক্রিয় মাল্টি-লেভেল ক্যাশিং সহ।
Glide এবং Picasso-এর বিপরীতে, Coil কলব্যাক চেইনের পরিবর্তে Kotlin Coroutines ব্যবহার করে, যা কোডকে আরও রৈখিক এবং পূর্বানুমানযোগ্য করে তোলে। সমস্ত লোডিং এবং ডিকোডিং অপারেশন Dispatchers.IO ডিসপ্যাচারের মাধ্যমে ব্যাকগ্রাউন্ড থ্রেডে এক্সিকিউট হয় এবং ফলাফল স্পষ্ট সুইচিং ছাড়াই প্রধান থ্রেডে পৌঁছে দেওয়া হয়।
Coil ট্রান্সফর্মেশন (Round, Blur, Grayscale), ট্রানজিশন অ্যানিমেশন, SVG এবং GIF, সেইসাথে অ-মানক ডিসপ্লের জন্য কাস্টম Targets সমর্থন করে। Google I/O 2023 অনুযায়ী, Coil-কে Glide-এর পাশাপাশি অফিসিয়াল Jetpack Compose টিউটোরিয়ালে সুপারিশ করা হয়েছে।
ImageLoader Coil-এর প্রধান উপাদান, যা লোডিং অনুরোধ সম্পাদন এবং ক্যাশ পরিচালনার জন্য দায়ী। প্রতিটি ইনস্ট্যান্সে MemoryCache, DiskCache, BitmapPool এবং coroutine পুলের রেফারেন্স থাকে। ডিফল্টরূপে, Coil.imageLoader(context)-এর মাধ্যমে তৈরি একটি সিংগলটন ব্যবহার করা হয়।
ImageRequest একটি অবজেক্ট যা একটি একক ইমেজ লোডিং অনুরোধ বর্ণনা করে: ডেটা উৎস (URL, URI, Int রিসোর্স), লক্ষ্য ImageView বা Target, ট্রান্সফর্মেশন, ক্যাশিং সেটিংস এবং placeholder। ImageRequest একটি বিল্ডারের মাধ্যমে তৈরি করা হয়, যা নমনীয়তা এবং পঠনযোগ্যতা নিশ্চিত করে।
val request = ImageRequest.Builder(context)
.data("https://example.com/image.jpg")
.crossfade(true)
.size(512, 512)
.transformations(listOf(RoundedCornersTransformation(12f)))
.memoryCachePolicy(CachePolicy.ENABLED)
.diskCachePolicy(CachePolicy.ENABLED)
.target(imageView)
.build()
তৈরির পরে, ImageRequest enqueue বা execute-এর মাধ্যমে ImageLoader-এ পাঠানো হয়। enqueue মেথড একটি coroutine শুরু করে এবং একটি Disposable রিটার্ন করে, যা স্ক্রিন ছেড়ে যাওয়ার সময় লোডিং বাতিল করার অনুমতি দেয়। execute মেথড একটি suspend ফাংশন যা সরাসরি Result রিটার্ন করে।
ImageLoader ক্রমান্বয়ে MemoryCache, DiskCache চেক করে এবং শুধুমাত্র উভয়ের মিস হলে HttpEngine-এর মাধ্যমে নেটওয়ার্ক অনুরোধ সম্পাদন করে। লোড করার পরে, বাইটগুলি টার্গেট সাইজ বিবেচনা করে Bitmap-এ ডিকোড করা হয়, ট্রান্সফর্মেশন প্রয়োগ করা হয়, ফলাফল উভয় ক্যাশে সংরক্ষণ করা হয় এবং Target-এ পাঠানো হয়।
Coil একটি উপাদান আর্কিটেকচারের উপর নির্মিত যেখানে ডিপেন্ডেন্সি ইনজেকশন-এর মাধ্যমে যেকোনো অংশ প্রতিস্থাপনের ক্ষমতা রয়েছে। সমস্ত উপাদান ImageLoaderFactory-এ নিবন্ধিত হয় এবং বিল্ডারের মাধ্যমে ImageLoader কনস্ট্রাক্টরে পাঠানো হয়।
ImageLoader সমস্ত লোডিং অপারেশনের জন্য প্রবেশ বিন্দু। প্রতিটি ইনস্ট্যান্সে coroutine পুল, BitmapPool, MemoryCache, DiskCache এবং ইন্টারসেপ্টরগুলির একটি তালিকা থাকে। ডিফল্টরূপে, একটি গ্লোবাল ইনস্ট্যান্স তৈরি করা হয়, কিন্তু ইউনিট টেস্টিংয়ের জন্য, বিচ্ছিন্ন ক্যাশ সহ পৃথক ইনস্ট্যান্স তৈরি করা যেতে পারে।
MemoryCache LRU (Least Recently Used) ভিত্তিক একটি ইন-মেমরি ক্যাশ যা ডিকোডেড Bitmap অবজেক্ট সংরক্ষণ করে। ডিফল্ট সর্বোচ্চ আকার উপলব্ধ অ্যাপ্লিকেশন মেমরির 25%, কিন্তু 32 MB-এর কম নয়। ক্যাশ কী URL + আকার + ট্রান্সফর্মেশন থেকে গঠিত হয়, যা পুরানো ইমেজ পুনরুদ্ধার প্রতিরোধ করে।
DiskCache কাঁচা ডেটা (JPEG, PNG, WebP) এবং ডিকোডেড মেটাডেটার জন্য একটি ফাইল-ভিত্তিক ক্যাশ। এটি অ্যাপ্লিকেশনের ক্যাশ ডিরেক্টরিতে অবস্থিত এবং সীমা অতিক্রম করলে স্বয়ংক্রিয় পরিষ্কার সমর্থন করে। ডিস্ক অপারেশন DiskCache.Builder-এর মাধ্যমে ডিরেক্টরি এবং সর্বোচ্চ আকার কনফিগারেশন সহ সম্পাদিত হয়।
Coil একটি মাল্টি-লেভেল ক্যাশিং কৌশল প্রয়োগ করে যা নেটওয়ার্ক অনুরোধ কমায় এবং ইমেজ প্রদর্শন দ্রুত করে। প্রতিটি স্তরের নিজস্ব উদ্দেশ্য এবং ডেটা জীবনকাল রয়েছে।
| স্তর | স্টোরেজ প্রকার | জীবনকাল | ডিফল্ট আকার |
|---|---|---|---|
| Memory Cache | RAM-এ Bitmap | LRU অপসারণ পর্যন্ত | heap-এর 25%, 32 MB থেকে |
| Disk Cache | JPEG/WebP ফাইল | সীমা অতিক্রম পর্যন্ত | 250 MB |
| Http Cache | OkHttp প্রতিক্রিয়া | Cache-Control হেডার অনুযায়ী | HTTP ক্লায়েন্টের উপর নির্ভর করে |
Memory Cache ইতিমধ্যে ডিকোডেড Bitmaps-এ তাত্ক্ষণিক অ্যাক্সেস প্রদান করে। Disk Cache প্রথম লোডের পরে নেটওয়ার্ক ছাড়া (offline-first) অ্যাপ্লিকেশন কাজ নিশ্চিত করে। OkHttp স্তরে Http Cache ETag এবং If-Modified-Since-এর সাথে শর্তসাপেক্ষ অনুরোধ পরিচালনা করে।
ক্যাশিং নীতিগুলি প্রতি-অনুরোধ CachePolicy-এর মাধ্যমে তিনটি মান সহ কনফিগার করা হয়: ENABLED, READ_ONLY, WRITE_ONLY, DISABLED। উদাহরণস্বরূপ, ব্যবহারকারী অবতারগুলির জন্য, Memory Cache-এর জন্য READ_ONLY এবং Disk Cache-এর জন্য ENABLED সেট করা যেতে পারে।
Coil অ্যাপ্লিকেশন আর্কিটেকচারের উপর নির্ভর করে বেশ কয়েকটি ইন্টিগ্রেশন পদ্ধতি প্রদান করে। চলুন কার্যকরী কোড উদাহরণ সহ তিনটি মূল পরিস্থিতি দেখি।
load ImageView-এর জন্য একটি এক্সটেনশন ফাংশন, এক লাইনে ইমেজ লোড করার সবচেয়ে সহজ উপায়। ফাংশনটি URL, URI, Int রিসোর্স বা File, ল্যাম্বডা কনফিগারেটরের মাধ্যমে সমস্ত ঐচ্ছিক প্যারামিটার সহ গ্রহণ করে।
imageView.load("https://example.com/photo.jpg") {
crossfade(true)
placeholder(R.drawable.placeholder)
error(R.drawable.error)
size(300, 300)
transformations(CircleCropTransformation())
}
load মেথড একটি Disposable রিটার্ন করে, যা onDestroy-এ বা View পুনরায় ব্যবহার করার সময় বাতিল করা যেতে পারে। এটি দ্রুত তালিকা স্ক্রলিংয়ের সময় মেমরি লিক এবং অপ্রয়োজনীয় নেটওয়ার্ক অনুরোধ প্রতিরোধ করে।
AsyncImage ডিক্লারেটিভ UI-তে ইমেজ লোড করার জন্য একটি composable ফাংশন। এটি যেকোনো ডেটা উৎস এবং অবস্থার জন্য তিনটি ঐচ্ছিক প্যারামিটার গ্রহণ করে: placeholder, error এবং success।
@Composable
fun NetworkImage(url: String) {
AsyncImage(
model = url,
contentDescription = "নেটওয়ার্ক ইমেজ",
placeholder = ColorPainter(Color.Gray),
error = ColorPainter(Color.Red)
)
}
SubcomposeAsyncImage একটি আরও নমনীয় সংস্করণ যা কন্টেন্ট স্লটের মাধ্যমে লোডিংয়ের সময় ডিসপ্লে কাস্টমাইজ করার অনুমতি দেয়। এটি কঙ্কাল (shimmer) এবং প্রগতি বারের জন্য দরকারী।
যদি ImageView বা AsyncImage উপযুক্ত না হয়, তাহলে আপনি একটি Target প্রয়োগ করতে পারেন যার একটি একক onSuccess মেথড রয়েছে যা Bitmap গ্রহণ করে। এটি Notification, RemoteViews বা OpenGL টেক্সচারে লোড করার জন্য ব্যবহৃত হয়।
val target = object : BitmapTarget() {
override fun onSuccess(result: Bitmap) {
notificationRemoteView.setImageViewBitmap(R.id.icon, result)
}
}
imageLoader.enqueue(
ImageRequest.Builder(context)
.data(url)
.target(target)
.build()
)
ইমেজ লোডিং লাইব্রেরির পছন্দ প্রকল্পের প্রয়োজনীয়তার উপর নির্ভর করে। Coil Glide এবং Picasso-এর সাথে প্রতিযোগিতা করে, প্রতিটির নিজস্ব শক্তি রয়েছে। মূল বৈশিষ্ট্যগুলির তুলনা টেবিলে উপস্থাপন করা হয়েছে।
| বৈশিষ্ট্য | Coil | Glide | Picasso |
|---|---|---|---|
| ভাষা | Kotlin (100%) | Java + Kotlin | Java |
| APK আকার | ~150 KB | ~500 KB | ~120 KB |
| Coroutines | অন্তর্নির্মিত | না (কলব্যাক) | না (কলব্যাক) |
| Jetpack Compose | স্থানীয় সমর্থন | accompanist-এর মাধ্যমে | তৃতীয়-পক্ষ |
| GIF/WebP | হ্যাঁ (অন্তর্নির্মিত) | হ্যাঁ (অন্তর্নির্মিত) | না |
| Google সুপারিশ | হ্যাঁ (I/O 2023) | হ্যাঁ | না |
Kotlin এবং Jetpack Compose-এ নতুন প্রকল্পের জন্য, Coil শূন্য অতিরিক্ত coroutine নির্ভরতা এবং ন্যূনতম আকারের কারণে প্রাকৃতিক পছন্দ হয়ে ওঠে। Glide অ্যানিমেশন এবং ভিডিও প্রিভিউ সহ জটিল পরিস্থিতির জন্য পছন্দের থাকে। Picasso কার্যকারিতায় উভয়ের থেকে পিছিয়ে কিন্তু সরলতায় জয়ী।
Android প্রকল্পে Coil যোগ করা Gradle নির্ভরতার মাধ্যমে করা হয়। যোগ করার পরে, লাইব্রেরি ContentProvider-এর মাধ্যমে স্বয়ংক্রিয়ভাবে একটি ImageLoader নিবন্ধন করে, তাই Application-এ ম্যানুয়াল আরম্ভের প্রয়োজন নেই। যদি কাস্টমাইজেশনের প্রয়োজন হয়, বিল্ডারের মাধ্যমে একটি কাস্টম ImageLoader তৈরি করা হয়।
// build.gradle.kts (app module)
dependencies {
implementation("io.coil-kt:coil:2.6.0")
// Jetpack Compose-এর জন্য অতিরিক্ত:
implementation("io.coil-kt:coil-compose:2.6.0")
// SVG সমর্থনের জন্য:
implementation("io.coil-kt:coil-svg:2.6.0")
// GIF সমর্থনের জন্য:
implementation("io.coil-kt:coil-gif:2.6.0")
}
ImageLoader কাস্টমাইজ করার জন্য, ImageLoaderFactory ব্যবহার করা হয় — Application.onCreate-এ তৈরি একটি সিংগলটন। ফ্যাক্টরিতে, আপনি ক্যাশ সীমা, HTTP ক্লায়েন্ট, কাস্টম ডিকোডার এবং লগিং কনফিগার করতে পারেন। ডিফল্টরূপে, Coil একটি প্রস্তুত সংযোগ পুল সহ OkHttp ব্যবহার করে।
class App : Application(), ImageLoaderFactory {
override fun newImageLoader(): ImageLoader {
return ImageLoader.Builder(this)
.memoryCache {
MemoryCache.Builder()
.maxSizePercent(0.25)
.build()
}
.diskCache {
DiskCache.Builder()
.directory(cacheDir.resolve("coil_cache"))
.maxSizeBytes(512 * 1024 * 1024)
.build()
}
.build()
}
}
প্রায়শই জিজ্ঞাসিত প্রশ্ন
Coil Android-এ ইমেজ লোড করার জন্য একটি লাইব্রেরি, যা Kotlin-এ coroutines ব্যবহার করে লেখা। এটি নেটওয়ার্ক, রিসোর্স বা ফাইল সিস্টেম থেকে অ্যাসিনক্রোনাস লোডিং, ক্যাশিং এবং বিটম্যাপ ইমেজ প্রদর্শনের জন্য ব্যবহৃত হয়।
Coil 100% Kotlin-এ লেখা এবং Glide-এর কলব্যাক প্রক্রিয়ার পরিবর্তে coroutines ব্যবহার করে। Coil-এর APK আকার ছোট (~150 KB বনাম ~500 KB) এবং AsyncImage-এর মাধ্যমে Jetpack Compose-এর জন্য স্থানীয় সমর্থন রয়েছে।
build.gradle.kts-এ নির্ভরতা io.coil-kt:coil:2.6.0 যোগ করুন। Jetpack Compose-এর জন্য, io.coil-kt:coil-compose:2.6.0 ও যোগ করুন। লাইব্রেরিটি ContentProvider-এর মাধ্যমে স্বয়ংক্রিয়ভাবে ImageLoader নিবন্ধন করে।
Coil JPEG, PNG, WebP, BMP, SVG (coil-svg মডিউলের মাধ্যমে) এবং GIF (coil-gif মডিউলের মাধ্যমে) সমর্থন করে। AVIF এবং HEIF ফরম্যাট Android 10+ ডিভাইসে কাস্টম ডিকোডারের মাধ্যমে সমর্থিত।
ক্যাশ ImageLoader.Builder-এর মাধ্যমে কনফিগার করা হয়: memoryCache heap-এর শতাংশ সহ, diskCache পাথ এবং বাইটে সীমা সহ। ক্যাশ নীতিগুলি (ENABLED, DISABLED, READ_ONLY) CachePolicy-এর মাধ্যমে প্রতি-অনুরোধ কনফিগার করা হয়।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন