| کانال توسعهدهندگان اندروید |
Kanalga Telegram’da o‘tish
⭕️ کانال توسعهدهندگان اندروید دولوپیکس 💠 دولوپیکس | جامعه توسعهدهندگان ایرانی 💎 @Developix 🚀 Developix.ir 📌 پشتیبانی و تبلیغات: @DevelopixSupport
Ko'proq ko'rsatish1 724
Obunachilar
-124 soatlar
-97 kun
-730 kun
Postlar arxiv
📰 عینک اندروید XR مدل Aura از XREAL با ۲۰۰ دلار تخفیف عرضه میشود
شرکت XREAL قیمت پیشخرید و زمان عرضه عینک هوشمند Aura، نخستین عینک این شرکت مبتنی بر اندروید XR، را اعلام کرد. این محصول اواسط نوامبر عرضه میشود و تخفیفهای ویژه آغاز عرضه آن تا سقف ۲۰۰ دلار، تا دسامبر ۲۰۲۶ ادامه خواهد داشت.
این دستگاه از عینکی ۹۵ گرمی همراه با یک واحد پردازشی دیسکیشکل متصل به کمربند تشکیل شده است. نمایشگرهای میکرو OLED با نرخ نوسازی ۱۲۰ هرتز، ردیابی فضایی، ردیابی دست و پشتیبانی از کنترلر از قابلیتهای آن هستند.
Aura در آمریکا، کانادا، ژاپن و کره جنوبی عرضه میشود. ورود آن به بازارهای بیشتر برای سال ۲۰۲۷ برنامهریزی شده است.
🔖 #news
💎 @DevelopixAndroid
📰 گوگل ثبتنام در برنامه فروشگاههای اپلیکیشن شخص ثالث اندروید را با هزینه ۱۰ هزار دلار آغاز کرد
گوگل پذیرش درخواستها برای برنامه «فروشگاههای اپلیکیشن ثبتشده» را آغاز کرده است؛ برنامهای با هدف سادهسازی نصب و بهروزرسانی اپلیکیشنها از فروشگاههای شخص ثالث تأییدشده در دستگاههای اندرویدی. این طرح، در صورت استفاده کاربران از نسخه سازگار اندروید، مراحل نصب را کاهش میدهد و امکان بهروزرسانی در پسزمینه را فراهم میکند. فروشگاههای واجد شرایط باید الزامات مربوط به مالکیت فکری، محتوای غیرقانونی، سیاستهای حریم خصوصی و امنیت را رعایت کنند. متقاضیان باید مدارک انطباق با الزامات و نسخههایی از اپلیکیشنها را ارائه دهند و سالانه ۱۰ هزار دلار بپردازند.
🔖 #news
💎 @DevelopixAndroid
📏 اندازهٔ 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📰 لجر از اتم، دستگاه رمزارزی جدید اندرویدی با نمایشگر لمسی، رونمایی کرد
لجر دستگاه اندرویدی لمسی اتم را معرفی کرده است؛ دستگاهی برای تراکنشهای رمزارزی، پیامرسانی رمزگذاریشده و تأیید اقدامات عاملهای هوش مصنوعی. این دستگاه به تراشه امنیتی Secure Element، نمایشگر ۶٫۷۷ اینچی OLED، باتری ۴۰۰۰ میلیآمپرساعتی و کلیدی فیزیکی برای قطع برق دوربین و میکروفون مجهز است. اتم با اپلیکیشن ازپیشنصبشده Seeker متعلق به سولانا موبایل عرضه خواهد شد. امکان رزرو فراهم شده، اما لجر هنوز قیمت یا تاریخ عرضه را اعلام نکرده است.
🔖 #news
💎 @DevelopixAndroid
🔥 پروژه: ویپیان چندموتورهٔ 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
تست بهتر با تزریق 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+1
وقتی با 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🔥 پروژه: ابزار و مودهای ضروری اندروید (Essentials)
یه پروژه متنباز برای اندرویدبازها؛ مجموعهای از ابزار و مودهایی که کارهای ریز و خستهکننده روزمره روی دستگاههاتون رو سادهتر میکند 🔧
تو Essentials میتوانی اسکریپتها و تنظیمات آماده پیدا کنی تا راحتتر روی دستگاههات تست، دیباگ و انواع تغییرات سیستمی را انجام بدهی، بدون اینکه هر بار از صفر همهچیز را کانفیگ کنی.
اگر با روت، کاستوم رام یا توسعه جدی روی دیوایس واقعی سر و کار داری، یه نگاه بهش میارزه.
⭐️ 105 stars this week
🔖 #Android #اندروید #اندروید #Android #توسعهدهندگان_اندروید
💎 @DevelopixAndroid
❓ خروجی این کد Kotlin چیست؟
در این مثال از Sequence در Kotlin استفاده شده که ارزیابی تنبل (Lazy) دارد. دقت کن که چه زمانی هر بخش اجرا میشود و ترتیب چاپ لاگها را دقیق در نظر بگیر.
خروجی نهایی اجرای این برنامه را (دقیقاً همان چیزی که روی خروجی استاندارد چاپ میشود، خطبهخط) بنویس.
🔖 #Android #اندروید
👤 Developix
💎 Channel: @DevelopixAndroid
📱 تو اپهای اندرویدی مدرن، تقریبا همهچیز وابسته به درخواست شبکه و دیتای 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🔥 پروژه: سرور کمیک خودمیزبان Komga
برای تست اپهای کتابخوان/مانگا ریدر روی اندروید، داشتن یک سرور محتوای واقعی خیلی کمک میکند 📚
Komga یک media server خودمیزبان برای کامیک، مانگا، مجله و eBook است؛ با وباپ، مدیریت کاربر، یادآوری موقعیت مطالعه و تگگذاری.
نکته جذاب برای ما اندرویدیها: API و خروجی OPDS دارد، یعنی میتوانی کل بکاند کتابخانه را به Komga بسپاری و در اپ فقط روی UX و ریدر تمرکز کنی.
کد منبع در GitHub باز است؛ برای ساخت پروتوتایپ یک reader جدی، گزینهی تمیزی است.
⭐️ 32 stars this week
🔖 #Android #اندروید #اندروید #Android #توسعهدهندگان_اندروید
💎 @DevelopixAndroid
کتابخونه 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در کد زیر یک 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🧩 استفادهی امن از 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: @DevelopixAndroidViewModel بهعنوان 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⭕️ یک سوال برای Kotlinکارهای Android:
به خروجی این کد Kotlin که از Coroutines با
runBlocking و launch استفاده میکند دقت کنید.
خروجی دقیق برنامه (با در نظر گرفتن ترتیب چاپ) چه خواهد بود؟
پاسخ را دقیقا همانطور که در خروجی Console چاپ میشود بنویسید.
🔖 #Android #اندروید
👤 Developix
💎 Channel: @DevelopixAndroid+1
در نمونهکد بالا در هنگام گوشدادن به تغییرات UI با استفاده از Flow، هر بار مقدار جدید میرسد، همهٔ listenerهای قدیمی بدون لغو شدن روی همان
view ثبت میشوند. این الگو علاوه بر ایجاد Memory Leak، میتواند باعث تکرار غیرضروری کارها و افت کارایی شود. در نسخهٔ اصلاحشده با استفاده از Lifecycle.repeatOnLifecycle و collectLatest، هم جمعکنندهها به چرخهٔ حیات Fragment یا Activity گره میخورند و هم در صورت رسیدن مقدار جدید، بلاک قبلی بهدرستی لغو میشود. در سناریوهای real-time مانند بهروزرسانی لیست یا status کاربران، این روش، مصرف مموری را کاهش داده و از اجرای همزمان چند کار مشابه جلوگیری میکند.
🔖 #Android #اندروید
👤 Developix
💎 Channel: @DevelopixAndroidکتابخونه امروز: 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کتابخونه 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برای لیستهای طولانی (فید، لیست محصولات، لاگها)، لود کردن همه دیتا یکجا فقط 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