Android KTX Parte do Android Jetpack.
O Android KTX é um conjunto de extensões Kotlin que fazem parte do Android Jetpack e de outras bibliotecas do Android. Com as extensões do KTX, o Jetpack, a Plataforma Android e outras APIs podem fazer uso de uma linguagem Kotlin concisa e idiomática. Para isso, essas extensões usam vários recursos do Kotlin, incluindo:
- Funções da extensão
- Propriedades de extensão
- Lambdas
- Parâmetros nomeados
- Valores padrão de parâmetro
- Corrotinas
Por exemplo, ao trabalhar com
SharedPreferences
, é preciso
criar um editor
para poder fazer modificações nos dados de preferências. Você também precisa aplicar
ou confirmar essas modificações ao terminar de editar, conforme mostrado no exemplo
a seguir:
sharedPreferences
.edit() // create an Editor
.putBoolean("key", value)
.apply() // write to disk asynchronously
Usar lambdas do Kotlin é ideal neste caso de uso. Com elas, você pode adotar uma
abordagem mais concisa passando um bloco de código para execução após a criação do editor,
permitindo que o código seja executado e que a API SharedPreferences
aplique as mudanças atomicamente.
Confira um exemplo de uma das funções principais do Android KTX,
SharedPreferences.edit
,
que adiciona uma função de edição a SharedPreferences
. Essa função usa uma flag boolean
opcional
como o primeiro argumento, que indica se as mudanças serão confirmadas ou aplicadas. Ela também recebe uma ação para executar no editor SharedPreferences
na forma de 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) }
O autor da chamada pode escolher entre confirmar ou aplicar as mudanças. A lambda action
é, por si só, uma função de extensão anônima em SharedPreferences.Editor
que retorna Unit
, conforme indicado pela assinatura. É por isso que, dentro do
bloco, você pode executar o trabalho diretamente na interface
SharedPreferences.Editor
.
Por fim, a assinatura SharedPreferences.edit()
traz a palavra-chave inline
.
Essa palavra-chave informa ao compilador do Kotlin que ele precisa copiar e colar (ou tornar inline) o bytecode compilado para a função sempre que ela for usada.
Isso evita a sobrecarga de instanciar uma nova classe para cada action
sempre que essa função for chamada.
Esse padrão de passagem de código usando lambdas, aplicação de padrões sensíveis que podem
ser substituídos e adição desses comportamentos a APIs existentes usando funções de extensão inline
é comum entre as melhorias trazidas pela
biblioteca Android KTX.
Usar o Android KTX no projeto
Para começar a usar o Android KTX, adicione a dependência a seguir ao arquivo
build.gradle
do projeto:
Groovy
repositories { google() }
Kotlin
repositories { google() }
Módulos do AndroidX
O Android KTX é organizado em módulos, e cada módulo contém um ou mais pacotes.
É necessário incluir uma dependência para cada artefato do módulo no arquivo build.gradle
do app. Lembre-se de anexar o número da versão ao artefato.
Neste tópico, disponibilizamos os números de versão mais recentes em
cada seção correspondente.
O Android KTX contém um único módulo principal que fornece extensões Kotlin para APIs de framework comuns e várias extensões específicas do domínio.
Com exceção do módulo principal, todos os artefatos de módulo do KTX substituem a
dependência Java subjacente no arquivo build.gradle
. Por exemplo, você pode
substituir uma dependência androidx.fragment:fragment
por androidx.fragment:fragment-ktx
. Essa sintaxe ajuda a gerenciar melhor
o controle de versões e não gera outros requisitos de declaração de dependência.
Core KTX
O módulo Core KTX oferece extensões para bibliotecas comuns que fazem parte do
framework do Android. Essas bibliotecas não têm dependências baseadas em Java que
você precisa adicionar a build.gradle
.
Para incluir este módulo, adicione o seguinte código ao arquivo build.gradle
do seu app:
Groovy
dependencies { implementation "androidx.core:core-ktx:1.13.1" }
Kotlin
dependencies { implementation("androidx.core:core-ktx:1.13.1") }
Confira a seguir uma lista dos pacotes contidos no módulo Core KTX:
- 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
- androidx.core.transition
- androidx.core.util
- androidx.core.view
- androidx.core.widget
Collection KTX
As extensões Collection trazem funções utilitárias para trabalhar com bibliotecas de coleções
que fazem uso eficiente da memória do Android, incluindo ArrayMap
, LongSparseArray
,
LruCache
e outras.
Para usar este módulo, adicione o seguinte código ao arquivo build.gradle
do seu app:
Groovy
dependencies { implementation "androidx.collection:collection-ktx:1.4.5" }
Kotlin
dependencies { implementation("androidx.collection:collection-ktx:1.4.5") }
As extensões Collection aproveitam a sobrecarga de operadores do Kotlin para simplificar alguns processos, como a concatenação de coleções, conforme a seguir:
// 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
Fragment KTX
O módulo Fragment KTX fornece diversas extensões para simplificar a API do fragmento.
Para incluir este módulo, adicione o seguinte código ao arquivo build.gradle
do seu app:
Groovy
dependencies { implementation "androidx.fragment:fragment-ktx:1.8.5" }
Kotlin
dependencies { implementation("androidx.fragment:fragment-ktx:1.8.5") }
Com o módulo Fragment KTX, é possível simplificar transações fragmentadas com lambdas, por exemplo:
fragmentManager().commit {
addToBackStack("...")
setCustomAnimations(
R.anim.enter_anim,
R.anim.exit_anim)
add(fragment, "...")
}
Você também pode vincular um ViewModel
a uma linha usando as delegações de propriedade 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>()
Lifecycle KTX
O Lifecycle KTX define um LifecycleScope
para cada
objeto Lifecycle
. Qualquer corrotina
iniciada nesse escopo será cancelada quando o Lifecycle
for destruído. Acesse
CoroutineScope
de Lifecycle
usando as
propriedades lifecycle.coroutineScope
ou lifecycleOwner.lifecycleScope
.
Para incluir este módulo, adicione o seguinte código ao arquivo build.gradle
do seu app:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.8.7" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7") }
O exemplo a seguir demonstra como usar lifecycleOwner.lifecycleScope
para
criar um texto pré-computado de forma assíncrona:
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)
}
}
}
LiveData KTX
Ao usar LiveData, talvez seja necessário calcular valores de forma assíncrona. Por exemplo,
caso você queira recuperar as preferências de um usuário e exibi-las na
interface. Para esses casos, o LiveData KTX fornece uma função do builder liveData
que
chama uma função suspend
e veicula o resultado como um objeto LiveData
.
Para incluir este módulo, adicione o seguinte código ao arquivo build.gradle
do seu app:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.7" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.8.7") }
No exemplo a seguir, loadUser()
é uma função de suspensão declarada em outro lugar.
É possível usar a função do builder liveData
para chamar loadUser()
de maneira assíncrona
e, em seguida, usar emit()
para emitir o resultado:
val user: LiveData<User> = liveData {
val data = database.loadUser() // loadUser is a suspend function.
emit(data)
}
Se quiser mais informações sobre o uso de corrotinas com LiveData
, consulte
Usar corrotinas do Kotlin com componentes de arquitetura.
Navigation KTX
Cada componente da biblioteca Navigation tem a própria versão KTX que adapta a API para ser mais sucinta e idiomática para o Kotlin.
Para incluir esses módulos, adicione o seguinte código ao arquivo build.gradle
do seu app:
Groovy
dependencies { implementation "androidx.navigation:navigation-runtime-ktx:2.8.4" implementation "androidx.navigation:navigation-fragment-ktx:2.8.4" implementation "androidx.navigation:navigation-ui-ktx:2.8.4" }
Kotlin
dependencies { implementation("androidx.navigation:navigation-runtime-ktx:2.8.4") implementation("androidx.navigation:navigation-fragment-ktx:2.8.4") implementation("androidx.navigation:navigation-ui-ktx:2.8.4") }
Use as funções de extensão e a delegação de propriedade para acessar os argumentos de destinos e navegar para eles, conforme mostrado no exemplo a seguir:
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)
}
}
...
}
Palette KTX
O módulo Palette KTX tem suporte ao Kotlin idiomático para trabalhar com paletas de cores.
Para usar este módulo, adicione o seguinte código ao arquivo build.gradle
do seu app:
Groovy
dependencies { implementation "androidx.palette:palette-ktx:1.0.0" }
Kotlin
dependencies { implementation("androidx.palette:palette-ktx:1.0.0") }
Por exemplo, ao trabalhar com uma instância Palette
, você pode recuperar a
amostra selected
para um determinado target
usando o operador get ([ ]
):
val palette = Palette.from(bitmap).generate()
val swatch = palette[target]
Reactive Streams KTX
O módulo Reactive Streams KTX permite criar um stream LiveData
observável em
um editor ReactiveStreams
.
Para incluir este módulo, adicione o seguinte código ao arquivo build.gradle
do seu app:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.7" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.7") }
Como exemplo, considere um banco de dados com uma pequena lista de usuários. No app, você
carrega o banco de dados na memória e, depois, exibe os dados do usuário na interface. Para fazer
isso, é possível usar RxJava.
O componente Room
do Jetpack pode recuperar
a lista de usuários como um Flowable
. Nesse cenário, você também precisa gerenciar a assinatura do editor de Rx
durante a vida útil do fragmento ou atividade.
Com LiveDataReactiveStreams
, no entanto, você pode se beneficiar do RxJava e do
amplo conjunto de operadores e recursos de agendamento de tarefa, além de trabalhar com
a simplicidade de LiveData
, como mostrado no exemplo a seguir:
val fun getUsersLiveData() : LiveData<List<User>> {
val users: Flowable<List<User>> = dao.findUsers()
return LiveDataReactiveStreams.fromPublisher(users)
}
Room KTX
As extensões Room são compatíveis com corrotinas para transações de banco de dados.
Para usar este módulo, adicione o seguinte código ao arquivo build.gradle
do seu app:
Groovy
dependencies { implementation "androidx.room:room-ktx:2.6.1" }
Kotlin
dependencies { implementation("androidx.room:room-ktx:2.6.1") }
Confira alguns exemplos de corrotinas usadas com o Room. O primeiro exemplo
usa uma função suspend
para retornar uma lista de objetos User
, enquanto o segundo
usa Flow
do Kotlin
para retornar de maneira assíncrona a lista User
. Observe que, ao usar Flow
, você
também receberá notificações sobre quaisquer mudanças nas tabelas que estiver consultando.
@Query("SELECT * FROM Users")
suspend fun getUsers(): List<User>
@Query("SELECT * FROM Users")
fun getUsers(): Flow<List<User>>
SQLite KTX
As extensões SQLite unem o código relacionado a SQL em transações, eliminando uma grande quantidade de código boilerplate.
Para usar este módulo, adicione o seguinte código ao arquivo build.gradle
do seu app:
Groovy
dependencies { implementation "androidx.sqlite:sqlite-ktx:2.4.0" }
Kotlin
dependencies { implementation("androidx.sqlite:sqlite-ktx:2.4.0") }
Confira um exemplo de como usar a extensão transaction
para executar uma transação
de banco de dados:
db.transaction {
// insert data
}
ViewModel KTX
A biblioteca ViewModel KTX fornece uma função viewModelScope()
que facilita
iniciar corrotinas no ViewModel
. O
CoroutineScope
está vinculado ao Dispatchers.Main
e é cancelado automaticamente
quando o ViewModel
é liberado. Você pode usar viewModelScope()
em vez de
criar um novo escopo para cada ViewModel
.
Para incluir este módulo, adicione o seguinte código ao arquivo build.gradle
do seu app:
Groovy
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.5" }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.5") }
Como exemplo, a seguinte função viewModelScope()
inicia uma corrotina
que faz uma solicitação de rede em uma linha de execução em segundo plano. A biblioteca processa toda a
configuração e a limpeza do escopo correspondente:
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()
}
WorkManager KTX
O WorkManager KTX tem alta compatibilidade com corrotinas.
Para incluir este módulo, adicione o seguinte código ao arquivo build.gradle
do seu app:
Groovy
dependencies { implementation "androidx.work:work-runtime-ktx:2.9.1" }
Kotlin
dependencies { implementation("androidx.work:work-runtime-ktx:2.9.1") }
Agora, em vez de estender Worker
, você pode
estender CoroutineWorker
,
que tem uma API um pouco diferente. Por exemplo, se você quiser criar um CoroutineWorker
simples
para executar algumas operações de rede, faça o seguinte:
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()
}
}
Se quiser mais informações sobre o uso de CoroutineWorker
, consulte
Linhas de execução no CoroutineWorker.
O WorkManager KTX também adiciona funções de extensão a Operations
e
ListenableFutures
para suspender a corrotina atual.
Confira um exemplo que suspende o
Operation
retornado por
enqueue()
:
// Inside of a coroutine...
// Run async operation and suspend until completed.
WorkManager.getInstance()
.beginWith(longWorkRequest)
.enqueue().await()
// Resume after work completes...
Outros módulos KTX
Você também pode incluir módulos KTX adicionais que existam fora do AndroidX.
Firebase KTX
Alguns dos SDKs do Firebase para Android têm bibliotecas de extensão Kotlin que permitem escrever códigos idiomáticos do Kotlin ao usar o Firebase no seu aplicativo. Para mais informações, consulte os seguintes tópicos:
KTX para a Plataforma Google Maps
Há extensões KTX disponíveis para os SDKs do Android da Plataforma Google Maps que permitem aproveitar vários recursos da linguagem Kotlin, como funções de extensão, argumentos padrão e parâmetros nomeados, declarações de desestruturação e corrotinas. Para encontrar mais informações, consulte os seguintes tópicos:
Play Core KTX
O Play Core KTX oferece suporte a corrotinas Kotlin para solicitações únicas e fluxo
para monitoramento de atualizações de status adicionando funções de extensão a
SplitInstallManager
e AppUpdateManager
na biblioteca Play Core.
Para incluir este módulo, adicione o seguinte código ao arquivo build.gradle
do seu app:
Groovy
dependencies { implementation "com.google.android.play:core-ktx:1.8.1" }
Kotlin
dependencies { implementation("com.google.android.play:core-ktx:1.8.1") }
Confira um exemplo de monitoramento de status Flow
:
// 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()
}
}
Mais informações
Para saber mais sobre o Android KTX, assista ao vídeo DevBytes (em inglês).
Para informar um problema ou sugerir um recurso, use o Issue Tracker do Android KTX.