ThreeTenABP — Android uchun adapter kutubxonasi, Android 8 dan past (API < 26) qurilmalarda java.time API (org.threeten.bp paketi) ni tadim etadi. Spetsifikatsiyaga köra Jake Wharton (GitHub, 2023), kutubxona ThreeTen-Backport loyihasi ustidagi qobiq bo‘lib, resurslarni optimallashtirish va AssetManager orqali tzdata qo‘llab-quvvatlash bilan Android uchun moslashtirilgan.
Asosiy fikrlar
ThreeTenABP (ThreeTen Android Backport) — Jake Wharton tomonidan eski Android versiyalarida Java 8 sana/vaqt API sidan foydalanish uchun yaratilgan kutubxona. Bu ThreeTen-Backport loyihasi uchun adapter bo‘lib, java.time (JSR-310) ni Java 7 va Android API < 26 ga port qiladi.
Kutubxona hal qiladigan asosiy muammo: Android 8 (API 26) gacha java.time standart yetkazib berishga kiritilmagan. Dasturchilar java.util.Date/Calendar ishlatishga yoki Joda-Time ni ulashga majbur edilar. ThreeTenABP xuddi ichki java.time kabi zamonaviy API ni tadim etadi, lekin org.threeten.bp paketi orqali.
Ma‘lumotlarga köra GitHub ombori (2023), kutubxona Android uchun optimallashtirilgan: tzdata ma‘lumotlari (IANA Time Zone Database) assets da saqlanadi va AssetManager orqali yuklanadi, ish stolidagi kabi classpath orqali emas. Bu APK hajmini kamaytiradi va yuklashni tezlashtiradi.
Oxirgi barqaror versiya — 1.4.0 (avgust 2021). Kutubxona qo‘llab-quvvatlash rejimida, chunki desugaring keng tarqalishi bilan unga ehtiyoj kamayadi, lekin minimal API < 26 bo‘lgan loyihalar uchun dolzarb bo‘lib qolmoqda.
Java 8 da (2014) java.time paydo bo‘lishidan oldin dasturchilar java.util.Date va java.util.Calendar dan foydalanardilar. Bu sinflar jiddiy kamchiliklarga ega: Date mutable, Calendar intuitiv bo‘lmagan konstantalardan foydalanadi (Calendar.JANUARY = 0), ikkala sinf thread-safe emas va vaqt mintaqalari bilan ishlashda xatolarga moyil.
Joda-Time Java 8 dan oldin de-fakto standart edi, lekin uning yaratuvchisi Stephen Colebourne java.time ni rasmiy o‘rnini bosuvchi sifatida loyihalashtirdi, Joda-Time tajribasiga asoslanib va uning kamchiliklarini hisobga olib. java.time paketi JDK 8 ga kiritildi, lekin Android uni API 26 gacha olmadi.
ThreeTen-Backport — xuddi shu muallif (Stephen Colebourne) tomonidan yaratilgan java.time ni Java 7 ga porti. Barcha asosiy sinflarni o‘z ichiga oladi: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter. ThreeTenABP bu portni Android uchun moslashtiradi, AssetsManager orqali ishga tushirish va mobil qurilmalar uchun optimallashtirishni qo‘shadi.
Shunday qilib, ThreeTenABP Android 4.0+ (API 14+) qurilmalarda zamonaviy sana/vaqt API sidan foydalanishga imkon beradi, OT yangilanishini kutmasdan.
Ulash ikki bosqichda amalga oshiriladi: build.gradle (app-level) ga bog‘liqlik qo‘shish va Application sinfida ishga tushirish. Muhim: ThreeTenABP compileSdk 21 dan kam bo‘lmagan va Gradle versiyasi 4.0 dan kam bo‘lmaganini talab qiladi.
Bog‘liqlik dependencies bo‘limiga qo‘shiladi: implementation “com.jakewharton.threetenabp:threetenabp:1.4.0”. 1.4.0 chiqarilishidan beri kutubxona yangilanmagan, chunki u barqaror va barcha kerakli holatlarni qamrab oladi.
Rasmiy hujjatlarga köra rasmiy hujjatlar, kutubxona tzdata ni assets da o‘z ichiga oladi. Agar ilovada allaqachon boshqa fayllar bilan assets papkasi bo‘lsa, ThreeTenABP ular bilan to‘g‘ri birga mavjud bo‘ladi. Tzdata hajmi siqilgan holda taxminan 200 KB.
// build.gradle (ilova darajasi)
android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
dependencies {
implementation "com.jakewharton.threetenabp:threetenabp:1.4.0"
}
org.threeten.bp dan har qanday sinfdan foydalanishdan oldin kutubxonani ishga tushirish kerak. Ishga tushirish bir marta Application.onCreate() ichida AndroidThreeTen.init(this) chaqiruvi orqali amalga oshiriladi.
Ishga tushirish tzdata ma‘lumotlarini assets dan yuklaydi va tizim soatini sozlaydi. init() chaqiruvsiz now() metodlari kutubxona ishga tushirilmaganligi haqida IllegalStateException istisnosini qaytaradi.
Testlar uchun AndroidThreeTen.init(applicationContext, zoneId) — vaqt mintaqasini aniq körsatish bilan overload ishlatilishi mumkin. Bu testlarning bashorat qilinadigan xatti-harakati uchun foydali. Faqat tzdata siz asosiy ishga tushirish kerak bo‘lsa — AndroidThreeTen.initWithoutFiles(context) dan foydalaning.
class App : Application() {
override fun onCreate() {
super.onCreate()
AndroidThreeTen.init(this)
}
}
// Ishga tushirishdan keyin foydalanish
val today = LocalDate.now()
val now = LocalDateTime.now()
ThreeTenABP java.time ning barcha asosiy sinflarini tadim etadi, lekin org.threeten.bp paketida. API asl java.time bilan deyarli bir xil, bu API 26+ ga o‘tishda migratsiyani osonlashtiradi.
Asosiy sinflar:
Yordamchi sinflar ham qo‘llab-quvvatlanadi: Clock, DayOfWeek, Month, Year, YearMonth, MonthDay. Vaqt mintaqalari kutubxona bilan birga keladi (IANA tzdata). ThreeTenABP 1.4.0 da tzdata versiyasi 2021a ga mos keladi.
Android Gradle Plugin 4.0 (2020) va desugar_jdk_libs dan boshlab, dasturchilar coreLibraryDesugaring orqali barcha Android versiyalarida java.time dan foydalanish imkoniyatiga ega bo‘ldilar. Desugaring bayt kodini shunday o‘zgartiradiki, java.time chaqiruvlari qo‘shimcha kutubxonalarsiz eski API larda ishlaydi.
Desugaring ning afzalliklari: asl java.time paketi ishlatiladi (org.threeten.bp emas), ishga tushirish talab qilinmaydi, Android Studio bilan to‘liq integratsiya. Kamchiliklari: AGP 4.0+ talab qiladi, qurish vaqtini oshiradi, APK hajmi 2-3 MB ga oshishi mumkin.
ThreeTenABP AGP ni 4.0+ ga yangilay olmaydigan legacy loyihalar yoki APK hajmi muhim bo‘lgan holatlar uchun eng yaxshi tanlov bo‘lib qolmoqda. Shuningdek, ThreeTenABP sozlashda soddaroq — bitta bog‘liqlik va bitta qator ishga tushirish kifoya. Stack Overflow (2024) ma‘lumotlariga köra, minSdk < 26 bo‘lgan loyihalarning taxminan 30% i hali ham desugaring o‘rniga ThreeTenABP dan foydalanadi.
Birinchi misol — ThreeTenABP orqali sanalar bilan ishlash. API java.time bilan bir xil, lekin importlar org.threeten.bp dan keladi. Bu migratsiyadan keyin faqat importlarni o‘zgartirishni talab qiladigan kod yozishga imkon beradi.
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalTime
import org.threeten.bp.Duration
fun isWeekend(date: LocalDate): Boolean {
val dayOfWeek = date.getDayOfWeek()
return dayOfWeek == DayOfWeek.SATURDAY ||
dayOfWeek == DayOfWeek.SUNDAY
}
fun timeBetween(
start: LocalTime, end: LocalTime
): Duration {
return Duration.between(start, end)
}
Ikkinchi misol — sanani formatlash. org.threeten.bp dan DateTimeFormatter java.time dagi kabi ishlaydi.
import org.threeten.bp.LocalDateTime
import org.threeten.bp.format.DateTimeFormatter
fun formatTimestamp(dateTime: LocalDateTime): String {
val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm")
return dateTime.format(formatter)
}
Uchinchi misol — ZonedDateTime bilan ishlash va ThreeTenABP da vaqt mintaqalari o‘rtasida konvertatsiya.
import org.threeten.bp.ZonedDateTime
import org.threeten.bp.ZoneId
fun convertTimeZone(
time: ZonedDateTime,
targetZone: ZoneId
): ZonedDateTime {
return time.withZoneSameInstant(targetZone)
}
minSdk 26 ga ko‘tarilganda ThreeTenABP dan voz kechib, ichki java.time ga o‘tish mumkin. Migratsiya jarayoni bir necha bosqichni o‘z ichiga oladi va diqqatli test talab qiladi.
Birinchi bosqich — importlarni almashtirish. org.threeten.bp importlari java.time ga o‘zgartiriladi. Aksariyat hollarda sinf nomlari mos keladi: LocalDate → java.time.LocalDate, ZonedDateTime → java.time.ZonedDateTime. Istisno DateTimeFormatter — ThreeTenABP da org.threeten.bp.format, java.time da esa java.time.format.
Ikkinchi bosqich — ishga tushirishni olib tashlash. AndroidThreeTen.init(this) qatori endi kerak emas, chunki java.time Android SDK ga kiritilgan. Application.onCreate() dan chaqiruvni va build.gradle dan bog‘liqlikni olib tashlang.
Uchinchi bosqich — agar minSdk 26 dan past bo‘lib qolsa, bog‘liqlikni desugaring bilan almashtirish. compileOptions da isCoreLibraryDesugaringEnabled = true va desugar_jdk_libs bog‘liqligini qo‘shing. Bu ThreeTenABP siz eski API larda java.time ishlashini ta‘minlaydi. Google I/O (2023) ma‘lumotlariga köra, desugaring yangi loyihalar uchun afzal usuldir.
// build.gradle — ThreeTenABP ni desugaring bilan almashtir
android {
compileOptions {
isCoreLibraryDesugaringEnabled = true
}
}
dependencies {
// Olib tashlash: implementation “com.jakewharton.threetenabp:threetenabp:1.4.0”
// Qo‘shish:
"coreLibraryDesugaring"("com.android.tools:desugar_jdk_libs:2.1.4")
}
// Application dan AndroidThreeTen.init(this) ni olib tashlash
Tez-tez beriladigan savollar
Texnik jihatdan — ha, lekin buning ma‘nosi yo‘q. Agar desugaring ishlatilsa, ichki java.time allaqachon mavjud. Ikkala kutubxonaning ishlatilishi kodning takrorlanishiga va APK hajmining oshishiga olib keladi. Loyiha uchun bitta yondashuvni tanlang.
Ishga tushirish IANA Time Zone Database ma‘lumotlarini assets dan xotiraga yuklaydi. Standart JDK da tzdata classpath orqali mavjud, lekin Android AssetManager dan foydalanadi. init() metodi ma‘lumotlarni tizim papkasiga nusxalaydi, ularni ZoneId uchun mavjud qiladi.
ThreeTenABP API 14+ (Android 4.0 Ice Cream Sandwich va undan yuqori) ni qo‘llab-quvvatlaydi. Foydalanish uchun Java 8 compatibility (compileOptions da sourceCompatibility va targetCompatibility) talab qilinadi. API 26+ da kutubxona kerak emas — ichki java.time dan foydalaning.
Vaqt mintaqalari kutubxona bilan birga keladi. 1.4.0 versiyasi tzdata 2021a ni o‘z ichiga oladi. Yangilash uchun ThreeTenABP versiyasini yangilash yoki assets dagi tzdata ni qo‘lda almashtirish kerak. Tzdata ning so‘nggi versiyalarini IANA omboridan yoki ThreeTen-Backport orqali olish mumkin.
Birlik testlari uchun mintaqani aniq körsatish bilan AndroidThreeTen.init(context, zoneId) dan foydalaning. Robolectric testlari uchun — AndroidThreeTen.init(ApplicationProvider.getApplicationContext()). Android siz toza JVM testlari uchun — ThreeTenABP siz to‘g‘ridan-to‘g‘ri ThreeTen-Backport dan foydalaning.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.