# Stories by Danny Preussler on Medium

Stories by Danny Preussler on Medium

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## Interpreting voice results for Android media apps in cars

DevFeed: [Interpreting voice results for Android media apps in cars](<https://devfeed.tech/articles/interpreting-voice-results-for-android-media-apps-in-cars-25891.md>)

Original publisher: [Read original article](<https://proandroiddev.com/interpreting-voice-results-for-android-media-apps-in-cars-f36d7bdb26e1?source=rss-1331e67af4e1------2>)

Author: Danny Preussler

Published: 2022-01-10T21:33:42Z

Content type: tutorial

Language: en

Sources: [Stories by Danny Preussler on Medium](<https://devfeed.tech/sources/stories-by-danny-preussler-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [App](<https://devfeed.tech/topics/app.md>), [Code](<https://devfeed.tech/topics/code.md>), [Query (disambiguation)](<https://devfeed.tech/topics/query.md>), [Google](<https://devfeed.tech/topics/google.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [android-auto](<https://devfeed.tech/tags/android-auto.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [apps](<https://devfeed.tech/tags/apps.md>), [audio](<https://devfeed.tech/tags/audio.md>), [callback](<https://devfeed.tech/tags/callback.md>), [car](<https://devfeed.tech/tags/car.md>), [code](<https://devfeed.tech/tags/code.md>), [google](<https://devfeed.tech/tags/google.md>), [google-assistant](<https://devfeed.tech/tags/google-assistant.md>), [integration](<https://devfeed.tech/tags/integration.md>), [manifest](<https://devfeed.tech/tags/manifest.md>), [voice](<https://devfeed.tech/tags/voice.md>)

### AI overview

This article explains how Android Auto voice searches are delivered to a music app such as SoundCloud. It compares the documented use of MediaStore.EXTRA_MEDIA_FOCUS with observed behavior, reporting that Assistant currently returns a focus value that is not defined as an SDK constant.

### Source excerpt

When working on the Android Auto integration for SoundCloud, I stumbled upon an interesting issue. When it comes to implementing voice actions, things you read in the documentation might differ a bit from reality. Voice commands are very critical while driving a car. You want the driver to keep looking at the street, keep his hands on the steering wheel, instead of interacting with any screen. This is why when building for Android Auto, Automotive OS, and Assistant Driving Mode you have to support basic voice searches. For a music app like ours, the idea is simple. A user can say something like: "Play Moderat on SoundCloud" Under the hood The Assistant will break down our sentence for interpretation: "<Play> <Moderat> <on SoundCloud>" The verb (Play) and the app (SoundCloud) in the above command were meant for the system. It will then wake up the app mentioned (if it declared auto support via manifest) and, as we asked for verb "Play", the method MediaSessionCompat.Callback.onPlayFromSearch() will be called with the remaining query ("Moderat") as the argument. This query of "what to play" can still mean different things though. How do you know if Moderat is a band or a song? Don't worry, the Assistant will help us also here. It already got some idea what our query could mean, if we asked for an artist, an album, or a specific track. But be aware, it behaves slightly differently than officially documented. According to documentation we are supposed to write code like this: val mediaFocus = extras?.getString(MediaStore.EXTRA_MEDIA_FOCUS) if (mediaFocus == MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) { isArtistFocus = true artist = extras.getString(MediaStore.EXTRA_MEDIA_ARTIST) We are suppose to check for a bundle entry with the key MediaStore.EXTRA_MEDIA_FOCUS . This will give us a hint on how best to interpret the query. The value of the constant MediaStore.EXTRA_MEDIA_ARTIST checked above is vnd.android.cursor.item/artist and there are similar constants related to

## Using the Kotlin standard library in Java

DevFeed: [Using the Kotlin standard library in Java](<https://devfeed.tech/articles/using-the-kotlin-standard-library-in-java-25888.md>)

Original publisher: [Read original article](<https://medium.com/google-developer-experts/using-the-kotlin-standard-library-in-java-ea0766deac10?source=rss-1331e67af4e1------2>)

Author: Danny Preussler

Published: 2021-06-14T19:01:08Z

Content type: tutorial

Language: en

Sources: [Stories by Danny Preussler on Medium](<https://devfeed.tech/sources/stories-by-danny-preussler-on-medium.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Java](<https://devfeed.tech/topics/java.md>), [Library](<https://devfeed.tech/topics/library.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [collections](<https://devfeed.tech/tags/collections.md>), [dependencies](<https://devfeed.tech/tags/dependencies.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-beginners](<https://devfeed.tech/tags/kotlin-beginners.md>), [kotlin-standard-library](<https://devfeed.tech/tags/kotlin-standard-library.md>), [libraries](<https://devfeed.tech/tags/libraries.md>), [standard-library](<https://devfeed.tech/tags/standard-library.md>)

### AI overview

This tutorial explains how Java code can use Kotlin standard-library functions through static imports. It covers list creation, Kotlin free functions compiled into classes, and extension functions exposed to Java with the receiver as the first argument.

### Source excerpt

Using the Kotlin standard library from Javagiphy.com If you work with Kotlin on a daily basis you probably love the language and don't want to go back to Java. Though, many of us work on a codebase that isn't purely Kotlin. Our Android codebase at SoundCloud still has a fair amount of code written in Java. This percentage gets smaller over time but there is no urgent need for mass migration of the remains right now. Therefore, every once in a while, I find myself, changing Java files. In those cases, I miss some of the Kotlin functions I'm used to; I can easily think of string manipulation or handling collections as examples. Of course, Java has powerful utility libraries such as Googles Guava or Apache Commons, libraries many of which we used to work with in the world before Kotlin. But when writing Kotlin code all day, remembering those "older" APIs is sometimes hard. It is a complete context switch. It would be much easier to use what we use in Kotlin. And you should! Let me show you! Let's assume we want to create a list of items. In Kotlin, we would write: val items = listOf( items1, item2, item3 ) In Java, I would write it as: List<Item> items = Arrays.asList(item1, item2, items3); Usage is pretty much the same but you still need to remember the name of the function. Wouldn't it be easier to just use: List<Item> items = listOf(item1, item2, items3); And yes you can! All you need to do is to static importthat function! This works aslistOf, like many of our daily Kotlin utility functions, are simply static functions you can use from Java. And even better, as your project already uses Kotlin, you already got those dependencies included anyway, no additional library needed. A closer look If you would click on the details of listOf from Kotlin, you would end up in a file called Collections.kt and the definition looks like this: public fun <T> listOf(vararg elements: T): List<T> It is a free function, not bound to any class. But from a Java perspective this looks so

## Understanding Kotlin property finality and compiler-opened classes

DevFeed: [Understanding Kotlin property finality and compiler-opened classes](<https://devfeed.tech/articles/the-modifier-that-shouldn-t-be-there-25894.md>)

Original publisher: [Read original article](<https://proandroiddev.com/the-modifier-that-shouldnt-be-there-77ff941f0529?source=rss-1331e67af4e1------2>)

Author: Danny Preussler

Published: 2021-05-31T14:15:00Z

Content type: tutorial

Language: en

Sources: [Stories by Danny Preussler on Medium](<https://devfeed.tech/sources/stories-by-danny-preussler-on-medium.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Android Studio](<https://devfeed.tech/topics/android-studio.md>), [Compiler](<https://devfeed.tech/topics/compiler.md>), [Testing](<https://devfeed.tech/topics/testing.md>)

Tags: [android-studio](<https://devfeed.tech/tags/android-studio.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [programming](<https://devfeed.tech/tags/programming.md>), [testing](<https://devfeed.tech/tags/testing.md>)

### AI overview

This article explains when Kotlin properties are final or open, including why properties inherited from interfaces may be open by default. It also shows how a Kotlin compiler plugin used for mocking can make classes and their fields open, and suggests alternatives such as Mockito's inline mock maker and using fewer mocks.

### Source excerpt

The Kotlin modifier that shouldn't be therePhoto by Belinda Fewings on Unsplash Most Kotlin developers would agree that a val property is equivalent to a final property in Java. What if I tell you that this is not completely true and sometimes you might need a final val? Opposite to Java, Kotlin properties are final by default unless they are explicitly marked as open! This would mean there is no need for the final keyword, right? Let's Google that: As the internet confirmed our hypothesis, I was quite surprised when Android Studio told me to addfinal to a val: and indeed adding final would fix that: So there is a final keyword for properties but why and when should we make a val final? Let's look at this behavior using a simple example: class FinalBlog { val someProperty: String = "some" init { print(someProperty + "thing") } } "Everything works as expected here and the code will print "something" when the class is instantiated. Let's modify everything to be open: open class FinalBlog { open val someProperty: String = "some" init { print(someProperty + "thing") } } This will trigger the same type of warning I got before. This is very obvious when you think about it. The class can be subclassed and our property might be overridden. This could lead to unexpected side effects (which we will look into at the end of this post.). We can fix this simply by removing theopen modifier from the field. So, althought the warning has the same cause, it's not the exact same scenario my Android Studio was warning me on, there is no way I could add final here: non open already means final! Let's try something else: interface BlogTopic { val someProperty: String } open class FinalBlog: BlogTopic { override val someProperty: String = "some" init { print(someProperty + "thing") } } If the property is inherited from an interface, then it's open by default! Again, we will get the warning, we were looking for: And this time adding the final modifier will fix it: open class FinalBlog: Blo

## Avoid backing properties for LiveData and StateFlow

DevFeed: [Avoid backing properties for LiveData and StateFlow](<https://devfeed.tech/articles/avoid-backing-properties-for-livedata-and-stateflow-25886.md>)

Original publisher: [Read original article](<https://medium.com/google-developer-experts/avoid-backing-properties-for-livedata-and-stateflow-706006c9867e?source=rss-1331e67af4e1------2>)

Author: Danny Preussler

Published: 2021-01-12T14:03:52Z

Content type: tutorial

Language: en

Sources: [Stories by Danny Preussler on Medium](<https://devfeed.tech/sources/stories-by-danny-preussler-on-medium.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [coding](<https://devfeed.tech/topics/coding.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [abstract-class](<https://devfeed.tech/tags/abstract-class.md>), [android](<https://devfeed.tech/tags/android.md>), [class](<https://devfeed.tech/tags/class.md>), [clean-code](<https://devfeed.tech/tags/clean-code.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [interface](<https://devfeed.tech/tags/interface.md>), [interfaces](<https://devfeed.tech/tags/interfaces.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-flow](<https://devfeed.tech/tags/kotlin-flow.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [stateflow](<https://devfeed.tech/tags/stateflow.md>), [val](<https://devfeed.tech/tags/val.md>), [var](<https://devfeed.tech/tags/var.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This Kotlin article argues that developers can avoid duplicated backing properties when exposing LiveData and StateFlow. It proposes separating the public API from the implementation with interfaces or an abstract class, including in ViewModels.

### Source excerpt

https://unsplash.com/photos/OopPIi_A428 If you have ever worked with LiveData you probably have written code similar to this: class MyViewModel: ViewModel() { val loading: LiveData<Boolean> get() = _loading private val _loading = MutableLiveData<Boolean>()} This seems nowadays the typical way developers would expose some immutable LiveData, while being able to have a mutable version inside the implementation we would write data into. Every time I saw, or even had to write, this kind of code something cringed inside me. As I quoted in one of my talks this feeling in our brain is for real: social missteps activate regions in the brain, [..] that have been previously associated with physical pain. As developers, we know something is wrong with this code, right? It also feels like we are writing manual getters and setters here. What's wrong? We could start with the prefix we use for the backing field, although we fought hard for a long time to get rid of prefixes, we accept it here! It is even made it into the official coding conventions. But even if we rename it, it still cringes: class MyViewModel: ViewModel() { val loading: LiveData<Boolean> get() = mutableLoading private val mutableLoading = MutableLiveData<Boolean>()} This duplication feels unneeded! Especially if you write something like a ViewModel that exposed many of these, you get lost in reading the code just by all these duplications. But it's just LiveData? You might think it's just a specialty of LiveData and the future of that construct might be a more limited one. And you would not have this issue with primitives. The language supports this out of the box with a private setter: var secret: String = "Secret" private set But there is a new kid in town: StateFlow needs the same thing! Look at this snippet from the official Jetbrains blog: class DownloadingModel { private val _state = MutableStateFlow<DownloadStatus>(DownloadStatus.NOT_REQUESTED) val state: StateFlow<DownloadStatus> get() = _state This probl

## When Android Compat Libraries Do Not Prevent New API Compatibility Issues

DevFeed: [When Android Compat Libraries Do Not Prevent New API Compatibility Issues](<https://devfeed.tech/articles/when-compat-libraries-won-t-save-you-25895.md>)

Original publisher: [Read original article](<https://proandroiddev.com/when-compat-libraries-do-not-save-you-dc55f16b4160?source=rss-1331e67af4e1------2>)

Author: Danny Preussler

Published: 2021-01-04T19:34:03Z

Content type: tutorial

Language: en

Sources: [Stories by Danny Preussler on Medium](<https://devfeed.tech/sources/stories-by-danny-preussler-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Jetpack](<https://devfeed.tech/topics/jetpack.md>), [deprecated](<https://devfeed.tech/topics/deprecated.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [deprecated](<https://devfeed.tech/tags/deprecated.md>), [fragmentation](<https://devfeed.tech/tags/fragmentation.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [linter](<https://devfeed.tech/tags/linter.md>)

### AI overview

This tutorial explains why Android compatibility libraries do not all work the same way. Some duplicate platform APIs, while others bridge to the original APIs, so developers still need appropriate API-level checks and should avoid using the "NewApi" suppression indiscriminately.

### Source excerpt

And why you should avoid using the "NewApi" suppression! https://unsplash.com/photos/EgGIPA68Nwo The idea of "Compat" libraries was probably one of the key aspects of Android dominating the mobile space. Other than with iOS, Android users often could not update their operating system after a new version launch, simply as their phones won't allow them to, the Android problem of fragmentation. But developers still wanted to use the latest features to compete. The solution was simple: instead of adding new APIs to the operating system, you shipped those directly with your app by using a "backport" version Google gave you. It all started with ActionBar Sherlock by Jake Wharton then got adopted by Google with in their "support libraries". Later on, this was mirrored as AndroidX under the Jetpack umbrella. Same but different Under the hood, not all of those "compat"-APIs are made the same way. Some, like the ones for Fragments, are complete copies of the code. You either use android.app.Fragment from the OS (actually deprecated) or androidx.fragment.app.Fragment. Both don't share any code or have a common base class (which is why we also have two versions of the FragmentManager). On the other handAppCompatActivity for example, simply extends the original Activity. AlsoAppCompatImageButton still is an ImageButton! We can see that sometimes these "Compat"-classes are just a "bridge" to add missing functionalities and sometimes they are complete duplicates. Let's look at another example! One area that changed a lot over time is the notification API from Android. There was a time where every Google I/O introduced a new API change. Good that we have NotificationManagerCompat to save us!? If, for example, we need to get the notification channel groups: val groups = notificationManagerCompat.notificationChannelGroups We don't need to worry about the groups being supported on all OS versions, as it is handled under the hood for us: public List<NotificationChannelGroup> getNotific

## When LiveData and Kotlin don't play well together

DevFeed: [When LiveData and Kotlin don't play well together](<https://devfeed.tech/articles/when-livedata-and-kotlin-don-t-play-well-together-25889.md>)

Original publisher: [Read original article](<https://medium.com/google-developer-experts/when-livedata-and-kotlin-dont-play-hand-in-hand-30149aa794ec?source=rss-1331e67af4e1------2>)

Author: Danny Preussler

Published: 2020-12-15T13:38:10Z

Content type: tutorial

Language: en

Sources: [Stories by Danny Preussler on Medium](<https://devfeed.tech/sources/stories-by-danny-preussler-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [reactive](<https://devfeed.tech/topics/reactive.md>), [bug](<https://devfeed.tech/topics/bug.md>), [RxJava](<https://devfeed.tech/topics/rxjava.md>), [Code](<https://devfeed.tech/topics/code.md>), [implementation](<https://devfeed.tech/topics/implementation.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [bug](<https://devfeed.tech/tags/bug.md>), [code](<https://devfeed.tech/tags/code.md>), [explore](<https://devfeed.tech/tags/explore.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [jetpack](<https://devfeed.tech/tags/jetpack.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [livedata](<https://devfeed.tech/tags/livedata.md>), [reactive](<https://devfeed.tech/tags/reactive.md>), [rotation](<https://devfeed.tech/tags/rotation.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>), [viewmodel](<https://devfeed.tech/tags/viewmodel.md>)

### AI overview

This tutorial explains how LiveData's sticky last-value behavior interacts with Kotlin nullability on Android. It examines attempts to consume values by resetting LiveData to null and explains how that can cause a runtime crash when the value is treated as non-nullable.

### Source excerpt

When LiveData and Kotlin don't play well togetherPlaying well together The idea of LiveData was an interesting one. Based on the idea of reactive streams, that was on the peak at that time with RxJava plus adding automatic lifecycle handling -- a problem on Android. LiveData had bad timing though. It arrived just before Kotlin made its impact in the Android community and sometimes both don't play that nice together. Let's explore why and what can happen! The good and the bad The idea of LiveData was pretty simple: a lifecycle-aware implementation of the Observable pattern. In addition, if you resubscribe, you will get the last emitted value again. It could be compared to a typed version of an EventBus with sticky messages. This is one of the core features of LiveData. But very soon after developers, including the authors, figured, you don't always want that behavior. Let's say you have an error value. Then you probably don't want to show that error value again after resubscribing, like after rotation of a device -- for instance. One way to solve this is SingleLiveEvent and it's a good choice for one-off events like errors. Both worlds But what if you want a bit of both? You want to have the last value "sticky" plus not showing potential errors multiple times! In that case, it would be good to remove our error value from LiveData after they have been consumed, right? Let's look at the implementation ofLiveData: The current value is saved on a field: private volatile Object mData; Initially, it is set to NOT_SET which. static final Object NOT_SET = new Object(); Unfortunately, is not public otherwise, we could use it to reset the value. What now? If you search for this problem, one of the most suggested solutions is simply setting it to null. Let's explore this: viewModel.results.observe(lifecycleOwner) { result -> when (result) { SomeResult.Error -> { handleError() viewModel.results.reset() } SomeResult.Result -> { handleResult(result) } } } where the ViewModel's imple

## Swift's Guard Statement for Kotlin

DevFeed: [Swift's Guard Statement for Kotlin](<https://devfeed.tech/articles/swift-s-guard-statement-for-kotlin-25890.md>)

Original publisher: [Read original article](<https://medium.com/swlh/swifts-guard-statement-for-kotlin-967ba580443f?source=rss-1331e67af4e1------2>)

Author: Danny Preussler

Published: 2020-12-07T21:55:37Z

Content type: tutorial

Language: en

Sources: [Stories by Danny Preussler on Medium](<https://devfeed.tech/sources/stories-by-danny-preussler-on-medium.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Swift](<https://devfeed.tech/topics/swift.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [code](<https://devfeed.tech/tags/code.md>), [condition](<https://devfeed.tech/tags/condition.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [programming](<https://devfeed.tech/tags/programming.md>), [swift](<https://devfeed.tech/tags/swift.md>)

### AI overview

This tutorial compares Swift's guard statement with Kotlin's early-return patterns. It explains how guard exits early when conditions fail, then demonstrates Kotlin alternatives using returns, expressions, exceptions, and a wrapper for handling arbitrary lambdas.

### Source excerpt

https://unsplash.com/photos/znMu0Enj_Gw Even if you live on the Kotlin side of things maybe once in a while you also check Swift code. If you do, you probably noticed how similar both languages are. To me, Kotlin looks more concise but I'm also biased as I work with Kotlin daily. On the other hand, Swift has some great features too. One is the guard keyword, a really nice tool Swift developers have that we are missing. Can we bring it to Kotlin? What is guard? guard is used to exit a block of code early, if a given condition is not met. This way all the code following the guarded variable can be safely executed. Let's look at an example where we do some calculation but only if the given input can be converted into an integer: func printResultFor(input: String) -> Void { guard let result = Int(input) else { println("input was not an integer") return } // function continues with valid int print("result: ", 100 * result)} Of course, simple code like this could be written with the standard if/else statements! But the power of guard becomes apparent when many of these statements are used in succession. Written in a traditional way this can easily lead to a hell of nested ifs where you make sure everything is safe in the innermost block when all the if are true. Take a simple sign up flow for example, where the customer needs to enter user, password, and their age for validation. We have to make sure those are not nil or empty and check for a valid age. func submit(usernameText: String?, passwordText: String?, ageText: String?) { guard let username = usernameText, !username.isEmpty else { print("username is not set or blank") return } guard let password = passwordText, !password.isEmpty else { print("password is not set or blank") return } guard let ageString = ageText else { print("age is not set") return } guard let age = Int(ageString), age > 18 else { print("age not valid") return } // all values are checked and valid here register(username, password, age)} Here the r

## The hidden pitfalls of the Elvis operator

DevFeed: [The hidden pitfalls of the Elvis operator](<https://devfeed.tech/articles/the-hidden-pitfalls-of-the-elvis-operator-25887.md>)

Original publisher: [Read original article](<https://medium.com/google-developer-experts/the-hidden-pitfalls-of-the-elvis-operator-da536ba68161?source=rss-1331e67af4e1------2>)

Author: Danny Preussler

Published: 2020-07-28T08:05:18Z

Content type: tutorial

Language: en

Sources: [Stories by Danny Preussler on Medium](<https://devfeed.tech/sources/stories-by-danny-preussler-on-medium.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [elvis-operator](<https://devfeed.tech/tags/elvis-operator.md>), [expression](<https://devfeed.tech/tags/expression.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [null-safety](<https://devfeed.tech/tags/null-safety.md>), [pitfalls](<https://devfeed.tech/tags/pitfalls.md>), [programming](<https://devfeed.tech/tags/programming.md>), [returning](<https://devfeed.tech/tags/returning.md>)

### AI overview

This Kotlin article explains that the Elvis operator can behave differently from an equivalent if/else statement when chained expressions are involved. Kotlin evaluates the full expression on the left, including the final function call, before deciding whether to evaluate the Elvis branch, so both functions may be called when the final expression returns null.

### Source excerpt

Hidden pitfalls when using Elvis operator I guess many of us love Elvis, both the artist and the operator in Kotlin. But it can lead to some hidden pitfalls if you are not aware of how it works. https://unsplash.com/photos/1LCzr14Ah5U I only realized recently when Vladimir Zdravkovic put some code on twitter and ask us to guess what it's printing: https://twitter.com/vlazdra/status/1287366531987406848?s=20 I assumed a hidden puzzle but I could not see the issue. I could not see any reason why this would print anything but it does! After thinking about the issue (Vladimir wrote an article about it) I found more and more cases where this could go wrong. But let me show you some code: Kotlin's null safety I think most of us love the way we can easily write null safe code with Kotlin like this: presenter?.onDestroy() or data?.let{ updateData(data) } And it is super easy to add an alternative case: data?.let{ updateData(data) } ?: run { showLoadingSpinner() }Let me ask you something Do you think the following code is basically the same as the above? if (data != null) { updateData(data) } else { showLoadingSpinner() } I'm sure most of us do think they are equivalent. But what if I told you, it's not? The if/else is totally binary, it's either-or. But with the Elvis operator, it might be both! To understand why we have to look closer to how it works. Other than the else that belongs explicit to an if , the Elvis operator is not tied to a single ?. Remember, we can chain them: someVariable?.someField?.doSomething() if we now add the Elvis operator here, it will get executed depending on the expression to its left side: someVariable?.someField?.doSomething() ?: run { doSomethingElse() } so if any expression in there is null, the Elvis block will get called. It will finish evaluating everything on the left before checking if the operator is needed. This includes the last expression. So this is depending on whatever doSomething() returns! If it is null, then the right side wil

## Keep your interfaces simple

DevFeed: [Keep your interfaces simple](<https://devfeed.tech/articles/keep-your-interfaces-simple-25892.md>)

Original publisher: [Read original article](<https://proandroiddev.com/keep-your-interfaces-simple-e025d515e3b9?source=rss-1331e67af4e1------2>)

Author: Danny Preussler

Published: 2020-07-16T07:56:26Z

Content type: tutorial

Language: en

Sources: [Stories by Danny Preussler on Medium](<https://devfeed.tech/sources/stories-by-danny-preussler-on-medium.md>)

Topics: [interfaces](<https://devfeed.tech/topics/interfaces.md>), [API](<https://devfeed.tech/topics/api.md>), [feature flags](<https://devfeed.tech/topics/feature-flags.md>), [Mocking](<https://devfeed.tech/topics/mocking.md>), [Code](<https://devfeed.tech/topics/code.md>), [implementation](<https://devfeed.tech/topics/implementation.md>), [Java](<https://devfeed.tech/topics/java.md>), [Extension](<https://devfeed.tech/topics/extension.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [api](<https://devfeed.tech/tags/api.md>), [code](<https://devfeed.tech/tags/code.md>), [extension](<https://devfeed.tech/tags/extension.md>), [feature-flags](<https://devfeed.tech/tags/feature-flags.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [interfaces](<https://devfeed.tech/tags/interfaces.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [mocking](<https://devfeed.tech/tags/mocking.md>), [tests](<https://devfeed.tech/tags/tests.md>)

### AI overview

This article explains how implicit connections between interface methods can create hidden contracts that every implementation and mock must honor. It uses Java List methods, the equals/hashCode contract, and feature flags to argue for simpler interfaces, extension functions, and stub implementations where appropriate.

### Source excerpt

Avoiding implicit connections and learn how extension functions can help you writing good APIshttps://unsplash.com/photos/xxeAftHHq6E Writing your classes with a good API is hard but important. As the writer is trying to make it easy for the user, we sometimes tend to repeat ourselves by adding convenient methods. Think about the List interface in Java. To check if there are no elements in the list we could check list.getLength() == 0 or we simply ask for isEmpty(). The 2nd one reads much better. But it also adds a duplication and implicit connection between the two: If the list is empty, it can't contain any elements! This must be respected by every implementer of the interface! We can easily think of many other methods with implicit dependencies. Think about how hashCode and equals have a connection. This is stated in the Javadocs: Note that it is generally necessary to override the hashCode method whenever equals is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes. This is a pitfall that can be difficult to avoid and can lead to issues elsewhere that are difficult to track down and fix. Nowadays we have tools to validate this contract, or even better, to generate the implementation. Another example: feature flags A lot of developers work with features flags. These enable us to release continuously without the need for long-lived feature branches. Let's say we have an interface like this: interface AppFeatures { fun isEnabled(feature: Feature): Boolean } When using this I realized I often write code like: if (!isEnabled(Feature.SomeFeature)) "not is enabled" does not read nicely though. But I want the reader to understand my code without thinking too much. Therefore my initial thought was to add another method to the interface fun isDisabled(feature: Feature): Boolean But I realized, doing this might break a lot of tests that simply mock the interface: val appFeatures = mock<AppF

## Why Large Dependency-Injection Constructors Signal a Single-Responsibility Problem

DevFeed: [Why Large Dependency-Injection Constructors Signal a Single-Responsibility Problem](<https://devfeed.tech/articles/the-forgotten-art-of-construction-25893.md>)

Original publisher: [Read original article](<https://proandroiddev.com/the-forgotten-art-of-construction-cfedc368e67f?source=rss-1331e67af4e1------2>)

Author: Danny Preussler

Published: 2020-06-22T17:39:16Z

Content type: opinion

Language: en

Sources: [Stories by Danny Preussler on Medium](<https://devfeed.tech/sources/stories-by-danny-preussler-on-medium.md>)

Topics: [Code](<https://devfeed.tech/topics/code.md>), [clean-code](<https://devfeed.tech/topics/clean-code.md>), [Dagger](<https://devfeed.tech/topics/dagger.md>), [koin](<https://devfeed.tech/topics/koin.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [clean-code](<https://devfeed.tech/tags/clean-code.md>), [code](<https://devfeed.tech/tags/code.md>), [code-smells](<https://devfeed.tech/tags/code-smells.md>), [constructor](<https://devfeed.tech/tags/constructor.md>), [dagger](<https://devfeed.tech/tags/dagger.md>), [dependencies](<https://devfeed.tech/tags/dependencies.md>), [dependency-injection](<https://devfeed.tech/tags/dependency-injection.md>), [koin](<https://devfeed.tech/tags/koin.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>)

### AI overview

The article argues that dependency-injection tools can hide overly large constructors. It presents large constructors as a code smell that may indicate a violation of the Single Responsibility Principle, and notes that they make classes harder to test.

### Source excerpt

How tools made us forget how to write sane constructors https://unsplash.com/photos/qvBYnMuNJ9A In an ideal world, developers get smarter every day. The code we write this year should be better than the code we wrote 10 years ago, which in turn should be better than the code 20 years ago. Today we have better tools, more modern languages, and better practices. But as often in life, we realize we are not living in that ideal world. In nearly every codebase I see today, there are things that would shock a developer two decades ago. I am speaking of what Mark Seemann called "Constructor Over Injection". We've all learned to inject our dependencies into constructors. And ideally use a tool for that like Spring or Dagger. If you look at some random classes from your codebase, how many fields are you injecting? Three? Five? More? I'm pretty sure you easily can find classes with even more, like this one: class ProfilePresenter @Inject constructor( @MainThreadScheduler private val mainScheduler: Scheduler, @IOScheduler private val ioScheduler: Scheduler, private val profileApi: ProfileApi, private val userRepository: UserRepository, private val analytics: Analytics, private val errorReporter: ErrorReporter private val referrerTracker: ReferrerTracker, private val shareTracker: ShareTracker, private val tracksRepository: TracksRepository, private val playlistRepository: PlaylistRepository ) If you would show this constructor to a developer from 20 years ago they would probably look at you as if you would be crazy. No one would want to call this constructor and provide all these parameters. But these days we don't care. We don't have to. We have a tool that will provide us with all those parameters, right? This does not make it right though! The proof If you would use some manual injection code or a service locator like Koin, you would notice more what's going on because you would need to write code like this: ProfilePresenter(get(), get(), get(), get(), get(), get(), get(),