Android KTX | Part of Android Jetpack .
Android KTX is a set of Kotlin extensions included in Android Jetpack and other Android libraries. The KTX extension can provide simple and idiomatic Kotlin code for Jetpack, the Android platform and other APIs. To this end, these extensions take advantage of a variety of Kotlin language features, including:
- Extension function
- Extended attributes
- Lambda
- Named parameters
- Parameter default value
- Coroutine
For example, the use SharedPreferences
, you must first create an editor before you can modify preferences data. After making the modifications, you must also apply or submit these changes, as shown in the following example:
sharedPreferences
.edit() // create an Editor
.putBoolean("key", value)
.apply() // write to disk asynchronously
Kotlin lambda is very suitable for this use case. They allow you to take a more concise approach, which is to pass a block of code to be executed after the editor is created, let the code execute, and then let the SharedPreferences
API apply the changes atomically.
The following is a function Android KTX Core SharedPreferences.edit
of example, in the present example to SharedPreferences
add an edit function. This function is an optional boolean
sign as the first parameter, indicating whether or not to submit or apply the changes. In addition, it receives in the form of lambda to the SharedPreferences
operation performed on the editor.
// 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) }
The caller can choose whether to submit or apply the changes. action
lambda itself is SharedPreferences.Editor
an anonymous function on the extension, it returns Unit
, such as its signature indicated. Thus, in the code block, it can be directly SharedPreferences.Editor
performed on the work.
Finally, the SharedPreferences.edit()
signature contains inline
the keyword. This keyword indicates to the Kotlin compiler that every time a function is used, it should copy and paste (or inline) the compiled bytecode for the function. This can avoid this each time for each function call action
overhead instance of a new class generated.
Using lambda pass code, application of reasonable default values may be replaced using inline
extension functions to add to an existing API which acts in this model is typically Android KTX enhancements provided by the library.
Use Android KTX in the project
To start using Android KTX, add the following dependency to the project build.gradle
file:
repositories {
google()
}
AndroidX module
Android KTX is divided into several modules, and each module contains one or more software packages.
You must use the build.gradle
add files for each module piece dependencies. Be sure to include the version number behind the workpiece. You can find the latest version number in the corresponding section of each artifact in this topic.
Android KTX includes a core module that can provide Kotlin extensions for common framework APIs, and it can also provide some domain-specific extensions.
In addition to the core module, the workpiece will replace all modules KTX build.gradle
underlying Java file dependencies. For example, you can androidx.fragment:fragment
rely item replaced androidx.fragment:fragment-ktx
. This syntax helps to better manage version control without adding additional dependency declaration requirements.
Core KTX
The Core KTX module provides extensions for common libraries belonging to the Android framework. You do not need to add these libraries to build.gradle
Java-based dependencies.
To use this module, add the following to the application build.gradle
file:
dependencies { implementation "androidx.core:core-ktx:1.3.2" }
The software packages included in the Core KTX module are listed below:
- 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
Collection extension includes Android utility function used in the library set to save memory, comprising ArrayMap
, LongParseArray
, LruCache
and the like.
To use this module, add the following to the application build.gradle
file:
dependencies { implementation "androidx.collection:collection-ktx:1.1.0" }
The Collection extension uses Kotlin's operator overloading to simplify operations such as collection concatenation, as shown in the following example:
// 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
The Fragment KTX module provides a series of extensions to simplify the Fragment API.
To use this module, add the following to the application build.gradle
file:
dependencies { implementation "androidx.fragment:fragment-ktx:1.2.5" }
With the Fragment KTX module, you can use lambda to simplify Fragment transactions, for example:
fragmentManager().commit {
addToBackStack("...")
setCustomAnimations(
R.anim.enter_anim,
R.anim.exit_anim)
add(fragment, "...")
}
You can also use viewModels
and activityViewModels
property entrusted to bind in a row ViewModel
:
// 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
Lifecycle KTX for each Lifecycle
defining an object LifecycleScope
. Within this range start coroutine will Lifecycle
be canceled when it is destroyed. You can use lifecycle.coroutineScope
or lifecycleOwner.lifecycleScope
property access Lifecycle
is CoroutineScope
.
To use this module, add the following to the application build.gradle
file:
dependencies { implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0" }
The following example demonstrates how to use lifecycleOwner.lifecycleScope
asynchronous create pre-computed text:
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
When using LiveData, you may need to calculate values asynchronously. For example, you may need to retrieve the user’s preferences and transmit them to the interface. In these cases, LiveData KTX provide a liveData
builder function that calls suspend
the function, and as a result of LiveData
object transfer.
To use this module, add the following to the application build.gradle
file:
dependencies { implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0" }
In the following example, it loadUser()
is the suspend function declared elsewhere. You can use the liveData
builder function asynchronous call loadUser()
, then use emit()
to issue the results:
val user: LiveData<User> = liveData {
val data = database.loadUser() // loadUser is a suspend function.
emit(data)
}
For more information about how to co-process and LiveData
used together, refer to the process used in conjunction with the Association of Kotlin architectural components .
Navigation KTX
Each component of the Navigation library has its own KTX version, which is used to adjust the API to make it more concise and more in line with Kotlin's language habits.
To add these modules, add the following to the application build.gradle
file:
dependencies { implementation "androidx.navigation:navigation-runtime-ktx:2.3.1" implementation "androidx.navigation:navigation-fragment-ktx:2.3.1" implementation "androidx.navigation:navigation-ui-ktx:2.3.1" }
You can use extension functions and property delegates to access target parameters and navigate to the target, as shown in the following example:
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)
}
}
...
}
KTX Palette
The Palette KTX module provides idiomatic Kotlin support for using palettes.
To use this module, add the following to the application build.gradle
file:
dependencies { implementation "androidx.palette:palette-ktx:1.0.0" }
For example, using Palette
an instance, operator can use the get ( [ ]
) to retrieve a set target
of selected
color samples:
val palette = Palette.from(bitmap).generate()
val swatch = palette[target]
Reactive Streams KTX
Use Reactive Streams KTX module according ReactiveStreams
to create a publisher can monitor the LiveData
flow.
To use this module, add the following to the application build.gradle
file:
dependencies { implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.2.0" }
For example, suppose a database has only a few users. In your application, you load the database into memory, and then display user data in the interface. For this, you can use RxJava . Room
Jetpack component capable of Flowable
retrieving a user list form. In this case, you must also manage Rx publisher subscriptions throughout the life cycle of the Fragment or Activity.
However, with LiveDataReactiveStreams
, you can either take advantage of its rich RxJava operator functions and organization of work, you can enjoy LiveData
the simplicity, as shown in the following example:
val fun getUsersLiveData() : LiveData<List<User>> {
val users: Flowable<List<User>> = dao.findUsers()
return LiveDataReactiveStreams.fromPublisher(users)
}
Room KTX
The Room extension adds coroutine support for database transactions.
To use this module, add the following to the application build.gradle
file:
dependencies { implementation "androidx.room:room-ktx:2.2.5" }
Below are a few examples of Room currently using coroutines. The first example uses the suspend
function returns User
the object list, the second example of the use of Kotlin Flow
asynchronous returned User
list. Note that using Flow
, you will be notified about the table you are querying any changes.
@Query("SELECT * FROM Users")
suspend fun getUsers(): List<User>
@Query("SELECT * FROM Users")
fun getUsers(): Flow<List<User>>
SQLite KTX
The SQLite extension encapsulates SQL-related code in a transaction, thereby avoiding writing a lot of boilerplate code.
To use this module, add the following to the application build.gradle
file:
dependencies { implementation "androidx.sqlite:sqlite-ktx:2.1.0" }
Here is an transaction
example of an extended program to perform database transactions:
db.transaction {
// insert data
}
ViewModel KTX
ViewModel KTX library provides a viewModelScope()
function that allows you to more easily from ViewModel
start coroutine . CoroutineScope
Bind to Dispatchers.Main
, and will clear ViewModel
automatically canceled after. You can use viewModelScope()
, without the need for each ViewModel
to create a new range.
To use this module, add the following to the application build.gradle
file:
dependencies { implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0" }
For example, the following viewModelScope()
function will start a coroutine, a network request for a background thread. The library will handle all settings and the corresponding range clearing:
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
WorkManager KTX provides first-class support for coroutines.
To use this module, add the following to the application build.gradle
file:
dependencies { implementation "androidx.work:work-runtime-ktx:2.4.0" }
Now, you don't need to extend Worker
, but you can extend CoroutineWorker
, the latter uses a slightly different API. For example, if you want to build a simple CoroutineWorker
to perform some network operation, it is necessary to perform the following operations:
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()
}
}
For details on how to use it CoroutineWorker
, see Threading in CoroutineWorker .
In addition, WorkManager KTX also to Operations
and ListenableFutures
add an extension function to pause the current coroutine.
The following is a pause enqueue()
returned Operation
an example:
// Inside of a coroutine...
// Run async operation and suspend until completed.
WorkManager.getInstance()
.beginWith(longWorkRequest)
.enqueue().await()
// Resume after work completes...
Other KTX modules
You can also add other KTX modules that exist outside of AndroidX.