| کانال توسعهدهندگان اندروید |
Kanalga Telegram’da o‘tish
⭕️ کانال توسعهدهندگان اندروید دولوپیکس 💠 دولوپیکس | جامعه توسعهدهندگان ایرانی 💎 @Developix 🚀 Developix.ir 📌 پشتیبانی و تبلیغات: @DevelopixSupport
Ko'proq ko'rsatish1 724
Obunachilar
-124 soatlar
-97 kun
-730 kun
Ma'lumotlar yuklanmoqda
O'xshash kanallar
Ma'lumot yo'q
Muammo bormi? Iltimos, sahifani yangilang yoki bizning qo'llab-quvvatlash boshqaruvchimizga murojaat qiling>.
Taglar buluti
Ma'lumot yo'q
Muammo bormi? Iltimos, sahifani yangilang yoki bizning qo'llab-quvvatlash boshqaruvchimizga murojaat qiling>.
Kirish va chiqish esdaliklari
---
---
---
---
---
---
Obunachilarni jalb qilish
Oktabr '26Okt '26
Oktabr '26
+327
0 kanalda
Sentabr '260
0 kanalda
Get PRO
Avgust '260
0 kanalda
Get PRO
Iyul '260
0 kanalda
Get PRO
Iyun '260
0 kanalda
Get PRO
May '260
0 kanalda
Get PRO
Aprel '260
0 kanalda
Get PRO
Mart '260
0 kanalda
Get PRO
Fevral '260
0 kanalda
Get PRO
Yanvar '260
0 kanalda
Get PRO
Dekabr '250
0 kanalda
Get PRO
Noyabr '250
0 kanalda
Get PRO
Oktabr '250
0 kanalda
Get PRO
Sentabr '250
0 kanalda
Get PRO
Avgust '250
0 kanalda
Get PRO
Iyul '250
0 kanalda
Get PRO
Iyun '250
0 kanalda
Get PRO
May '250
0 kanalda
Get PRO
Aprel '250
0 kanalda
Get PRO
Mart '250
0 kanalda
Get PRO
Fevral '250
0 kanalda
Get PRO
Yanvar '250
0 kanalda
Get PRO
Dekabr '240
0 kanalda
Get PRO
Noyabr '240
0 kanalda
Get PRO
Oktabr '240
0 kanalda
Get PRO
Sentabr '24
+55
0 kanalda
Get PRO
Avgust '24
+82
0 kanalda
Get PRO
Iyul '24
+105
1 kanalda
Get PRO
Iyun '24
+123
0 kanalda
Get PRO
May '24
+46
0 kanalda
Get PRO
Aprel '24
+89
0 kanalda
Get PRO
Mart '24
+108
0 kanalda
Get PRO
Fevral '24
+116
0 kanalda
Get PRO
Yanvar '24
+1 176
0 kanalda
| Sana | Obunachilarni jalb qilish | Esdaliklar | Kanallar | |
| 29 Oktabr | 0 | |||
| 28 Oktabr | +2 | |||
| 27 Oktabr | 0 | |||
| 26 Oktabr | +1 | |||
| 25 Oktabr | 0 | |||
| 24 Oktabr | +1 | |||
| 23 Oktabr | +1 | |||
| 22 Oktabr | +2 | |||
| 21 Oktabr | +2 | |||
| 20 Oktabr | +2 | |||
| 19 Oktabr | +2 | |||
| 18 Oktabr | 0 | |||
| 17 Oktabr | 0 | |||
| 16 Oktabr | +1 | |||
| 15 Oktabr | 0 | |||
| 14 Oktabr | 0 | |||
| 13 Oktabr | +2 | |||
| 12 Oktabr | +5 | |||
| 11 Oktabr | 0 |
Kanal postlari
📰 گوگل ثبتنام در برنامه فروشگاههای اپلیکیشن شخص ثالث اندروید را با هزینه ۱۰ هزار دلار آغاز کرد
گوگل پذیرش درخواستها برای برنامه «فروشگاههای اپلیکیشن ثبتشده» را آغاز کرده است؛ برنامهای با هدف سادهسازی نصب و بهروزرسانی اپلیکیشنها از فروشگاههای شخص ثالث تأییدشده در دستگاههای اندرویدی. این طرح، در صورت استفاده کاربران از نسخه سازگار اندروید، مراحل نصب را کاهش میدهد و امکان بهروزرسانی در پسزمینه را فراهم میکند. فروشگاههای واجد شرایط باید الزامات مربوط به مالکیت فکری، محتوای غیرقانونی، سیاستهای حریم خصوصی و امنیت را رعایت کنند. متقاضیان باید مدارک انطباق با الزامات و نسخههایی از اپلیکیشنها را ارائه دهند و سالانه ۱۰ هزار دلار بپردازند.
🔖 #news
💎 @DevelopixAndroid
| 2 | 📏 اندازهٔ View را زودتر از موعد نخوان!
گاهی داخل onCreate یا onViewCreated، مقدار width یک View صفر است؛ نه بهخاطر خراب بودن رابط کاربری، بلکه چون مرحلهٔ layout هنوز انجام نشده.
💡 برای کاری که به اندازهٔ واقعی View وابسته است، از doOnLayout در AndroidX Core استفاده کن. مثلاً این تابع اندازهٔ یک View را بعد از آمادهشدن layout در Logcat ثبت میکند:
import android.util.Log
import android.view.View
import androidx.core.view.doOnLayout
fun logSize(view: View) {
view.doOnLayout {
Log.d("ViewSize", "${it.width} x ${it.height}")
}
}
✅ اگر View قبلاً layout شده باشد و درخواست layout تازهای نداشته باشد، کد همان لحظه اجرا میشود؛ در غیر این صورت، تا layout بعدی صبر میکند. این callback یکبار اجرا میشود، نه با هر تغییر اندازه.
⚠️ برای این کار سراغ تأخیر ثابت با postDelayed نرو؛ سرعت دستگاه تضمینشده نیست. برای انیمیشن یا محاسبات وابسته به اندازه، این روش را جایگزین حدسزدن زمان کن.
📚 مستندات رسمی doOnLayout
🔖 #Android #اندروید #Android #Kotlin #AndroidX #UI
👤 Developix
💎 Channel: @DevelopixAndroid | 278 |
| 3 | 📰 لجر از اتم، دستگاه رمزارزی جدید اندرویدی با نمایشگر لمسی، رونمایی کرد
لجر دستگاه اندرویدی لمسی اتم را معرفی کرده است؛ دستگاهی برای تراکنشهای رمزارزی، پیامرسانی رمزگذاریشده و تأیید اقدامات عاملهای هوش مصنوعی. این دستگاه به تراشه امنیتی Secure Element، نمایشگر ۶٫۷۷ اینچی OLED، باتری ۴۰۰۰ میلیآمپرساعتی و کلیدی فیزیکی برای قطع برق دوربین و میکروفون مجهز است. اتم با اپلیکیشن ازپیشنصبشده Seeker متعلق به سولانا موبایل عرضه خواهد شد. امکان رزرو فراهم شده، اما لجر هنوز قیمت یا تاریخ عرضه را اعلام نکرده است.
🔖 #news
💎 @DevelopixAndroid | 384 |
| 4 | 🔥 پروژه: ویپیان چندموتورهٔ MLM
برای دیدن یک پروژهٔ شبکه با Kotlin و Jetpack Compose، اپلیکیشن اندرویدی MLM VPN ارزش بررسی دارد؛ چند موتور مثل Xray، WARP، Tor و OpenVPN را کنار هم آورده است.
نکتهٔ متمایزش موتور تطبیقی MLM است که هر اپ را از مسیر مناسب خودش عبور میدهد. پنلهای Cloudflare، ابزار Config Studio و قابلیت game booster هم در پروژه وجود دارند.
برای مطالعهٔ ساختار یک VPN چندموتوره و مسیریابی بهازای هر اپ، سری به کد پروژه بزنید؛ نمونهٔ جالبی برای یادگیری توسعهٔ ابزارهای شبکه است.
⭐️ 98 stars this week
🔖 #Android #اندروید #Android #Kotlin #Jetpack_Compose
💎 @DevelopixAndroid | 440 |
| 5 | تست بهتر با تزریق Dispatcher 🧪
وقتی در یک Repository مستقیم از Dispatchers.IO استفاده میکنیم، انتخاب محل اجرای کار را به همان کلاس گره میزنیم. در اجرا مشکلی دیده نمیشود، اما در تست، بخشی از کار از کنترل زمانبندی تست خارج میشود. نتیجه ممکن است تستی کند یا ناپایدار باشد.
یک تغییر کوچک این وابستگی را آشکار میکند: به جای انتخاب Dispatcher در بدنه، آن را از سازنده بگیریم. این کاربردی از Dependency Injection است؛ برای شروع هم نیازی به Hilt نداریم.
نمونهٔ ساده در لایهٔ داده 👇
interface NameStore {
fun read(): String
}
class NameRepository(
private val store: NameStore,
private val io: CoroutineDispatcher
) {
suspend fun load(): String =
withContext(io) { store.read() }
}
در این مثال، خواندن داده یک عملیات blocking است. در برنامه، نمونه را با Dispatchers.IO میسازیم تا این کار روی نخ اصلی انجام نشود. در تست، یک Dispatcher قابلکنترل میدهیم:
@Test
fun loadsName() = runTest {
val store = object : NameStore {
override fun read() = "Sara"
}
val repo = NameRepository(
store,
StandardTestDispatcher(testScheduler)
)
assertEquals("Sara", repo.load())
}
این نمونه از ابزارهای kotlinx-coroutines-test استفاده میکند. با اشتراک همان testScheduler، اجرای coroutine در محدودهٔ زمانبندی تست باقی میماند؛ دیگر برای هماهنگی به خواباندن نخ و انتظار حدسی نیاز نداریم.
یک مرز مهم ⚠️
هر تابع suspend به انتقال روی IO نیاز ندارد. بسیاری از APIهای asynchronous خودشان اجرای مناسب را مدیریت میکنند. این الگو برای کاری مفید است که واقعاً blocking است؛ افزودن بیدلیل withContext فقط مسیر کد را پیچیده میکند.
همچنین این تغییر بهتنهایی Dispatcher اصلیِ viewModelScope را در تست جایگزین نمیکند؛ آن موضوع تنظیم جداگانه دارد.
📚 راهنمای رسمی تزریق Dispatcher
🌱 از یک Repository شروع کنید؛ جدا کردن تصمیم اجرای کار از منطق داده، قدمی کوچک برای کدی قابلتستتر است.
🔖 #Android #اندروید #Android #Kotlin #Coroutines #Dependency_Injection #Testing
👤 Developix
💎 Channel: @DevelopixAndroid | 430 |
| 6 | وقتی با Room کار میکنی، اجرای Query روی Main Thread هم ریسک ANR داره هم عملاً مزیتهای Room رو از بین میبره.
تو کد اول، تابع DAO یه suspend نیست و مستقیم روی رشتهٔ اصلی صدا زده شده؛ روی دیتای زیاد، خیلی راحت UI رو قفل میکنه.
تو کد دوم، هم تو DAO از suspend استفاده شده، هم در ViewModel توی viewModelScope و Dispatchers.IO صدا زده شده؛ اینطوری هم کد تمیزتره، هم Threading درست انجام میشه و خبری از فریز شدن UI نیست.
خلاصه: هر کاری که بوی I/O میده (Room، Network، File…) رو همیشه بیرون از Main Thread انجام بده؛ مخصوصاً تو ViewModel با viewModelScope و Dispatchers.IO.
🔖 #Android #اندروید
👤 Developix
💎 Channel: @DevelopixAndroid | 394 |
| 7 | 🔥 پروژه: ابزار و مودهای ضروری اندروید (Essentials)
یه پروژه متنباز برای اندرویدبازها؛ مجموعهای از ابزار و مودهایی که کارهای ریز و خستهکننده روزمره روی دستگاههاتون رو سادهتر میکند 🔧
تو Essentials میتوانی اسکریپتها و تنظیمات آماده پیدا کنی تا راحتتر روی دستگاههات تست، دیباگ و انواع تغییرات سیستمی را انجام بدهی، بدون اینکه هر بار از صفر همهچیز را کانفیگ کنی.
اگر با روت، کاستوم رام یا توسعه جدی روی دیوایس واقعی سر و کار داری، یه نگاه بهش میارزه.
⭐️ 105 stars this week
🔖 #Android #اندروید #اندروید #Android #توسعهدهندگان_اندروید
💎 @DevelopixAndroid | 447 |
| 8 | ❓ خروجی این کد Kotlin چیست؟
در این مثال از Sequence در Kotlin استفاده شده که ارزیابی تنبل (Lazy) دارد. دقت کن که چه زمانی هر بخش اجرا میشود و ترتیب چاپ لاگها را دقیق در نظر بگیر.
خروجی نهایی اجرای این برنامه را (دقیقاً همان چیزی که روی خروجی استاندارد چاپ میشود، خطبهخط) بنویس.
🔖 #Android #اندروید
👤 Developix
💎 Channel: @DevelopixAndroid | 565 |
| 9 | 📱 تو اپهای اندرویدی مدرن، تقریبا همهچیز وابسته به درخواست شبکه و دیتای async شده. اگر این درخواستها درست مدیریت نشه، هم Memory Leak میآید، هم کرش، هم UI لگ میزند.
توی این پست میرویم سراغ یه الگوی تمیز و واقعی برای هندلکردن درخواستهای شبکه با Kotlin Coroutines و ViewModel، دقیقا بر اساس راهنمای رسمی Android:
android.com/topic/libraries/architecture/coroutines
🔥 ایده کلی
✅ منطق async داخل ViewModel
✅ استفاده از viewModelScope برای مدیریت Lifecycle
✅ برگردوندن State به UI (مثلا با StateFlow)
اینطوری:
• وقتی Activity/Fragment نابود میشود، coroutineها خودکار cancel میشوند.
• نیاز به Callback جهنمی و AsyncTask قدیمی نیست.
• تستکردن ViewModel خیلی راحتتر میشود.
مثال واقعی: لود لیست از API و نمایش Loading/Error
تو این مثال:
• یه Repository فرضی داریم که از سرور دیتا میگیرد.
• توی ViewModel با viewModelScope.launch صداش میزنیم.
• نتیجه رو با یه sealed class به UI میفرستیم.
// ViewModel + Coroutines + StateFlow
class UserViewModel(
private val repository: UserRepository
) : ViewModel() {
sealed class UiState {
object Loading : UiState()
data class Success(val users: List<User>) : UiState()
data class Error(val message: String) : UiState()
}
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState: StateFlow<UiState> = _uiState
init {
loadUsers()
}
fun loadUsers() {
viewModelScope.launch {
_uiState.value = UiState.Loading
try {
val result = repository.getUsers()
_uiState.value = UiState.Success(result)
} catch (e: Exception) {
_uiState.value = UiState.Error(e.message ?: "Unknown error")
}
}
}
}
برای سمت UI (چه View قدیمی، چه Jetpack Compose) کافیه روی uiState subscribe کنی و سه حالت Loading/Success/Error رو render کنی. نمونه رسمی Compose رو هم میشود اینجا دید:
android.com/jetpack/compose/state
🎯 چند نکته ریز ولی مهم
• همیشه Coroutine اصلی رو توی ViewModel نگهدار، نه تو Activity؛ اینطوری منطق از UI جدا میشود.
• Exceptionها رو بگیر و تبدیل به State قابلنمایش کن، نه اینکه بذاری تا بالا کرش کند.
• برای درخواستهای تکراری (مثلا سرچ) میتوانی از Flow و اپراتورهایی مثل debounce استفاده کنی.
این الگو، پایه خیلی از معماریهای تمیز (MVVM + Coroutines + Flow) توی پروژههای جدی اندروید است. از یه اسکرین ساده شروع کن، همون رو با این روش بازنویسی کن و تفاوت خوانایی و پایداری رو ببین 🙌
🔖 #Android #اندروید #Android #Kotlin #Coroutines #ViewModel #StateFlow #Jetpack #MVVM
👤 Developix
💎 Channel: @DevelopixAndroid | 645 |
| 10 | 🔥 پروژه: سرور کمیک خودمیزبان Komga
برای تست اپهای کتابخوان/مانگا ریدر روی اندروید، داشتن یک سرور محتوای واقعی خیلی کمک میکند 📚
Komga یک media server خودمیزبان برای کامیک، مانگا، مجله و eBook است؛ با وباپ، مدیریت کاربر، یادآوری موقعیت مطالعه و تگگذاری.
نکته جذاب برای ما اندرویدیها: API و خروجی OPDS دارد، یعنی میتوانی کل بکاند کتابخانه را به Komga بسپاری و در اپ فقط روی UX و ریدر تمرکز کنی.
کد منبع در GitHub باز است؛ برای ساخت پروتوتایپ یک reader جدی، گزینهی تمیزی است.
⭐️ 32 stars this week
🔖 #Android #اندروید #اندروید #Android #توسعهدهندگان_اندروید
💎 @DevelopixAndroid | 464 |
| 11 | کتابخونه OkHttp یکی از پایهایترین ابزارها برای شبکه توی اندرویده و زیر hood خیلی از کتابخونههای معروف مثل Retrofit هم ازش استفاده میکنن 🚀
با OkHttp میتونی:
• اتصال HTTP/HTTPS پایدار و سریع داشته باشی (HTTP/2, pooling)
• Cache سمت کلاینت رو خیلی راحت هندل کنی
• Timeoutها، Retry و Redirect رو ریز تنظیم کنی
• با Interceptorها، لاگگیری و Auth رو تمیز پیادهسازی کنی
نمونه استفاده ساده در Kotlin:
val client = OkHttpClient()
val request = Request.Builder()
.url("https://api.example.com/users")
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
// handle error
}
override fun onResponse(call: Call, response: Response) {
val body = response.body?.string()
// parse body
}
})
برای debug، حتما از Logging Interceptor استفاده کن تا راحتتر Request/Responseها رو ببینی 👍
Docs و سورس رسمی:
Docs
GitHub
امتحانش کن، مخصوصا اگه میخوای کنترل ریز روی لایه شبکه بدون اضافهکاری اضافی داشته باشی ⚙️
🔖 #Android #اندروید #Android #OkHttp #Networking #Kotlin #Java
👤 Developix
💎 Channel: @DevelopixAndroid | 659 |
| 12 | در کد زیر یک Memory Leak و یک Anti Pattern مربوط به استفاده از Handler در یک Activity وجود دارد:
class MainActivity : AppCompatActivity() {
private val handler = Handler(Looper.getMainLooper())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
handler.postDelayed({
// استفاده مستقیم از this (Activity) بعد از تاخیر طولانی
Toast.makeText(this, "Done", Toast.LENGTH_LONG).show()
}, 60_000)
}
}
در این نمونه، چه چیزی باید اصلاح شود تا هم Memory Leak رخ ندهد و هم الگوی استفاده از Handler در Activity صحیح باشد؟
🔖 #Android #اندروید
👤 Developix
💎 Channel: @DevelopixAndroid | 705 |
| 13 | 🧩 استفادهی امن از ViewBinding در Fragment
یکی از منبعهای معمول Memory Leak توی اندروید، نگهداشتن reference به view بعد از onDestroyView() توی Fragment هست. برای حل تمیز این مشکل، استفادهی درست از ViewBinding کمک خیلی بزرگی میکند. 🙂
ایدهی اصلی: توی Fragment فقط تا وقتی view زنده است به binding دسترسی داشته باش و بعد از onDestroyView() حتماً nullش کن.
class SampleFragment : Fragment(R.layout.fragment_sample) {
private var _binding: FragmentSampleBinding? = null
private val binding get() = _binding!!
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentSampleBinding.bind(view)
binding.textView.text = "Hello ViewBinding"
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
✨ با این الگو:
• از Memory Leak جلوگیری میشود.
• کد تمیزتر از findViewById میماند.
• Null-safety کوتلین را واقعاً استفاده میکنی.
برای جزئیات بیشتر:
مرجع رسمی ViewBinding در Fragment
امتحان این الگو توی همهی Fragment های جدید، ساختار پروژه را خیلی پایدار و قابلاعتمادتر میکند. 🚀
🔖 #Android #اندروید #Android #ViewBinding #Fragment #Kotlin #Memory_Leak #BestPractice
👤 Developix
💎 Channel: @DevelopixAndroid | 710 |
| 14 | ViewModel بهعنوان Single Source of Truth در MVVM 🧠
یکی از مهمترین ایدهها در معماری تمیز اندروید اینه که UI فقط نمایشدهندهٔ state باشه، نه محاسبهکنندهٔ اون. تو MVVM، بهترین جا برای نگهداشتن این state، همون ViewModel هست؛ یعنی تبدیلش کنیم به یک Single Source of Truth برای صفحه. ✅
وقتی state صفحه تو چند جا پخش میشه (Fragment، Adapter، ViewModel، حتی SharedPreferences مستقیم تو UI)، کد هم شکننده میشه، هم تستنشدنی. راهحل سادهاش: همهٔ state صفحه فقط در ViewModel.
📌 ایدهٔ اصلی:
- فقط ViewModel دادهٔ نهایی قابل نمایش رو نگه میداره
- UI فقط collect / observe میکنه و رندر میکنه
- هر اکشن کاربر تبدیل میشه به یک متد روی ViewModel
data class UiState(
val isLoading: Boolean = false,
val userName: String? = null,
val errorMessage: String? = null
)
class ProfileViewModel(
private val repo: UserRepository
) : ViewModel() {
private val _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState
fun loadProfile() {
viewModelScope.launch {
_uiState.value = _uiState.value.copy(isLoading = true)
runCatching { repo.getUser() }
.onSuccess { user ->
_uiState.value = UiState(
isLoading = false,
userName = user.name
)
}
.onFailure { e ->
_uiState.value = UiState(
isLoading = false,
errorMessage = e.message
)
}
}
}
}
حالا تو Compose، خیلی تمیز فقط state رو میخونیم و UI رو براساسش میسازیم 👇
@Composable
fun ProfileScreen(
viewModel: ProfileViewModel = hiltViewModel()
) {
val state by viewModel.uiState.collectAsState()
when {
state.isLoading -> LoadingView()
state.errorMessage != null -> ErrorView(state.errorMessage)
else -> UserView(name = state.userName.orEmpty())
}
}
🎯 چند نکتهٔ کاربردی:
- fieldهای پراکنده تو Fragment (مثل var isLoading) رو حذف کن و توی UiState جمع کن
- از نوعهای immutable (مثل data class) استفاده کن تا state شفاف و قابل تست بمونه
- با این ساختار، تست ViewModel فقط یه test روی UiState میشه، بدون نیاز به Android framework
برای مطالعهٔ بیشتر، مستند رسمی ViewModel و State در Compose تو سایت Android Developers خیلی کمک میکنه:
ViewModel
State در Compose
قدمهای کوچیک مثل تبدیل ViewModel به Single Source of Truth، کمکم پروژه رو از یک کد شکننده به یک کد قابل نگهداری و مقیاسپذیر تبدیل میکنه. امروز روی فقط یک صفحه این refactor رو اجرا کن و تفاوت خوانایی و تستپذیری رو ببین 🌱
🔖 #Android #اندروید #Android #MVVM #ViewModel #StateFlow #Jetpack_Compose #Clean_Architecture #Kotlin
👤 Developix
💎 Channel: @DevelopixAndroid | 699 |
| 15 | ⭕️ یک سوال برای Kotlinکارهای Android:
به خروجی این کد Kotlin که از Coroutines با runBlocking و launch استفاده میکند دقت کنید.
خروجی دقیق برنامه (با در نظر گرفتن ترتیب چاپ) چه خواهد بود؟
پاسخ را دقیقا همانطور که در خروجی Console چاپ میشود بنویسید.
🔖 #Android #اندروید
👤 Developix
💎 Channel: @DevelopixAndroid | 750 |
| 16 | در نمونهکد بالا در هنگام گوشدادن به تغییرات UI با استفاده از Flow، هر بار مقدار جدید میرسد، همهٔ listenerهای قدیمی بدون لغو شدن روی همان view ثبت میشوند. این الگو علاوه بر ایجاد Memory Leak، میتواند باعث تکرار غیرضروری کارها و افت کارایی شود. در نسخهٔ اصلاحشده با استفاده از Lifecycle.repeatOnLifecycle و collectLatest، هم جمعکنندهها به چرخهٔ حیات Fragment یا Activity گره میخورند و هم در صورت رسیدن مقدار جدید، بلاک قبلی بهدرستی لغو میشود. در سناریوهای real-time مانند بهروزرسانی لیست یا status کاربران، این روش، مصرف مموری را کاهش داده و از اجرای همزمان چند کار مشابه جلوگیری میکند.
🔖 #Android #اندروید
👤 Developix
💎 Channel: @DevelopixAndroid | 923 |
| 17 | کتابخونه امروز: Hilt از Jetpack برای Dependency Injection تو اندروید 🚀
Hilt روی Dagger ساخته شده و کار DI رو برای Android Devها خیلی ساده میکنه؛ مخصوصاً وقتی چند Activity، Fragment، ViewModel و Service داری و نمیخوای دستی objectها رو پاس بدی یا Singletonهای شلخته بسازی.
✨ چرا Hilt؟
• حذف مقدار زیادی boilerplate Dagger
• Scopeهای آماده برای Android (مثل ActivityRetained, ViewModel)
• ادغام عالی با Jetpack ViewModel و WorkManager
• Performance بالا چون هنوز زیرش Dagger هست
نمونه استفاده Kotlin ⬇️
dependencies {
implementation "com.google.dagger:hilt-android:2.51.1"
kapt "com.google.dagger:hilt-android-compiler:2.51.1"
}
@HiltAndroidApp
class MyApp : Application()
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject lateinit var repo: UserRepository
}
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
fun provideApi(): Api = ApiImpl()
}
برای پروژههای متوسط و بزرگ، Hilt ساختار کد رو تمیزتر، تستنویسی رو راحتتر و refactor رو کمریسکتر میکنه. ارزش اینو داره یه پروژه کوچیک رو کامل با Hilt بالا بیاری و الگوهاشو تمرین کنی 💡
Docs رسمی:
Hilt Documentation
Android Developers - Hilt
🔖 #Android #اندروید #Android #Hilt #Dependency_Injection #Kotlin #Jetpack
👤 Developix
💎 Channel: @DevelopixAndroid | 888 |
| 18 | کتابخونه Retrofit از Square یکی از استانداردهای طلایی برای کار با API تو اندرویده 🚀
با Retrofit دیگه خبری از HttpURLConnection و کد تکراری برای parse کردن JSON نیست. فقط یک Interface مینویسی، بقیه کار رو خودش انجام میده.
ویژگیها:
• تبدیل خودکار JSON به data classهای Kotlin با Gson/Moshi 🧩
• پشتیبانی از Coroutines و RxJava
• ادغام راحت با OkHttp برای Log و Interceptor ها
• هندل ساده Error ها و Response Code ها
نمونه استفاده:
implementation "com.squareup.retrofit2:retrofit:2.11.0"
implementation "com.squareup.retrofit2:converter-moshi:2.11.0"
interface ApiService {
@GET("users/{id}")
suspend fun getUser(@Path("id") id: Long): Response<User>
}
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(MoshiConverterFactory.create())
.build()
val api = retrofit.create(ApiService::class.java)
برای اپهایی که زیاد با REST API سروکار دارن، Retrofit کد رو تمیزتر، قابل تستتر و قابل نگهداریتر میکنه. 🤝
مستندات رسمی:
Docs
GitHub
🔖 #Android #اندروید #Android #Retrofit #Networking #Kotlin #API
👤 Developix
💎 Channel: @DevelopixAndroid | 818 |
| 19 | برای لیستهای طولانی (فید، لیست محصولات، لاگها)، لود کردن همه دیتا یکجا فقط RAM را میسوزاند و UI را کند میکند. اینجا Paging 3 از Jetpack میدرخشد ✨
Paging3 کمک میکند دیتا را صفحهبهصفحه از شبکه یا DB بگیرید، اسکرول نرم بماند و مصرف حافظه و ترافیک کم شود.
ویژگیها:
• ادغام مستقیم با Room، Retrofit و Jetpack Compose
• پشتیبانی از Flow و LiveData
• هندل خودکار load state (loading / error / retry)
نصب (Gradle):
dependencies {
implementation "androidx.paging:paging-runtime-ktx:3.3.2"
}
مثال ساده با Flow و ViewModel:
val flow = Pager(
PagingConfig(pageSize = 20)
) {
MyPagingSource(api)
}.flow
در Compose میتوانید همین Flow را با collectAsLazyPagingItems() مصرف کنید و مستقیماً به LazyColumn بدهید؛ بدون اینکه خودتان pagination، loading و error را مدیریت کنید.
مستندات رسمی:
Docs
Release Notes
برای هر لیست بزرگ در اپ بعدی، یک بار Paging3 را امتحان کنید و تفاوت روانی اسکرول را ببینید 🚀
🔖 #Android #اندروید #Android #Paging3 #Kotlin #Jetpack #Compose
👤 Developix
💎 Channel: @DevelopixAndroid | 770 |
| 20 | در کد زیر یک Memory Leak و استفادهی اشتباه از Context در ViewModel وجود دارد.
چه چیزی باید اصلاح شود تا این Memory Leak رخ ندهد و کد مطابق با Best Practiceهای Android Architecture درست شود؟
class MainViewModel(private val context: Context) : ViewModel() {
private var dialog: AlertDialog? = null
fun showErrorDialog(message: String) {
val builder = AlertDialog.Builder(context)
builder.setTitle("Error")
builder.setMessage(message)
builder.setPositiveButton("OK", null)
dialog = builder.create()
dialog?.show()
}
override fun onCleared() {
super.onCleared()
dialog?.dismiss()
}
}
🔖 #Android #اندروید
👤 Developix
💎 Channel: @DevelopixAndroid | 757 |
