Codeit Mobile
94 subscribers
3 photos
1 video
243 links
📱 آموزش برنامه‌نویسی موبایل

Kotlin • Android

🚀 آموزش ساده، کاربردی و پروژه‌محور
💡 مخصوص توسعه‌دهندگان موبایل
Download Telegram
سلام! 🚀 امروز می‌خوایم با While Loop در کاتلین آشنا بشیم. یک ابزار ساده و قدرتمند برای تکرار کارها تا زمانی که شرط برقرار باشه.

While Loop چه جوریه؟
- تا وقتی شرط true باشه، بلاک داخلش اجرا می‌شه.
- اگر شرط اولیه false باشه، حتی یک بار هم اجرا نمی‌شه.
- برای حلقه‌هایی که تعداد تکرارش رو از قبل نمی‌دونیم عالیه.

مثال کاربردی: فرض کن می‌خوایم از کاربر عدد ورودی بگیریم تا وقتی عدد مثبت وارد کنه، مجموع رو حساب کنیم.

var sum = 0
var number: Int

while (true) {
println("یک عدد وارد کنید (عدد منفی برای خروج):")
number = readLine()?.toIntOrNull() ?: 0
if (number < 0) break
sum += number
}
println("مجموع اعداد وارد شده: $sum")


این کد تا وقتی عدد منفی وارد نشده، اعداد رو جمع می‌کنه و بعد نمایش می‌ده.
break برای خروج از حلقه استفاده شده.

نکته: همیشه مطمئن باش حلقه متناهی هست، وگرنه برنامه هنگ می‌کنه!

#WhileLoop #KotlinBasics #Looping #AndroidDev #Programming #Codeit #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1
سلام رفیق! وقت یادگیری عمیق‌تره! 🚀

Enum کلاس در کاتلین خیلی فراتر از یک لیست ساده است. می‌تونه داده‌ها و رفتارهای خاص خودش رو داشته باشه. ⚡️

💡 استفاده از enum برای تعریف ثابت‌های محدود (مثل وضعیت‌های یک سفارش یا نوع کاربر) عالیه. اما قابلیت‌های بیشتری هم داره.

مثلاً می‌تونی به هر مقدار enum یک پراپرتی اضافه کنی و داخل هرکدوم یه متد بنویسی. حتی می‌تونی when رو روی enum استفاده کنی تا کدت خواناتر بشه. 🧩

یه مثال کاربردی:

enum class OrderStatus(val displayName: String, val isTerminal: Boolean) {
PENDING("در انتظار پرداخت", false),
PROCESSING("در حال پردازش", false),
SHIPPED("ارسال شده", false),
DELIVERED("تحویل شده", true),
CANCELLED("لغو شده", true);

fun nextStatus(): OrderStatus? {
return when (this) {
PENDING -> PROCESSING
PROCESSING -> SHIPPED
SHIPPED -> DELIVERED
DELIVERED -> null
CANCELLED -> null
}
}
}


این enum دو پراپرتی داره: اسم فارسی و وضعیت نهایی بودن. متد nextStatus هم وضعیت بعدی رو برمی‌گردونه.
اینطوری منطق تغییر وضعیت رو داخل خود enum نگه می‌داری و کدت تمیزتر میشه.

📌 نکته مهم: از enum وقتی استفاده کن که مقادیر محدود و از پیش تعریف شده دارن. اگر تعدادش زیاده یا ممکنه اضافه بشه، از sealed class استفاده کن.

هشتگ‌های مرتبط:
#Enum #KotlinTips #CleanCode #Programming #AndroidDev
#Codeit #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
🔒 Null Safety در Kotlin؛ ترس از Null رو برای همیشه کنار بذار!

بسیاری از باگ‌های برنامه‌نویسی توی اندروید به خاطر NullPointerException هست. 😫 اما Kotlin با یه سیستم هوشمند، این مشکل رو ریشه‌کن کرده!

چطور کار میکنه؟
هر متغیر میتونه دو نوع باشه:
String? → میتونه null باشه
String → هرگز null نیست

🧠 مثال عملی:
فرض کن از سرور اسم کاربر رو می‌گیری. احتمال null وجود داره:

val name: String? = fetchUserName() // ممکنه null برگردونه
val length = name?.length ?: 0 // اگه null باشه، 0 می‌ذاره
println("Length: $length")


📌 توضیح کد:
با ?. (Safe Call) اگه name null باشه، length هم null میشه. با ?: (Elvis Operator) مقدار پیش‌فرض می‌دیم. نتیجه: بدون کرش!

🎯 بعدش چیکار کنیم؟
از عملگرهای !! فقط در مواقع مطمئن استفاده کن (مثلاً بعد از چک کردن if).

خلاصه: Null Safety مثل یه کمربند ایمنی می‌مونه – توی Kotlin دیگه NPE نمی‌بینی! 🚀

#NullSafety #Kotlin #JetpackCompose #AndroidDev #Codeit #Android #Kotlin #Programming
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile

━━━━━━━━━━━━━━━
@CodeitMobile
1
🔹 تا حالا توی «Kotlin» از «if» فقط برای شرط‌گذاری استفاده می‌کردی؟ 😲
🔸 وقتشه ببینی «if» می‌تونه یه مقدار برگردونه! یعنی مثل یه عبارت عمل کنه، نه فقط دستور.

یعنی به جای نوشتن چند خط کد برای مقداردهی، می‌تونی مستقیم از «if» خروجی بگیری.
⚡️ این ویژگی باعث میشه کدت خواناتر، کم‌حجم‌تر و حرفه‌ای‌تر بشه.

💡 مثال واقعی: فرض کن می‌خوای بر اساس امتیاز کاربر، یه پیام خوشامدگویی متفاوت نشون بدی.

📌 کد ساده با «if as expression»:

val score = 85
val message = if (score >= 90) {
"عالی! عالی! 🏆"
} else if (score >= 70) {
"خوب بود، ادامه بده 💪"
} else {
"نیاز به تلاش بیشتر داره 📚"
}
println(message)


🔍 اینجا «if» دقیقا مثل یه تابع عمل می‌کنه و مقدار نهایی رو به «message» نسبت میده.
🔁 دیگه نیازی به متغیر موقت یا «var» نداری، همه چیز یک‌خطی و تمیزه.

🎯 نکته مهم: حتما باید همه شاخه‌ها (if, else if, else) مقدار برگردونن، وگرنه کامپایل خطا میده.

🔥 یه قدم کوچیک به سمت کدنویسی حرفه‌ای‌تر با «Kotlin». از امروز تو پروژه‌هات از این قابلیت استفاده کن.

#Codeit #Android #Kotlin #Jetpack #KotlinTips #CleanCode #AndroidDev #Programming
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
🔁 حلقه‌های تکرار (For Loops) در کاتلین – ساده و عملی
اگر تازه کاتلین رو شروع کردی، یکی از اولین چیزایی که باید بلد باشی، حلقه for هستش. این حلقه بهت اجازه میده روی Range یا لیست‌ها قدم بزنی و کدت رو مرتب و کوتاه بنویسی.

کاربرد واقعی:
فرض کن یه لیست از اسم کاربرها داری و می‌خوای همشون رو توی کنسول چاپ کنی. به جای نوشتن چند خط تکراری، از for استفاده می‌کنی.

مثال کد (بدون placeholder):
fun main() {
// حلقه روی محدوده اعداد ۱ تا ۵
for (i in 1..5) {
println("Number: $i")
}

// حلقه روی لیست اسامی
val users = listOf("Ali", "Sara", "Reza")
for (user in users) {
println("Hello, $user!")
}
}

توضیح کد:
- 1..5 یه Range از ۱ تا ۵ می‌سازه و i هر بار یکی از این مقادیر رو می‌گیره.
- توی حلقه دوم، user به‌ترتیب عناصر لیست رو می‌گیره و چاپ می‌کنه.
- این روش کدت رو خواناتر و خطاهای تکرار دستی رو از بین می‌بره.

🎯 نتیجه‌گیری:
هر وقت نیاز به تکرار یه عمل روی مجموعه‌ای از داده‌ها داری، از for استفاده کن. این یکی از پایه‌ای‌ترین ابزارهای برنامه‌نویسیه که تو همه پروژه‌هات باهاش کار می‌کنی.

#Codeit #Android #Kotlin #Jetpack #Loops #Beginner #Programming
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2
🟢 پارامترهای پیش‌فرض (Default) و نام‌دار (Named) در کاتلین
خیلی وقت‌ها مجبور بودی برای هر حالت جدید، یه تابع جدا بنویسی؟ 🥱
کاتلین با Default Arguments و Named Arguments این مشکل رو یک‌بار برای همیشه حل کرده. 🎯

💡 ماجرا چیه؟
- پارامتر پیش‌فرض: می‌تونی برای آرگومان‌ها مقدار اولیه بذاری. اگه هنگام فراخوانی مقداری ندی، همون مقدار پیش‌فرض استفاده میشه.
- پارامتر نام‌دار: موقع صدا زدن تابع، اسم پارامتر رو مینویسی و بعد مقدار. دیگه مجبور نیستی ترتیب رو رعایت کنی!

🛠 مثال واقعی: فرض کن تابعی برای ارسال اعلان (Notification) می‌نویسی. خیلی از پارامترها مثل عنوان و بدنه همیشه فرق دارن، ولی متن پیش‌فرض و تاخیر شاید ثابت باشن.

👇 کد عملی:
fun sendNotification(
title: String,
body: String,
priority: Int = 1,
delayMs: Long = 0L
) {
// شبیه‌سازی ارسال نوتیفیکیشن
println("Sending: $title - $body (Priority=$priority, Delay=${delayMs}ms)")
}

// فراخوانی با مقادیر پیش‌فرض برخی پارامترها
sendNotification("سلام", "کد جدید اومد!")

// فراخوانی با اسم پارامتر و تغییر فقط delay
sendNotification("توجه", "به‌روزرسانی", delayMs = 5000L)


📊 توضیح کد:
- پارامتر priority و delayMs مقدار پیش‌فرض دارن.
- توی خط اول فقط title و body رو می‌دی، بقیه از پیش‌فرض استفاده میشه.
- توی خط دوم با استفاده از Named Argument فقط delayMs رو تغییر دادی و ترتیب مهم نیست.

🚀 یادت باشه:
این قابلیت باعث میشه توابعت انعطاف‌پذیر بشن و کد خواناتر و تمیزتری داشته باشی. دیگه نیازی به overload کردن تابع نیست!

#Codeit #Android #Kotlin #Jetpack #KotlinTips #CleanCode #MobileDev #Programming
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
🔍 یکی از پراستفاده‌ترین «Scope Functions» در «Kotlin» تابع «let» است.
اگر با متغیرهای «nullable» سروکار دارید، «let» کمک می‌کند بدون شلوغی کد، عملیات ایمن انجام دهید.

🔄 کاربرد اصلی: وقتی مقدار یک متغیر «nullable» را دارید و فقط در صورت غیر null بودن باید پردازش کنید.
اما «let» فقط برای null-check نیست؛ می‌توانید مقدار خروجی را هم تغییر دهید.

⚙️ مثال واقعی: گرفتن یک متن از کاربر و اگر خالی نبود، آن را به حروف بزرگ تبدیل کنیم.

کد زیر را ببینید:

val userInput: String? = getUserInput()

userInput?.let { text ->
val processed = text.uppercase()
textView.text = processed
processed // return value
}

🔹 در اینجا «let» فقط در صورتی اجرا می‌شود که «userInput» null نباشد.
🔹 داخل «let» به جای تکرار نام متغیر، از «it» یا یک نام دلخواه (مثل «text») استفاده می‌کنیم.
🔹 خروجی «let» آخرین عبارت داخل آن است (اینجا «processed»).

💡 نتیجه عملی: کد خوانا، ایمن و قابل نگهداری‌تر می‌شود.
از «let» برای زنجیره‌ای کردن عملیات روی اشیای nullable هم استفاده کنید.

#Codeit #Android #Kotlin #Jetpack #ScopeFunctions #KotlinTips #CleanCode #Programming
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1
لیست‌ها در «Kotlin» از پایه‌ای‌ترین مفاهیمی‌ان که هر اندروید دولوپری باید به‌خوبی بشناسهشون 🚀

🔹 فرق اصلی بین دو نوع لیست:
➡️ «MutableList» که می‌تونی بعد از ساختنش آیتم اضافه یا حذف کنی
➡️ «List» که فقط خواندنیه و تغییرناپذیره

🔸 مثال کاربردی:
فرض کن داری یه لیست از اسامی کاربرا رو تو یه «ViewModel» مدیریت می‌کنی. یه بار باید فقط نمایش بدی، یه بار هم باید بهش اضافه کنی.

کد ساده‌ای از تفاوت این دو رو ببین:

val immutableList: List<String> = listOf("Ali", "Sara")
// immutableList.add("Reza") // Error!

val mutableList: MutableList<String> = mutableListOf("Ali", "Sara")
mutableList.add("Reza") // کاملاً مجازه
println(mutableList) // [Ali, Sara, Reza]


📌 توضیح:
«immutableList» چون از نوع «List» هست، هیچ متد تغییردهنده‌ای نداره. اما «mutableList» از «MutableList» ساخته شده و متدهایی مثل «add», «remove» رو داره.

💡 نکته حرفه‌ای:
در برنامه‌نویسی اندروید با «Jetpack Compose» معمولاً از «StateFlow» یا «LiveData» با لیست‌های غیرقابل تغییر استفاده می‌کنن تا از بروز باگ‌های هم‌زمانی جلوگیری بشه. پس بهتره تا جایی که ممکنه از «List» استفاده کنی و فقط در صورت نیاز از «MutableList» بهره ببری.

برداشت عملی:
برای شروع هر پروژه‌ای، نوع لیست رو متناسب با نیازت انتخاب کن. اگه قرار نیست تغییر کنه، از «listOf» استفاده کن؛ در غیر این صورت «mutableListOf» رو به کار ببر.

#Codeit #Android #Kotlin #Jetpack #List #KotlinBasics #Programming
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1
📦 عملگرها در «Kotlin» فقط برای اعداد نیستند!
میتونی به کلاس‌های خودت یاد بدی که با علامت + یا == رفتار خاصی داشته باشن. به این میگن «Operator Overloading» 🤯

چرا به کار میاد؟
وقتی با مفاهیمی مثل مختصات، ماتریس یا تاریخ کار می‌کنی، استفاده از عملگرها کد رو خواناتر و طبیعی‌تر می‌کنه. دیگه نیازی به نوشتن point1.add(point2) نیست؛ کافیه بنویسی point1 + point2

💡 مثال عملی:
فرض کن یک کلاس Point داری که مختصات x و y رو ذخیره می‌کنه. می‌خوای دو نقطه رو با + جمع بزنی و نقطه جدیدی بدست بیاری.

data class Point(val x: Int, val y: Int) {
operator fun plus(other: Point): Point {
return Point(x + other.x, y + other.y)
}
}

fun main() {
val p1 = Point(2, 3)
val p2 = Point(4, 5)
val result = p1 + p2 // فراخوانی plus
println(result) // Point(x=6, y=8)
}


📝 توضیح:
با کلیدواژه operator به «Kotlin» می‌فهمونی که تابع plus برای عملگر + استفاده بشه. حالا هر جا p1 + p2 بنویسی، معادل p1.plus(p2) اجرا می‌شه.

🎯 کاربرد واقعی:
این قابلیت تو کتابخونه‌هایی مثل «Jetpack Compose» برای مدیریت مقادیر «Dp» یا «Offset» استفاده می‌شه. مثلاً offset1 + offset2 دو مختصات رو جمع می‌زنه.

🔑 نکته:
می‌تونی عملگرهای دیگه مثل -، *، []، == و in رو هم overload کنی. فقط کافیه تابع operator مناسب رو بنویسی.

#Codeit #Android #Kotlin #Jetpack #OperatorOverloading #CleanCode #Programming
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
📌 آنotation‌ها در «Kotlin» یک ابزار قدرتمند برای افزودن metadata به کد هستند.
🧠 به زبان ساده: annotation‌ها به کامپایلر، runtime یا فریمورک‌ها اطلاعات اضافی می‌دهند.
🎯 مثل «@Override» در جاوا یا «@Serializable» در «Kotlin Serialization».

🔧 می‌توانید annotation‌های سفارشی خود را بسازید.
📦 ابتدا یک annotation جدید تعریف می‌کنیم و با «@Retention» و «@Target» محدوده و زمان نگهداری آن را مشخص می‌کنیم.
💡 مثال: یک annotation برای فیلدهای JSON بسازیم:

@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD)
annotation class JsonField(val name: String)


🧩 حالا از آن در یک data class استفاده می‌کنیم:

data class User(
@JsonField("user_name")
val username: String,
@JsonField("user_age")
val age: Int
)


🔍 در runtime می‌توانیم این annotation را بخوانیم (مثلاً با reflection) تا نام واقعی فیلد در JSON را استخراج کنیم:

fun main() {
val field = User::class.java.declaredFields.find { it.name == "username" }
val annotation = field?.getAnnotation(JsonField::class.java)
println(annotation?.name) // خروجی: user_name
}


این کار باعث می‌شود کد شما تمیز، قابل توسعه و یکپارچه با کتابخانه‌های دیگر باشد.
🌟 «Annotations» پایه بسیاری از فریمورک‌های اندرویدی مثل «Room»، «Retrofit» و «Dagger» هستند.

#Codeit #Android #Kotlin #Jetpack #Annotations #Reflection #Programming
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
🧠 رفلکشن (Reflection) در «Kotlin» یکی از قدرتمندترین و در عین حال خطرناک‌ترین ابزارهاست.
اگر تا حالا خواستید توی runtime به ساختار کلاس‌ها دسترسی داشته باشید یا متدی رو بدون اسم دقیق صدا بزنید، وقتشه با اصولش آشنا بشید.

🔍 «Reflection» به شما اجازه میده نوع (Type) یک شیء، property‌ها، متدها و constructor‌هاش رو در لحظه بررسی کنید.
📌 کاربرد اصلیش توی کتابخونه‌هایی مثل «Retrofit» (برای خوندن annotation‌ها) یا «Room» هست.

💡 مثال واقعی: فرض کنید می‌خواید همه property‌های یک کلاس «DTO» (Data Transfer Object) رو که مقدارشون null نیست، به صورت خودکار لاگ کنید.

کد زیر با «KClass» و «memberProperties» این کار رو انجام میده:

import kotlin.reflect.full.memberProperties

data class UserDTO(val name: String?, val age: Int?, val email: String?)

fun logNonNullProperties(obj: Any) {
val kClass = obj::class
kClass.memberProperties.forEach { prop ->
val value = prop.getter.call(obj)
if (value != null) {
println("${prop.name}: $value")
}
}
}

fun main() {
val user = UserDTO("Ali", null, "ali@example.com")
logNonNullProperties(user)
// خروجی: name: Ali, email: ali@example.com
}


📝 توضیح:
«obj::class» به «KClass» دسترسی میده. «memberProperties» لیست property‌های کلاس رو برمی‌گردونه. با «prop.getter.call» مقدار runtime رو می‌گیریم.

🛠️ نکته امنیتی:
رفلکشن توی «Android» می‌تونه performance رو تحت تأثیر بذاره؛ اگه Provider لیست‌ش رو حذف کنه (ProGuard/R8) ممکنه خطا بده. پس فقط برای کتابخونه‌های ضروری و وقتی راه بهتری نیست استفاده کنید.

🎯 برداشت عملی:
رفلکشن کار Serialization/Deserialization سفارشی، تزریق وابستگی (Dependency Injection) و Annotation Processor‌ها رو ساده می‌کنه.

#Codeit #Android #Kotlin #Reflection #AdvancedKotlin #Jetpack #Programming
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥2
🚨 همیشه یک خطای کوچک کل پروژه رو خراب می‌کنه؟

اگه با «Coroutines» کار کرده باشی، می‌دونی که شکست یک فرزند توی «Job» عادی می‌تونه کل «Scope» رو نابود کنه. 😰

اما «SupervisorJob» دقیقاً برای همین ساخته شده؛ بهش بگو: «این کارها مستقل‌ان، اگه یکی افتاد بقیه ادامه بدن.»

کاربرد واقعی: وقتی چند تا «Network Request» موازی داری و یکی خطا می‌ده، بقیه نباید کنسل بشن. مثلاً دانلود سه عکس جداگانه. 🖼️

حالا ببینیم کدش چطوریه. سنگین ولی ساده:

val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)

scope.launch {
delay(100)
throw RuntimeException("child 1 failed")
}

scope.launch {
delay(200)
println("child 2 finished successfully")
}


توی کد بالا فرزند اول خطا می‌ده ولی فرزند دوم بدون مشکل ادامه می‌ده و تموم می‌شه. اگه از «Job» معمولی استفاده می‌کردی، فرزند دوم هم کنسل می‌شد. 🤝

نکته مهم: برای «ViewModel» هم می‌تونی از «SupervisorJob» استفاده کنی تا خطای یکی از تسک‌ها بقیه رو نکشه. فقط یادت باشه مدیریت خطا رو جدی بگیری. 🧠

در نهایت: وقتی کارهای موازی مستقل داری، «SupervisorJob» انتخاب درسته. ✌️

#Codeit #Android #Kotlin #Jetpack #Coroutines #SupervisorJob #KotlinFlow #Programming

🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥3
«Coroutines» بخش ۸؛ این بار سراغ یکی از پیچیدهترین مباحث رفتیم: مدیریت خطا! 🧯

وقتی یک «Coroutine» خطا بدهد، رفتارش با «try/catch» معمولی فرق دارد؛ خطا میتونه کل ساختار والد رو از بین ببره! 💥

مثال: یک «ViewModel» چند «Coroutine» موازی داره؛ اگر یکی خطا بده، بقیه هم باید ادامه بدن. 🧩

برای همین به «SupervisorJob» نیاز داریم تا خطای هر فرزند جداگانه مدیریت بشه. 🔧

کد زیر رو ببینید:

val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)

scope.launch {
delay(100)
throw RuntimeException("خطا در فرزند اول")
}

scope.launch {
delay(300)
println("فرزند دوم هنوز فعال است")
}


اینجا «SupervisorJob» باعث میشه خطای فرزند اول، فرزند دوم رو از بین نبره. 📝

نکته مهم: «CoroutineExceptionHandler» هم برای گرفتن خطاهای نهایی و لاگکردنشون استفاده میشه. ⚠️

پس برای کارهای مستقل از «SupervisorJob» و برای کارهای وابسته از «Job» معمولی استفاده کنید. 🚀

«Codeit» رو دنبال کنید تا بخشهای بعدی رو از دست ندید! 📚

#Codeit #Android #Kotlin #Jetpack #Coroutines #Programming #KotlinFlow

🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
راستش رو بخوای، «Cancellation» توی «Coroutines» برخلاف تصور اکثرا، یه مکانیزم همکارانهست نه اجبار! 🎯
وقتی یه «Coroutine» رو لغو میکنی، فوراً متوقف نمیشه؛ فقط یه «CancellationException» میگیره و باید خودش همکاری کنه تا تموم شه. 🤝
اگه کدت به این موضوع اهمیت نده، کارهای سنگین بعد از خروج از صفحه هم ادامه پیدا میکنن و منابع رو میبلعن! 🔥📱
توی «Android» با «viewModelScope» این کار خودکاره، ولی توی «Coroutine»های شخصیسازیشده باید خودت مدیریت کنی. 💡
توابعی مثل «delay» و «withContext» خودشون قابل «Cancellation» هستن؛ ولی کدهای سنگین مثل حلقهی پردازش تصویر، هیچ واکنشی نشون نمیدن. 😬
برای همین توی حلقهها از «ensureActive» یا بررسی «isActive» استفاده میکنیم. 🧠
یه مثال پیشرفته از همکاری حرفهای:

val scope = CoroutineScope(Dispatchers.Default)

val job = scope.launch {
try {
repeat(1000) { index ->
ensureActive()
saveBitmapToCache(index)
}
} catch (e: CancellationException) {
withContext(NonCancellable) {
clearCache()
}
throw e
}
}

job.cancel()
job.join()


«ensureActive» مطمئن میشه هر مرحله قبل از ادامه، وضعیتش رو چک کنه؛ بعد توی «catch» با «NonCancellable» کارهای تمیزکاری مثل بستن «File» یا «Database» رو انجام میدیم.
دقت کن «CancellationException» رو همیشه دوباره «throw» کن و هرگز قورتش نده؛ وگرنه کار ادامه پیدا میکنه! 🚨
جمعبندی: بعد از «cancel» حتماً «join» هم صدا بزن تا مطمئن شی واقعاً تموم شده.
با این الگو، دیگه نگران «Memory Leak» و حافظهی هدررفته نخواهی بود. 🚀

#Codeit #Android #Kotlin #Jetpack #Coroutines #Cancellation #KotlinAdvanced #Programming
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
⏱️ تا حالا شده یه عملیات دیتابیس، انقدر طول بکشه که کاربر از برنامه بزنه بیرون؟
اینجاست که «Timeouts» توی «Coroutines» نجاتت میده! 🚀

توی بخش چهاردهم، قراره یاد بگیریم چطور با «withTimeout» و «withTimeoutOrNull» جلوی آویزون موندن برنامه رو بگیریم.

🔹 مشکل: یه فراخوانی شبکه ممکنه هیچوقت جواب نده و برنامه همیشه منتظر بمونه.
🔹 راهحل: یه مهلت مشخص میکنیم؛ اگه تموم نشد، ادامه میدیم یا خطا میگیریم.

💡 کاربرد واقعی: مثلاً در یه اپ خرید، اگه سرور ظرف ۵ ثانیه جواب نداد، به کاربر پیام «اتصال برقرار نشد» نشون بدیم.

اول بذارید یه نمونه کد ساده ببینیم:

fun main() = runBlocking {
val result = withTimeoutOrNull(5000L) {
fetchDataFromServer()
"Done"
}
if (result == null) {
println("درخواست لغو شد؛ دوباره تلاش کنید.")
} else {
println(result)
}
}


📌 این کد یعنی: حداکثر ۵ ثانیه صبر کن؛ اگه «fetchDataFromServer» تموم نشد، به جای خطا، «null» برگردون.
به این ترتیب هم برنامه کرش نمیکنه، هم کاربر بیپاسخ نمیمونه.

📌 اگه به خطا نیاز داری، از «withTimeout» استفاده کن؛ اگه بخوای حالت خالی رو مدیریت کنی، «withTimeoutOrNull» مناسبتره.

نکته مهم: «Timeouts» مخصوص عملیاتهای طولانی مثل شبکه، دیتابیس یا «File I/O» هست و جلوی قفل شدن «UI» رو میگیره.

تمرین کن و توی پروژههات از «withTimeoutOrNull» برای فراخوانیهای شبکه استفاده کن.

#Codeit #Android #Kotlin #Jetpack #Coroutines #Timeouts #Programming #MobileDev
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
🎯 «Modifier» مهمترین ابزار شخصیسازی در «Jetpack Compose» است؛ بدون آن فقط یک صفحه خالی دارید!
🛠 «Modifier» مثل یک جعبه ابزار میماند که میتوانید روی هر «Composable» اعمال کنید.
📏 با آن فاصله، رنگ، کلیک، چرخش، اندازه و صدها ویژگی دیگر را تنظیم میکنید.
🔗 نکته طلایی: «Modifier» ها زنجیرهای میشوند؛ ترتیب آنها در نتیجه نهایی تأثیر مستقیم دارد.
📰 مثال واقعی: یک کارت خبری که پسزمینه دارد، قابل کلیک است و دورتادور آن فاصله گذاشتهایم.
کد زیر را ببینید:

Column(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth()
.background(Color.LightGray)
.clickable { openArticle() }
.padding(8.dp)
) {
Text(text = "Hello Codeit! 📰")
}


🧠 این کد ابتدا ۱۶ واحد فاصله بیرونی میگذارد، بعد عرض را کامل میکند و رنگ پسزمینه را روشن میسازد.
👆 سپس کامپوننت را قابل کلیک کرده و در نهایت ۸ واحد فاصله داخلی به محتوا میدهد.
⚠️ نکته مهم: اگر ترتیب «background» و «clickable» را عوض کنید، افکت کلیک زیر رنگ قرار میگیرد!
✍️ تمرین: همین مسیر را روی یک «Image» هم امتحان کنید و نتیجه را ببینید.
💪 با تکرار این الگو، بدنه «Modifier» برایتان کاملاً عادی میشود.

#Codeit #Android #Kotlin #Jetpack #Compose #Modifier #Programming #Learn
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2🔥1🥰1
🎯 چرا «ثبات قدم» از «استعداد» در برنامه‌نویسی مهم‌تر است؟

خیلی‌ها فکر می‌کنند برنامه‌نویس شدن نیاز به نابغه بودن داره. اما واقعیت چیز دیگه‌ای هست.

در دنیای واقعی، برنامه‌نویسی یک مهارت عملی است، نه یک آزمون هوش. مثل یادگیری رانندگی یا آشپزی، هر روز تمرین کنی جلو می‌ری. 🏃‍♂️

تازه‌کارها اشتباه می‌کنند:
روزی ۸ ساعت کدنویسی، بعد یک هفته خستگی و ترک
روزی ۳۰ دقیقه کدنویسی منظم، برای یک سال کامل

ثبات یعنی حتی وقتی حوصله نداری، بنشینی و یک خط کد بزنی. این عادت تو رو از ۹۰ درصد بقیه جدا می‌کنه. 💪

در دنیای واقعی، کارفرماها دنبال کسی هستند که پروژه رو تموم کنه، نه کسی که الگوریتم‌های پیچیده رو از حفظ باشه.

تجربه شخصی: خیلی از برنامه‌نویسان موفق نه استعداد خاصی داشتند، نه ضریب هوشی بالا. فقط هر روز پای کد نشستند. 📈

توصیه عملی:
یک چالش ۳۰ روزه برای خودت تعریف کن. هر روز یک قطعه کد کوچک بنویس. حتی اگه ۵ خط باشه. بعد از یک ماه نتیجه رو می‌بینی. 🎯

این رو همیشه یادت باشه:
استعداد شروع خوبی است، اما «ثبات قدم» تو رو به خط پایان می‌رسونه. 🏁

#Codeit #Android #Kotlin #Jetpack #Consistency #Mindset #Programming #Growth

🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥21