ANDROID
Kotlin Extensions
Top 10 Kotlin extensions used in Android App Development by Google Developers.
Overview
In this article, we will make some cool Android Extensions in Kotlin Programming Language.
Official definition
Kotlin provides the ability to extend a class with new functionality without having to inherit from the class or use design patterns such as Decorator. This is done via special declarations called extensions.
Don’t think about Decorator too much. It is a design pattern that allows a user to add new functionality to an existing object without altering its structure.
In this article, we will divide the extensions into 3 parts to make them easier to understand.
- View Extensions — we will use these to play with UI elements.
- General Extensions — these will be used to execute some general tasks.
- Background Extensions — And these will help us in performing our background tasks easier.
We will discuss at least 2 extensions of each type and rest you can check out on GitHub.
Note: The background extensions which we will be discussing are also used by Google Developers so must check them out and should use those in your code.
Prerequisite
Should have knowledge of basic kotlin syntax.
Resources
View Extensions
We often require to change the visible state of a view and to show some Toast or Snackbar for a particular event. Here, we will make extensions to simplify those functionality.
In extensions, you can name the function
anything you want and when you extend any object such as View
, Activity
, or Context
that means you are in the scope of that object by which you can change its properties directly as we have done above.
We can also overload
a function, like:
Now, let’s use them in our project.
General Extensions
We often require to refresh a list by removing the existing items and updating them with the new ones or sometimes we need to check the permission status in our app to access some features. So here, we will make Collections
and Permission
extensions.
The Generic
type is specified in the above List
extensions to avoid making different extensions for different Object
types.
Background Extensions: used by Google Developers
For most of the apps, the background tasks can be easily executed using Coroutines which includes API call and DB operations. To know more about that, click here.
To execute a background task, we generally make a function suspend
and then call it in a CoroutineScope. Also, suspend
functions can only be executed in a CoroutineScope.
In the above extension, we are passing a block
and a Context
as arguments in the extension function. The block is a suspend function which we are executing in a coroutine context which viewModelScope.launch
provides us.
Here, we have wrapped the block in a try/catch
block to handle the crashes which may occur which executing an API
call.
Before moving to the second extension, there is a ControlledRunner
class which I have imported from one of Google’s project.
You can check out that class by clicking on the link given below.
It contains 2 suspend
functions:
1. cancelPreviousThenRun : It is used in the scenarios where we want to cancel all the currently executing calls and in the place of that we want to execute a new call.
2. joinPreviousOrRun: It is used where we want to check whether there is a call that is currently executing and if yes then return the result of that call else make a new call.
We will be making extensions of those functions.
In the above extensions, we are just extending a class to execute a suspend function from the class’s functions.
You will better understand when you will see the use.
In our loadRequest
extension, we are passing a context to show a toast in case of an exception. To get the application context in the view model, we can make use of AndroidViewModel
instead of ViewModel
so with that we don’t have to pass the context from a view.
With the load request extension, we can call any suspend function without suspending the parent function and since we using try/catch block, the exception will be captured easily in it. So with this, we can execute our background tasks more easily.
While initializing the controlled runner, we have to pass the response which we are expecting from the function that we will execute in that controlled runner extension. In the example above, I am expecting a String response but if I was expecting LoginResponse then controlledRunner will be val runner = ControlledRunner<LoginResponse>()
And since our controlled runner extensions are the suspend functions so they need to be executed in a coroutine scope and that we can get from our loadRequest
extension.
Let’s take an example: If there is an API call that gets called at a button click, so in case of double click we want to cancel the request which was started earlier and then start a new call. So for that, we will use the cancelPreviousThenRun
extension which will provide us that functionality.