Does Injecting many dependencies in a ViewModel affect the performance? - kotlin

Does Injecting too many dependencies using dagger hilt in a ViewModel affect the performance of an android application?

As far as I know, increasing dependency will just increase build time for dagger hilt as dagger hilt provide dependency at compile time. So, it will not affect app performance.

Related

How to implement custom platform logic using Kotlin Multiplatform feature?

Kotlin Multiplatform is a good feature to build multiplatform applications, but currently it is (likely) restricted to be intrinsic in Kotlin Multiplatform ecosystem. Can I implement custom build logic to extend the resolution strategy of expect, actual and the like? Or to say treat these features as a general concept of multiplatform, but have different behaviors during build process. Gradle work is welcomed.
For example, if the related extension points were available, one could write a Kotlin compiler plugin to resolve those expect/actual endpoints and maybe compose them into actually platform-specific runtime logic, and then write a Gradle plugin to ultimately process these artifacts.
So if there were two "multiplatform" scenes where both use jvm as "backend", but provide different api with the same or similar logic as "frontend", one could do as above to provide benefits which Kotlin Multiplatform does - write once, run anywhere.
I'd prefer to call this "api-layer multiplatform", to differ that Kotlin Multiplatform is "system-layer multiplatform". "Platform" could be a more abstract one.
So here is what the producer does, just like Kotlin Multiplatform:
build.gradle.kts:
plugins {
kotlin("jvm")
id("<multiplatform-plugin-id>") // Comes with Kotlin compiler plugin too
}
dependencies {
api("<common-dependency-notation>") // Another multiplatform library
}
common module:
fun hello() {
val logger = serviceLogger // Using api from that another multiplatform library
logger.info("Hello")
}
expect fun hookOnStart(block: () -> Unit) // Needs to provide platform-specific implementations
platform module:
actual fun hookOnStart(block: () -> Unit) { // Imaginary
ClientEvents.START.register(block)
}
anotherPlatform module:
actual fun hookOnStart(block: () -> Unit) { // Imaginary
val event = EventFactory.once(ClientStartEvent::class.java, block)
GlobalEventHandler.register(event)
}
As said before, after build, each platform will have its own artifact prepared for runtime or provided as library. He benefits from that another multiplatform library because he could provide each platform with same features through sharing code.
And the following is what the consumer does: (Let's say he's on platform)
build.gradle.kts
plugins {
kotlin("jvm")
}
dependencies {
implementation("<previous-common-dependency-notation>") // From the previous author, mapped to `platform` version
}
Bussiness logic:
fun runBussiness() {
hello()
hookOnStart { serviceLogger.info("world!") }
}
This is pretty uncharted territory and without any documentation.
I'd investigate the source code of the kotlin-multiplatform gradle plugin more in-depth and see if you can extend the existing target palette and expect/actual behaviour.
I'd guess that the plugin isn't really built for this kind of extension, but if you have solid reasons, you could probably submit feature requests and work on a local fork in the meantime.
Update:
If I understood your use-case correctly, you'd like to extend the expect/actual mechanism, which is currently a target/platform based abstraction?
I believe a more general way of making abstractions, such as using interfaces, could serve you. However, I can see the added compile-time safety benefits you seek 🤔, not sure what changes that'd need in the kotlin-multiplatform plugin and if JetBrains team would like that direction. Maybe something Artyom Degtyarev or someone from the JetBrains team could answer?

What's the different between native-mt and normal kotlin coroutine lib?

When we use coroutine, we can either have the normal kotlin coroutine or the native-mt version.
i.e.
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0'
or
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0-native-mt'
Is there any difference between them? When should we use which?
It basically provides capability to use multiple threads in Kotlin/Native code (typically as part of a Kotlin Multiplatform (KMP) project). Some more info at https://kotlinlang.org/docs/mobile/concurrency-and-coroutines.html#multithreaded-coroutines. This is also version used now by many KMP libraries (e.g. Ktor) and is generally a requirement when developing KMP apps.

Concurrent Hash Map in Kotlin

Is it possible to implement a concurrent hash map purely in Kotlin (without Java dependency)? I am new to Kotlin and it looks like there is no obvious API available in kotlin.collections.
You can probably convert the source without too many issues. It's freely available, here for example. The concurrency model of Kotlin multiplatform (which I'm guessing is your goal, there's no point in reimplementing it if you only target the JVM) is a bit different than the one Java uses, there are no locks for example. But there's no reason why that would prevent it.
The following resources might also help you with the implementation:
Concurrency in Kotlin/Native
kotlin.native.concurrent package
Replacement for synchronized
Official Kotlin/Native Concurrency tutorial
You can try:
val emitters: ConcurrentMap<String, Any> = ConcurrentHashMap()
// get
val obj: Any = emitters[email]
// put:
emitters[email] = this
// delete
emitters.remove(email)
Such way, u don't need to add any library to your project

How to do method instrumentation in Kotlin - but keep it method testable

I have a method that I need to instrument to call New Relic: setup a segment, run the business logic and end the segment. Is there a way to do it in Kotlin (as in Spring AOP)?
fun saveCustomer() {
val segment = NewRelic.getAgent().transaction.startSegment("save customer")
// business logic here
segment.end()
}
I experimented isolating newRelic dependency and can now reuse it across my whole app:
fun saveCustomer() {
newRelic.executeWithSegment { // this starts/ends the segment and calls the function block
// business logic here
}
}
However, this makes unit testing of saveCustomer harder, because after mocking newRelic.executeWithSegment (which I must; otherwise New Relic is contacted in the tests), the code block (business logic) is not executed anymore - so the test fails.
Is there a way to fulfill those requirements? (Perhaps with an annotation or using Kotlin delegation pattern or even some lightweight library; not sure.)
You can use AspectJ.
It is independent of Spring, more powerful and more efficient (no proxies) than Spring AOP.
It should work with any JVM language, although I never tried with Kotlin as a target for my aspects.
If you do compile-time weaving, the AspectJ runtime is the only dependency you need. Its size is 120K.
For load-time weaving you need the AspectJ weaving agent instead. Its size is 1.9M.

Kotlin Coroutines dependency going into Overload Resolution Ambiguity

I'm having a production ready Kotlin code and I want to refactor it from changing all CompletableFuture requests to Coroutines, but when I add the compile('org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.0') dependecy tu build.gradle, all my kotlin.collections imports are going into "Overload resolution ambiguity". Does anybody knows how to deal with this problem?
Here is a snippet from my code:
TX!
Generally this happens when indexes get stale in IDEA. Try to build with gradle to ensure there is no real clashes. Running File -> Invalidate caches / Restart should help.