Android KTX Componente di Android Jetpack.
Android KTX è un insieme di estensioni Kotlin incluse in Android Jetpack e in altre librerie Android. Le estensioni KTX offrono Kotlin conciso e idiomatico a Jetpack, piattaforma Android e altre API. A questo scopo, queste estensioni sfruttano diverse funzionalità relative al linguaggio Kotlin, tra cui:
- Funzioni di estensione
- Proprietà estensione
- Lambda
- Parametri con nome
- Valori predefiniti dei parametri
- Coroutine
Ad esempio, quando lavori con SharedPreferences
, devi creare un editor prima di poter apportare modifiche ai dati delle preferenze. Devi anche applicare o eseguire il commit di queste modifiche al termine della modifica, come illustrato nell'esempio seguente:
sharedPreferences
.edit() // create an Editor
.putBoolean("key", value)
.apply() // write to disk asynchronously
Le lambda Kotlin sono la soluzione perfetta per questo caso d'uso. Consentono di adottare un approccio più conciso passando un blocco di codice da eseguire dopo la creazione dell'editor, lasciando l'esecuzione del codice e consentendo all'API SharedPreferences
di applicare le modifiche a livello atomico.
Ecco un esempio di una delle funzioni principali di Android KTX, SharedPreferences.edit
, che aggiunge una funzione di modifica a SharedPreferences
. Questa funzione prende un
flag boolean
facoltativo come primo argomento che indica se eseguire il commit
o applicare le modifiche. Riceve inoltre un'azione da eseguire sull'editor SharedPreferences
sotto forma di lambda.
// SharedPreferences.edit extension function signature from Android KTX - Core
// inline fun SharedPreferences.edit(
// commit: Boolean = false,
// action: SharedPreferences.Editor.() -> Unit)
// Commit a new value asynchronously
sharedPreferences.edit { putBoolean("key", value) }
// Commit a new value synchronously
sharedPreferences.edit(commit = true) { putBoolean("key", value) }
Il chiamante può scegliere se confermare o applicare le modifiche. La funzione lambda action
è una funzione di estensione anonima su SharedPreferences.Editor
che restituisce Unit
, come indicato dalla sua firma. Ecco perché all'interno del blocco puoi eseguire il lavoro direttamente su SharedPreferences.Editor
.
Infine, la firma SharedPreferences.edit()
contiene la parola chiave inline
.
Questa parola chiave indica al compilatore Kotlin che deve copiare e incollare (o incorporare) il bytecode compilato per la funzione ogni volta che viene utilizzata la funzione.
In questo modo si evita l'overhead associato alla creazione di istanze di una nuova classe per ogni action
ogni volta che viene chiamata questa funzione.
Questo pattern di trasmissione del codice utilizzando lambda, applicando valori predefiniti sensibili che possono essere sostituiti e aggiungendo questi comportamenti alle API esistenti utilizzando le funzioni di estensione di inline
è tipico dei miglioramenti forniti dalla libreria KTX di Android.
Usa Android KTX nel tuo progetto
Per iniziare a utilizzare Android KTX, aggiungi la seguente dipendenza al file build.gradle
del tuo progetto:
Trendy
repositories { google() }
Kotlin
repositories { google() }
Moduli AndroidX
Android KTX è organizzato in moduli, ognuno dei quali contiene uno o più pacchetti.
Devi includere una dipendenza per ogni artefatto del modulo nel file build.gradle
dell'app. Ricordati di aggiungere il numero di versione all'elemento.
Puoi trovare i numeri di versione più recenti nella sezione corrispondente di ogni elemento di questo argomento.
Android KTX contiene un modulo single core che fornisce estensioni Kotlin per le API framework comuni e diverse estensioni specifiche del dominio.
Ad eccezione del modulo principale, tutti gli artefatti del modulo KTX sostituiscono la dipendenza Java sottostante nel file build.gradle
. Ad esempio, puoi
sostituire una dipendenza androidx.fragment:fragment
con
androidx.fragment:fragment-ktx
. Questa sintassi aiuta a gestire meglio il controllo delle versioni e non aggiunge ulteriori requisiti di dichiarazione delle dipendenze.
KTX di base
Il modulo KTX principale fornisce estensioni per le librerie comuni che fanno parte del framework Android. Queste librerie non hanno dipendenze basate su Java che devi aggiungere a build.gradle
.
Per includere questo modulo, aggiungi quanto segue al file build.gradle
dell'app:
Trendy
dependencies { implementation "androidx.core:core-ktx:1.12.0" }
Kotlin
dependencies { implementation("androidx.core:core-ktx:1.12.0") }
Di seguito è riportato un elenco dei pacchetti contenuti nel modulo KTX principale:
- androidx.core.animation.
- androidx.core.content
- androidx.core.content.res.
- androidx.core.database.
- androidx.core.database.sqlite
- androidx.core.graphics.
- androidx.core.graphics.drawable.
- androidx.core.location
- androidx.core.net
- androidx.core.os
- androidx.core.text
- transizione.androidx.core.
- androidx.core.util.
- androidx.core.view.
- androidx.core.widget.
Raccolta KTX
Le estensioni di raccolta contengono funzioni di utilità per utilizzare le librerie di raccolta a elevata efficienza in termini di memoria di Android, tra cui ArrayMap
, LongSparseArray
, LruCache
e altre.
Per utilizzare questo modulo, aggiungi quanto segue al file build.gradle
dell'app:
Scadente
dependencies { implementation "androidx.collection:collection-ktx:1.2.0" }
Kotlin
dependencies { implementation("androidx.collection:collection-ktx:1.2.0") }
Le estensioni di raccolta sfruttano il sovraccarico degli operatori di Kotlin per semplificare operazioni come la concatenazione delle raccolte, come illustrato nell'esempio seguente:
// Combine 2 ArraySets into 1.
val combinedArraySet = arraySetOf(1, 2, 3) + arraySetOf(4, 5, 6)
// Combine with numbers to create a new sets.
val newArraySet = combinedArraySet + 7 + 8
Frammento KTX
Il modulo Fragment KTX fornisce una serie di estensioni per semplificare l'API Snippet.
Per includere questo modulo, aggiungi quanto segue al file build.gradle
dell'app:
Scadente
dependencies { implementation "androidx.fragment:fragment-ktx:1.6.1" }
Kotlin
dependencies { implementation("androidx.fragment:fragment-ktx:1.6.1") }
Con il modulo KTX per frammenti, puoi semplificare le transazioni di frammenti con lambda, ad esempio:
fragmentManager().commit {
addToBackStack("...")
setCustomAnimations(
R.anim.enter_anim,
R.anim.exit_anim)
add(fragment, "...")
}
Puoi anche associare un ViewModel
in una sola riga utilizzando i delegati delle proprietà viewModels
e
activityViewModels
:
// Get a reference to the ViewModel scoped to this Fragment
val viewModel by viewModels<MyViewModel>()
// Get a reference to the ViewModel scoped to its Activity
val viewModel by activityViewModels<MyViewModel>()
KTX del ciclo di vita
KTX del ciclo di vita definisce un LifecycleScope
per ogni oggetto Lifecycle
. Qualsiasi coroutine
lanciata in questo ambito viene annullata quando Lifecycle
viene eliminato. Puoi accedere a CoroutineScope
dell'elemento Lifecycle
utilizzando le proprietà lifecycle.coroutineScope
o lifecycleOwner.lifecycleScope
.
Per includere questo modulo, aggiungi quanto segue al file build.gradle
dell'app:
Scadente
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.2" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2") }
L'esempio seguente mostra come utilizzare lifecycleOwner.lifecycleScope
per creare testo precalcolato in modo asincrono:
class MyFragment: Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycleScope.launch {
val params = TextViewCompat.getTextMetricsParams(textView)
val precomputedText = withContext(Dispatchers.Default) {
PrecomputedTextCompat.create(longTextContent, params)
}
TextViewCompat.setPrecomputedText(textView, precomputedText)
}
}
}
KTX LiveData
Quando utilizzi LiveData, potrebbe essere necessario calcolare i valori in modo asincrono. Ad esempio, potresti voler recuperare le preferenze di un utente e pubblicarle nella tua UI. In questi casi, KTX LiveData fornisce una funzione del builder liveData
che chiama una funzione suspend
e gestisce il risultato come oggetto LiveData
.
Per includere questo modulo, aggiungi quanto segue al file build.gradle
dell'app:
Scadente
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.2" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2") }
Nell'esempio seguente, loadUser()
è una funzione di sospensione dichiarata altrove.
Puoi utilizzare la funzione del builder di liveData
per chiamare loadUser()
in modo asincrono, quindi utilizzare emit()
per emettere il risultato:
val user: LiveData<User> = liveData {
val data = database.loadUser() // loadUser is a suspend function.
emit(data)
}
Per ulteriori informazioni sull'utilizzo delle coroutine con LiveData
, consulta
Utilizzare le coroutine Kotlin con i componenti dell'architettura.
Navigazione KTX
Ogni componente della libreria di navigazione ha la propria versione KTX che adatta l'API in modo che risulti più concisa e idiomatica di Kotlin.
Per includere questi moduli, aggiungi quanto segue al file build.gradle
dell'app:
Scadente
dependencies { implementation "androidx.navigation:navigation-runtime-ktx:2.7.2" implementation "androidx.navigation:navigation-fragment-ktx:2.7.2" implementation "androidx.navigation:navigation-ui-ktx:2.7.2" }
Kotlin
dependencies { implementation("androidx.navigation:navigation-runtime-ktx:2.7.2") implementation("androidx.navigation:navigation-fragment-ktx:2.7.2") implementation("androidx.navigation:navigation-ui-ktx:2.7.2") }
Utilizza le funzioni di estensione e la delega delle proprietà per accedere agli argomenti della destinazione e raggiungere le destinazioni, come mostrato nell'esempio seguente:
class MyDestination : Fragment() {
// Type-safe arguments are accessed from the bundle.
val args by navArgs<MyDestinationArgs>()
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
view.findViewById<Button>(R.id.next)
.setOnClickListener {
// Fragment extension added to retrieve a NavController from
// any destination.
findNavController().navigate(R.id.action_to_next_destination)
}
}
...
}
Tavolozza KTX
Il modulo Palette KTX offre un supporto Kotlin idiomatico per lavorare con le tavolozze dei colori.
Per utilizzare questo modulo, aggiungi quanto segue al file build.gradle
dell'app:
Scadente
dependencies { implementation "androidx.palette:palette-ktx:1.0.0" }
Kotlin
dependencies { implementation("androidx.palette:palette-ktx:1.0.0") }
Ad esempio, quando lavori con un'istanza Palette
, puoi recuperare il campione selected
per un determinato target
utilizzando l'operatore get ([ ]
):
val palette = Palette.from(bitmap).generate()
val swatch = palette[target]
Flussi reattivi - KTX
Il modulo KTX per flussi reattivi ti consente di creare uno stream LiveData
osservabile da
un publisher ReactiveStreams
.
Per includere questo modulo, aggiungi quanto segue al file build.gradle
dell'app:
Scadente
dependencies { implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.6.2" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.6.2") }
Supponiamo, ad esempio, un database con un breve elenco di utenti. Nell'app, carichi il database in memoria e poi visualizzi i dati utente nella UI. Per ottenere questo risultato, puoi utilizzare RxJava.
Il componente Jetpack Room
può recuperare
l'elenco degli utenti come Flowable
. In questo scenario, devi anche gestire l'abbonamento dell'editore Rx per tutta la durata del frammento o dell'attività.
Tuttavia, con LiveDataReactiveStreams
puoi trarre vantaggio da RxJava e dal suo ricco insieme di operatori e funzionalità di pianificazione del lavoro, lavorando anche con la semplicità di LiveData
, come mostrato nell'esempio seguente:
val fun getUsersLiveData() : LiveData<List<User>> {
val users: Flowable<List<User>> = dao.findUsers()
return LiveDataReactiveStreams.fromPublisher(users)
}
KTX sala
Le estensioni della camera aggiungono il supporto delle coroutine per le transazioni del database.
Per utilizzare questo modulo, aggiungi quanto segue al file build.gradle
dell'app:
Trendy
dependencies { implementation "androidx.room:room-ktx:2.5.2" }
Kotlin
dependencies { implementation("androidx.room:room-ktx:2.5.2") }
Ecco un paio di esempi in cui Room ora utilizza le coroutine. Il primo esempio utilizza una funzione suspend
per restituire un elenco di oggetti User
, mentre il secondo utilizza Flow
di Kotlin per restituire in modo asincrono l'elenco User
. Tieni presente che, quando utilizzi Flow
, riceverai anche una notifica per eventuali modifiche alle tabelle su cui stai eseguendo una query.
@Query("SELECT * FROM Users")
suspend fun getUsers(): List<User>
@Query("SELECT * FROM Users")
fun getUsers(): Flow<List<User>>
KTX SQLite
Le estensioni SQLite aggregano il codice relativo a SQL nelle transazioni, eliminando una grande quantità di codice boilerplate.
Per utilizzare questo modulo, aggiungi quanto segue al file build.gradle
dell'app:
Scadente
dependencies { implementation "androidx.sqlite:sqlite-ktx:2.3.1" }
Kotlin
dependencies { implementation("androidx.sqlite:sqlite-ktx:2.3.1") }
Ecco un esempio di utilizzo dell'estensione transaction
per eseguire una transazione di database:
db.transaction {
// insert data
}
Visualizza modello KTX
La libreria KTX ViewModel fornisce una funzione viewModelScope()
che semplifica l'avvio delle coroutine da ViewModel
. L'elemento
CoroutineScope
è associato a Dispatchers.Main
e viene annullato automaticamente
quando viene cancellato il valore ViewModel
. Puoi utilizzare viewModelScope()
invece di
creare un nuovo ambito per ogni ViewModel
.
Per includere questo modulo, aggiungi quanto segue al file build.gradle
dell'app:
Scadente
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2") }
Ad esempio, la seguente funzione viewModelScope()
avvia una coroutine
che effettua una richiesta di rete in un thread in background. La libreria gestisce tutta la configurazione e la cancellazione dell'ambito corrispondente:
class MainViewModel : ViewModel() {
// Make a network request without blocking the UI thread
private fun makeNetworkRequest() {
// launch a coroutine in viewModelScope
viewModelScope.launch {
remoteApi.slowFetch()
...
}
}
// No need to override onCleared()
}
KTX WorkManager
WorkManager KTX fornisce un'assistenza di primo livello per le coroutine.
Per includere questo modulo, aggiungi quanto segue al file build.gradle
dell'app:
Scadente
dependencies { implementation "androidx.work:work-runtime-ktx:2.8.1" }
Kotlin
dependencies { implementation("androidx.work:work-runtime-ktx:2.8.1") }
Invece di estendere Worker
, ora puoi
estendere CoroutineWorker
,
che ha un'API leggermente diversa. Ad esempio, se vuoi creare una CoroutineWorker
semplice per eseguire alcune operazioni di rete, puoi:
class CoroutineDownloadWorker(context: Context, params: WorkerParameters)
: CoroutineWorker(context, params) {
override suspend fun doWork(): Result = coroutineScope {
val jobs = (0 until 100).map {
async {
downloadSynchronously("https://www.google.com")
}
}
// awaitAll will throw an exception if a download fails, which
// CoroutineWorker will treat as a failure
jobs.awaitAll()
Result.success()
}
}
Per maggiori informazioni sull'utilizzo di CoroutineWorker
, consulta
Organizzare i thread in CoroutineWorker.
WorkManager KTX aggiunge anche funzioni di estensione a Operations
e
ListenableFutures
per sospendere l'attuale coroutine.
Ecco un esempio che sospende l'elemento Operation
restituito da enqueue()
:
// Inside of a coroutine...
// Run async operation and suspend until completed.
WorkManager.getInstance()
.beginWith(longWorkRequest)
.enqueue().await()
// Resume after work completes...
Altri moduli KTX
Puoi anche includere moduli KTX aggiuntivi che esistono al di fuori di AndroidX.
Firebase KTX
Alcuni SDK Firebase per Android dispongono di librerie di estensioni Kotlin che consentono di scrivere codice Kotlin idiomatico quando utilizzi Firebase nella tua app. Per ulteriori informazioni, consulta i seguenti argomenti:
Piattaforma KTX di Google Maps
Per gli SDK Android di Google Maps Platform sono disponibili estensioni KTX che consentono di sfruttare diverse funzionalità del linguaggio Kotlin, come le funzioni di estensione, i parametri con nome e gli argomenti predefiniti, le dichiarazioni destrutturate e le coroutine. Per ulteriori informazioni, consulta i seguenti argomenti:
Gioca a Core KTX
Play Core KTX aggiunge il supporto delle coroutine Kotlin per le richieste one-shot e Flow
per il monitoraggio degli aggiornamenti dello stato aggiungendo funzioni di estensione a
SplitInstallManager
e AppUpdateManager
nella libreria di base di Play.
Per includere questo modulo, aggiungi quanto segue al file build.gradle
dell'app:
Trendy
dependencies { implementation "com.google.android.play:core-ktx:1.8.1" }
Kotlin
dependencies { implementation("com.google.android.play:core-ktx:1.8.1") }
Ecco un esempio di Flow
per il monitoraggio dello stato:
// Inside of a coroutine...
// Request in-app update status updates.
manager.requestUpdateFlow().collect { updateResult ->
when (updateResult) {
is AppUpdateResult.Available -> TODO()
is AppUpdateResult.InProgress -> TODO()
is AppUpdateResult.Downloaded -> TODO()
AppUpdateResult.NotAvailable -> TODO()
}
}
Ulteriori informazioni
Per scoprire di più su Android KTX, guarda il video DevBytes.
Per segnalare un problema o suggerire una funzionalità, utilizza lo strumento di monitoraggio dei problemi KTX di Android.