Kotlin extension overhead for Android - android

It´s a good idea to use kotlin extensions all over the code?
I miss a lot the extensions from iOS, but this is a good way to use those kind of things in android?
Refering to http://antonioleiva.com/kotlin-android-extension-functions/
Is there a better solution for this?

To expand a little bit more on Andrey Breslav's answer a bit, Kotlin extension functions do compile down to static java methods, so most general purpose extension functions carry no overhead. But there is one edge case you need to look out for that Jake Wharton calls out in the first few min of this talk at Google IO.
That is when you pass in higher order functions (lambdas), as a parameter to the extension function like so:
fun View.doSomething(block: () -> Unit) {
//do something
}
This code would take a performance hit because lambda's under the hood have to create an anonymous class under the hood which can eat up methods and cause class loading. This is a very simple fix by adding the inline keyword to the function which will essentially inline your code into all of this call sites functions so you will not take a performance hit each time the extension function is called.
inline fun View.doSomething(block: () -> Unit) {
//do something
}

Extension functions in Kotlin are compiled to normal Java methods. For example, when you define a function in your package it turns into a static method in a Java class. There's no overhead compared to simply calling a static utility

Related

Why should we use interface in MVP pattern for Android?

I'm making an Android app using Kotlin for the first time using MVP pattern. My questions is, why do I need interfaces for View and Presenter as Kotlin provides higher order functions? Can't we just communicate using those higher order functions? Is the use of pattern without interfaces bad?
I have looked and read lots of article and tutorials but non answered my question. Is what I am doing in the code below a wrong practice? Can someone explain it to me?
In my Activity
override fun init() {
btn_login.setOnClickListener {
LoginPresenter.userLogin(et_emailAddress.text.toString(),et_password.text.toString()){
if (it){
//do something
}else{
//do something
}
}
}
}
My Presenter
object LoginPresenter {
fun userLogin(emailId: String, password: String, completion: (Boolean) -> Unit) {
//do something
completion(true)
}
}
Higher-order function costs
Kotlin official documentation on the cost of higher order functions
Using higher-order functions imposes certain runtime penalties: each
function is an object, and it captures a closure, i.e. those variables
that are accessed in the body of the function. Memory allocations
(both for function objects and classes) and virtual calls introduce
runtime overhead.
and if you're replacing all your interfaces with higher-order functions, you may end up with a bad performance.
2.
Interfaces can hold multiple functions, for which you'll need individual function params when using higher-order functions.
Consider the following case,
interface UserLoginInterface {
fun onLoginSuccess(loggedInUser: User)
fun onLoginFailure(error: ErrorResponse)
fun onRedirect(someOtherObjectWithDirectives: SomeDataClass)
}
To translate this to higher-order functions usage, You'll have to use three Function params
why do I need interfaces for View and Presenter as Kotlin provides higher order functions?
This is rather a common practice in software development. And while you may not use interfaces, there is a number of key points why interfaces are preferable. Off the top of my head:
with interface you can have multiple implementations of it without actually caring about the concrete type of the implementation. This is what you're missing with the higher order functions - you're restricted with the only type, LoginPresenter, when using the LoginPresenter.userLogin() method.
most of the design patterns is based on the separation of interfaces from their implementations. So programming into implementation rather than abstraction won't let you make use of those.
you won't be able to properly unit test classes that depend on other implementations as no mocking is possible in this case.
code maintenance and extension becomes much harder with concrete implementation.

Kotlin Extension functions to split big classes

Recently at my company a debate started after reviewing a different approach for writing heavy duty classes.
A big Java class holding component specific logic (no standard OOP principles made sense) had to be rewritten in Kotlin. The solution provided was splitting the logic in categories and the categories into separate files with internal extension functions to the main class.
Example:
Main.kt
class BigClass {
// internal fields exposed to the extension functions in different files
// Some main logic here
}
BusinessLogic.kt
internal fun BigClass.handleBussinessCase() {
// Complex business logic handled here accessing the exposed internal fields from BigClass
}
What are your thoughts on this? I haven't seen it used anywhere maybe for a good reason, but the alternative of thousand lines classes seems worse.
You have to consider that an extension function is nothing more than a function with an implicit first parameter which is referenced with this.
So in your case you'd have something like:
internal fun handleBussinessCase(ref: BigClass)
which would translate to Java as:
static void handleBussinessCase(BigClass ref)
But this could be assumed to be a delegate pattern, which could be encapsulated much cleaner in Kotlin as well.
Since the properties have to be internal anyhow, you could just inject these as a data class into smaller use-cases. If you define an interface around these (which would make the properties public though), you could create a delegate pattern with it and still reference each property with this in your implementation.
Here are some thoughts on making extension functions for the class:
It will be a utility function that will operate with the object you're extending, it will not be an object function, meaning that it will have access to only public methods and properties;
If you're planning to use class that being extended in unit tests, these methods (extensions) will be harder to mock;
Most likely they wont behave as you expect when used with inherited objects.
Maybe I missed something, so please read more about extensions here.

Kotlin - can i use an extension for method overloading?

I have created a custom view in android. one of the methods has a signature like this:
fun show(CategoryFilterModel model) {/*...*/}
and it works fine. and now i'd like to create a overloaded function which would look like this if i did it by adding it to the custom view class:
fun show(ShopFilterModel model) {/*...*/}
Notice the type is different so this is a method overload.
a thought came to me that i could instead use an extension in kotlin to add another method to the class.
so it would like something like this:
fun MyCustomView.show(ShopFilterModel: model){
}
is this advised or should i only add utility methods with extensions ? Are there any overheads ?
It’s not only for utilities, as you can read in this great answer, which lists pretty much all use cases.
Imho, if you have control over that class you want to extend with a method, there’s no problem to add the method directly to it as opposed to doing it with an extension method. Yet, technically you can consider doing this. Please be aware that calling such an extension function from Java isn’t very idiomatic because it will be compiled to a static function. If it’s ever going to be invoked from Java, I’d rather use ordinary methods when possible.

Why use inline without lambdas

I'm trying to understand how to use inline modifier correctly. I understand general case, when we inlining lambda to prevent excess allocation, as described in docs.
I was inspecting kotlin stdlib and found in _Strings.kt the following piece of code:
#kotlin.internal.InlineOnly
public inline fun CharSequence.elementAtOrNull(index: Int): Char? {
return this.getOrNull(index)
}
What's the reasoning behind using inline here?
This particular function and a few others in kotlin-stdlib are marked as #InlineOnly so that they are not present in the actual stdlib class files and are only available for the Kotlin compiler to inline them. The goal that is achieved in this way is reducing the methods count in the artifacts, which matters for Android.
Apart from that, using inline functions without lambdas is useful for reifying type parameters.
There is still overhead, no matter how minor, that can be avoided.
A similar discussion on Inline Extension Properties.
A post on Kotlin Extensions which gets down into the bytecode effects
I would say that is related to efficiency. Instead of calling functions elementAtOrNull and thus, getOrNull this one is directly called.

Android studio convert to Kotlin: Use #JvmStatic in some cases

I have been using Kotlin over Android for quite intensively. It does make programming fun again.
Still, in some cases (mostly util classes where the name should be short and handy), when automatically converting Java to Kotlin, I would love to have an option to use #JvmStatic on static methods rather than converting callers to MyClass.Companion.Bar.
That is, in some specific cases, it would be nice to have
public static foo(Barian bar)
converted to
#JvmStatic
fun foo(bar:Barian)
so I can maintain the short calling syntax from Java:
MyClass.foo(bar)
rather than
MyClass.Companion.foo(bar)
Obviously, in most cases I agree it's bad manners for many reasons such as future compatibility, non-Kotlin spirit and many more, but in a few cases it can keep Java code (that uses my classes) shorter.
You don't need to specify the Companion-namespace explicitly, when you decalre your "static" method like this:
class MyClass {
companion object {
fun foo() {}
}
}
In this case you still can call it via:
MyClass.foo()
But nevertheless having static methods is not a Kotlin-idiomic way and should be avoided by using other features of this language.

Categories

Resources