Android KTX developed by Android Kotlin

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 SharedPreferencesAPI apply the changes atomically.

The following is a function Android KTX Core SharedPreferences.editof example, in the present example to SharedPreferencesadd an edit function. This function is an optional booleansign 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 SharedPreferencesoperation 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. actionlambda itself is SharedPreferences.Editoran anonymous function on the extension, it returns Unit, such as its signature indicated. Thus, in the code block, it can be directly SharedPreferences.Editorperformed on the work.

Finally, the SharedPreferences.edit()signature contains inlinethe 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 actionoverhead instance of a new class generated.

Using lambda pass code, application of reasonable default values may be replaced using inlineextension 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.gradlefile:

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.gradleadd 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.gradleunderlying Java file dependencies. For example, you can androidx.fragment:fragmentrely 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.gradleJava-based dependencies.

To use this module, add the following to the application build.gradlefile:

dependencies {
    implementation "androidx.core:core-ktx:1.3.2"
}

 

The software packages included in the Core KTX module are listed below:

Collection KTX

Collection extension includes Android utility function used in the library set to save memory, comprising ArrayMap, LongParseArray, LruCacheand the like.

To use this module, add the following to the application build.gradlefile:

    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.gradlefile:

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 viewModelsand activityViewModelsproperty 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 Lifecycledefining an object LifecycleScope. Within this range start coroutine will Lifecyclebe canceled when it is destroyed. You can use lifecycle.coroutineScopeor lifecycleOwner.lifecycleScopeproperty access Lifecycleis CoroutineScope.

To use this module, add the following to the application build.gradlefile:

    dependencies {
        implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
    }
    

 

The following example demonstrates how to use lifecycleOwner.lifecycleScopeasynchronous 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 liveDatabuilder function that calls suspendthe function, and as a result of LiveDataobject transfer.

To use this module, add the following to the application build.gradlefile:

    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 liveDatabuilder 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 LiveDataused together, refer to the process used in conjunction with the Association of Kotlin architectural components .

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.gradlefile:

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.gradlefile:

    dependencies {
        implementation "androidx.palette:palette-ktx:1.0.0"
    }
    

 

For example, using Palettean instance, operator can use the get ( [ ]) to retrieve a set targetof selectedcolor samples:

val palette = Palette.from(bitmap).generate()
val swatch = palette[target]

 

Reactive Streams KTX

Use Reactive Streams KTX module according ReactiveStreamsto create a publisher can monitor the LiveDataflow.

To use this module, add the following to the application build.gradlefile:

    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 . RoomJetpack component capable of Flowableretrieving 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 LiveDatathe 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.gradlefile:

    dependencies {
        implementation "androidx.room:room-ktx:2.2.5"
    }
    

 

Below are a few examples of Room currently using coroutines. The first example uses the suspendfunction returns Userthe object list, the second example of the use of Kotlin Flowasynchronous returned Userlist. 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.gradlefile:

    dependencies {
        implementation "androidx.sqlite:sqlite-ktx:2.1.0"
    }
    

 

Here is an transactionexample 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 ViewModelstart coroutine . CoroutineScopeBind to Dispatchers.Main, and will clear ViewModelautomatically canceled after. You can use viewModelScope(), without the need for each ViewModelto create a new range.

To use this module, add the following to the application build.gradlefile:

    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.gradlefile:

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 CoroutineWorkerto 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 Operationsand ListenableFuturesadd an extension function to pause the current coroutine.

The following is a pause enqueue()returned Operationan 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.

 

Guess you like

Origin blog.csdn.net/MYBOYER/article/details/109468272