# Vasya Drobushkov

Recent content on Vasya Drobushkov

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

## Android Development on Android: A Self-Contained Setup

DevFeed: [Android Development on Android: A Self-Contained Setup](<https://devfeed.tech/articles/android-development-on-android-a-self-contained-setup-38660.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2026_04_26_android_development_on_android/>)

Published: 2026-04-26T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [Termux](<https://devfeed.tech/topics/termux.md>), [android-development](<https://devfeed.tech/topics/android-development.md>), [Command-line interface](<https://devfeed.tech/topics/cli.md>), [Gradle](<https://devfeed.tech/topics/gradle.md>), [Java](<https://devfeed.tech/topics/java.md>), [Git](<https://devfeed.tech/topics/git.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [android-studio](<https://devfeed.tech/tags/android-studio.md>), [build](<https://devfeed.tech/tags/build.md>), [cli](<https://devfeed.tech/tags/cli.md>), [development](<https://devfeed.tech/tags/development.md>), [git](<https://devfeed.tech/tags/git.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [java](<https://devfeed.tech/tags/java.md>)

### AI overview

A practical guide to setting up Android development directly on an Android phone with Termux. It covers installing the JDK, Android command-line tools, platform and build tools, Gradle, and a Termux-compatible aapt2 binary, then cloning and assembling a project and authenticating Gemini.

### Source excerpt

I use my phone on a daily basis for dozens of various things. This is truly my pocket computer that helps me with many different tasks. Since the first time I had an Android phone until nowadays, the flexibility of the platform has been very astonishing Recently, I've learned about Termux - it is a UNIX terminal running on the phone. Yes, just directly on a mobile phone you have access to git, ssh, curl, and other terminal commands. It is very powerful by itself to be able to connect to a remote server from a phone and do sth, but one thing came to my mind - whether it can be used to work on Android projects

## Kotlin Coroutines Cancellation and Exception Handling

DevFeed: [Kotlin Coroutines Cancellation and Exception Handling](<https://devfeed.tech/articles/kotlin-coroutines-cancellation-and-exception-handling-38659.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2026_01_11_kotlin_coroutines_cancellation_and_exception_handling/>)

Published: 2026-01-11T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [kotlin-coroutines](<https://devfeed.tech/topics/kotlin-coroutines.md>), [cancellation](<https://devfeed.tech/topics/cancellation.md>), [Exception handling](<https://devfeed.tech/topics/exception-handling.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>)

Tags: [cancellation](<https://devfeed.tech/tags/cancellation.md>), [concurrency](<https://devfeed.tech/tags/concurrency.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [exception-handling](<https://devfeed.tech/tags/exception-handling.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>)

### AI overview

This article explains why cancellation and exception handling in Kotlin coroutines are difficult, emphasizing that the concepts are distinct but coupled. It discusses the flexibility and hidden complexity of the coroutine API and introduces explanations and best practices for learning and using these mechanisms.

### Source excerpt

Cancellation and exception handling in coroutines is by far the most complex thing I've faced during my entire career. These two things are so complicated that I sometimes ask myself how people are using such a difficult-to-use framework. I read all the possible docs that I found, many different articles, video courses, and even tried to look at the code - and still, I feel that my understanding of this topic is quite bad. When reading articles, I often thought that their structure was not good and that things were not clarified in a reasonable way. Usually, articles are just a collection of examples that show how certain combinations of suspending functions or coroutine builders will work. Learning by examples is good, but they should help with understanding core concepts so that all other situations are easy to relate to what was learned.

## Data-Driven Debugging for Engineers

DevFeed: [Data-Driven Debugging for Engineers](<https://devfeed.tech/articles/data-driven-debugging-for-engineers-38658.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2025_06_03_data_driven_debugging_for_engineers/>)

Published: 2025-06-03T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [debugging](<https://devfeed.tech/topics/debugging.md>), [bug](<https://devfeed.tech/topics/bug.md>), [Development](<https://devfeed.tech/topics/development.md>), [unit tests](<https://devfeed.tech/topics/unit-tests.md>), [Code](<https://devfeed.tech/topics/code.md>), [Users](<https://devfeed.tech/topics/users.md>)

Tags: [bugs](<https://devfeed.tech/tags/bugs.md>), [debugging](<https://devfeed.tech/tags/debugging.md>), [root](<https://devfeed.tech/tags/root.md>), [test](<https://devfeed.tech/tags/test.md>), [unit-tests](<https://devfeed.tech/tags/unit-tests.md>), [user](<https://devfeed.tech/tags/user.md>)

### AI overview

This developer article explains how engineers debug bugs reported by developers, QA, and users. It compares the role of unit tests and end-to-end tests, then describes the greater difficulty of diagnosing vague user-reported symptoms.

### Source excerpt

As engineers, we deal with bugs every day. Finding the root cause and delivering the right fix is one of our most essential -- and satisfying -- skills. In this post, I want to walk through different types of issues we face and how we typically debug them. Most importantly, I'll share my favorite and most challenging method: data-driven debugging. Let's break it down by who reports the issue and how it's discovered.

## Why the author questions SOLID and proposes CLARITY principles

DevFeed: [Why the author questions SOLID and proposes CLARITY principles](<https://devfeed.tech/articles/when-solid-breaks-choose-clarity-38657.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2025_05_05_when_solid_breaks_choose_clarity/>)

Published: 2025-05-05T00:00:00Z

Content type: opinion

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [Development](<https://devfeed.tech/topics/development.md>), [Programming](<https://devfeed.tech/topics/programming.md>), [clean-code](<https://devfeed.tech/topics/clean-code.md>)

Tags: [best-practices](<https://devfeed.tech/tags/best-practices.md>), [development](<https://devfeed.tech/tags/development.md>), [opinions](<https://devfeed.tech/tags/opinions.md>), [programming](<https://devfeed.tech/tags/programming.md>)

### AI overview

The author argues that SOLID principles are interpreted inconsistently and that rigid application can produce difficult-to-maintain code. The article proposes using a set of principles called CLARITY instead, beginning with consistent abstraction levels.

### Source excerpt

A long time ago, when I had just started my journey into programming, development, and engineering, it wasn't easy to find information, and bikeshedding could happen quite often because of that. We read books to gain insights into best practices and learn how to do things correctly. The concepts from the past were usually crucial and provided a great ramp-up to avoid obvious mistakes. Over time, we became flooded with information and opinions. In such an environment, old-time thoughts may even seem better, as they've been tested by time and by many engineers in the field.

## Java after Kotlin

DevFeed: [Java after Kotlin](<https://devfeed.tech/articles/java-after-kotlin-38656.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2025_02_17_java_after_kotlin/>)

Published: 2025-02-17T00:00:00Z

Content type: opinion

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Java](<https://devfeed.tech/topics/java.md>), [Developer experience](<https://devfeed.tech/topics/developer-experience.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>)

Tags: [compare](<https://devfeed.tech/tags/compare.md>), [developer-experience](<https://devfeed.tech/tags/developer-experience.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>)

### AI overview

The author compares Java with Kotlin after returning to Java for a coding task. They prefer Kotlin for its conciseness and developer experience, highlighting differences in semicolons, equality, naming, data access, and type declaration, while noting some Kotlin collection and array behavior differences.

### Source excerpt

I am usually pretty slow with new technologies and software updates. That happened with Kotlin a while ago. While version 1.0 was released in early 2016, and many companies were early adopters since the alpha versions, I really started using it only around the end of 2017. I should say that I do find it a very concise and easy-to-write-and-read language. Its focus on developer experience makes it very pleasant to use (except coroutines, lol).

## Intuitive Proofs for Linked-List Loop Detection and Majority-Element Algorithms

DevFeed: [Intuitive Proofs for Linked-List Loop Detection and Majority-Element Algorithms](<https://devfeed.tech/articles/relatively-non-obvious-tricks-in-solving-simple-algorithmic-problems-38655.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2024_12_21_relatively_non_obvious_tricks_in_solving_simple_algorithmic_problems/>)

Published: 2024-12-21T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [Algorithms, Complexity](<https://devfeed.tech/topics/algorithms-complexity.md>), [Algorithms](<https://devfeed.tech/topics/algorithms.md>), [LeetCode](<https://devfeed.tech/topics/leetcode.md>), [Programming](<https://devfeed.tech/topics/programming.md>)

Tags: [algorithms](<https://devfeed.tech/tags/algorithms.md>), [array](<https://devfeed.tech/tags/array.md>), [code](<https://devfeed.tech/tags/code.md>), [collections](<https://devfeed.tech/tags/collections.md>), [counter](<https://devfeed.tech/tags/counter.md>), [examples](<https://devfeed.tech/tags/examples.md>), [memory](<https://devfeed.tech/tags/memory.md>), [pointers](<https://devfeed.tech/tags/pointers.md>), [solutions](<https://devfeed.tech/tags/solutions.md>), [time](<https://devfeed.tech/tags/time.md>)

### AI overview

This tutorial explains why concise solutions to seemingly easy algorithmic problems work. It uses linked-list loop detection with slow and fast pointers and majority-element detection with a counter, emphasizing intuitive proofs over implementation alone.

### Source excerpt

Blowing the dust off LeetCode once again, I found myself, as in the past, struggling with coding relatively simple algorithms. Just like with anything else, if you don't practice for years, you lose some of the hands-on experience. On the positive side, I noticed that for some problems, my new submissions were much better and more concise compared to my old ones. That's an awesome feeling--a tangible measure of growth. While tackling certain easy problems, I realized that "easy" usually just means "doesn't require much code." However, the idea behind the optimal solution might still not be very intuitive. Sure, one can use brute force or additional collections, but in most cases, this leads to either a "time limit exceeded" or an "out of memory" error.

## Reactive streams testing

DevFeed: [Reactive streams testing](<https://devfeed.tech/articles/reactive-streams-testing-38654.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2023_01_08_reactive_streams_testing/>)

Published: 2023-01-08T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [Reactive Streams](<https://devfeed.tech/topics/reactive-streams.md>), [Testing](<https://devfeed.tech/topics/testing.md>), [API](<https://devfeed.tech/topics/api.md>), [Documentation](<https://devfeed.tech/topics/documentation.md>), [kotlin-flow](<https://devfeed.tech/topics/kotlin-flow.md>), [RxJava](<https://devfeed.tech/topics/rxjava.md>), [Refactoring](<https://devfeed.tech/topics/refactoring.md>), [callback](<https://devfeed.tech/topics/callback.md>)

Tags: [api](<https://devfeed.tech/tags/api.md>), [code](<https://devfeed.tech/tags/code.md>), [documentation](<https://devfeed.tech/tags/documentation.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-flow](<https://devfeed.tech/tags/kotlin-flow.md>), [reactive-streams](<https://devfeed.tech/tags/reactive-streams.md>), [refactoring](<https://devfeed.tech/tags/refactoring.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>), [testing](<https://devfeed.tech/tags/testing.md>)

### AI overview

This article explains how to test reactive-stream APIs, using RxJava and Kotlin Flow as examples. It emphasizes testing emitted values and other implicit behavior so tests document public API expectations and support safer migrations and refactoring.

### Source excerpt

Introduction We should test the code to guarantee that it does exactly what it is expected to do. Tests not only verify correctness of the program but also set expectations. This becomes especially useful for public API, where tests can be treated as part of documentation that describes not only results but also behavior. Such things help do less painful migrations and refactoring as it becomes clear what behaviors are changing and what we should do about that.

## When Compose remember cannot forget

DevFeed: [When Compose remember cannot forget](<https://devfeed.tech/articles/when-compose-remember-cannot-forget-38653.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2022_07_23_when_compose_remember_cannot_forget/>)

Published: 2022-07-23T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [Compose](<https://devfeed.tech/topics/compose.md>), [compose-for-web](<https://devfeed.tech/topics/compose-for-web.md>), [ui](<https://devfeed.tech/topics/ui.md>), [color](<https://devfeed.tech/topics/color.md>)

Tags: [change](<https://devfeed.tech/tags/change.md>), [compose](<https://devfeed.tech/tags/compose.md>), [compose-for-web](<https://devfeed.tech/tags/compose-for-web.md>), [recomposition](<https://devfeed.tech/tags/recomposition.md>), [state](<https://devfeed.tech/tags/state.md>), [ui](<https://devfeed.tech/tags/ui.md>), [update](<https://devfeed.tech/tags/update.md>)

### AI overview

This tutorial explains why a Compose composable continued displaying an old value after recomposition in a Compose for Web color utility app. The issue occurred because remember preserves values across recompositions; supplying the changing color value as a key caused the remembered value to update.

### Source excerpt

Чытаць на беларускай мове Introduction When developing color-utils app using Compose for Web I faced an issue that remember didn't want to forget the state. It was quite annoying experience as it felt stupid: composable function is recomposed with the new value provided but remember still kept old value. As usual, there is no magic there and the answer is quite simple therefore this article won't be that long. Compose is all about state. In the app I had two levels of state:

## Using Compose remember with changing values

DevFeed: [Using Compose remember with changing values](<https://devfeed.tech/articles/compose-remember-38661.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/by/2022_07_23_when_compose_remember_cannot_forget/>)

Published: 2022-07-23T00:00:00Z

Content type: tutorial

Language: be

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [Compose](<https://devfeed.tech/topics/compose.md>), [Web](<https://devfeed.tech/topics/web.md>), [color](<https://devfeed.tech/topics/color.md>), [ui](<https://devfeed.tech/topics/ui.md>)

Tags: [color](<https://devfeed.tech/tags/color.md>), [compose](<https://devfeed.tech/tags/compose.md>), [ui](<https://devfeed.tech/tags/ui.md>), [web](<https://devfeed.tech/tags/web.md>)

### AI overview

This tutorial explains why Compose remember retains a previous value during recomposition and how changing the remember key causes it to accept and store a new value. The example uses domain and UI state for color editing in a Compose for Web application.

### Source excerpt

Read in English Уводзіны Пры распрацоўцы прыкладання color-utils з выкарыстаннем Compose для Web я сутыкнуўся з праблемай, што remember не хацеў забываць стан. Гэта быў вельмі раздражняльны вопыт, бо я адчуваў сябе па-дурному: Composable функцыя перакампанавана з новым значэннем, але remember па-ранейшаму захоўвала старое значэнне. Як звычайна, ніякай магіі тут няма, і адказ даволі просты, таму гэты артыкул не будзе вельмі доўгі. Compose - гэта ўсё аб стане. У прыкладанні ў мяне было два ўзроўні стану:

## Card Soccer

DevFeed: [Card Soccer](<https://devfeed.tech/articles/card-soccer-38598.md>)

Original publisher: [Read original article](<https://krossovochkin.com/apps/card-soccer/>)

Published: 2022-07-10T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [Kotlin Multiplatform](<https://devfeed.tech/topics/kotlin-multiplatform.md>), [multiplatform](<https://devfeed.tech/topics/multiplatform.md>), [Compose](<https://devfeed.tech/topics/compose.md>), [ui](<https://devfeed.tech/topics/ui.md>), [compose-for-desktop](<https://devfeed.tech/topics/compose-for-desktop.md>), [Web](<https://devfeed.tech/topics/web.md>)

Tags: [ai](<https://devfeed.tech/tags/ai.md>), [compose](<https://devfeed.tech/tags/compose.md>), [compose-ui](<https://devfeed.tech/tags/compose-ui.md>), [desktop](<https://devfeed.tech/tags/desktop.md>), [game](<https://devfeed.tech/tags/game.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-multiplatform](<https://devfeed.tech/tags/kotlin-multiplatform.md>), [multiplatform](<https://devfeed.tech/tags/multiplatform.md>), [port](<https://devfeed.tech/tags/port.md>), [strategies](<https://devfeed.tech/tags/strategies.md>), [web](<https://devfeed.tech/tags/web.md>)

### AI overview

Card Soccer is a turn-based card game against an AI opponent. Players move a card-based ball through rows by matching its value or suit, using passes or shots to score goals. The author describes developing desktop and web versions with Kotlin Multiplatform and Jetpack Compose UI.

### Source excerpt

How to play The goal of the game is to win AI opponent by scoring more goals. The game is turn based. On your turn you should move the "ball" (card opened from your deck) to opponents goal. You start from the row that is close to your goal: you should select a card in a row and if it matches by value or suite - proceed to the next row up until the opponent's goal. If there is no match - your turn is over. You can select opened and closed cards. If the whole row is opened - you can skip it and procced to the next one. You score when your "ball" matches opponent goal.

## Controlling TextView MinWidth

DevFeed: [Controlling TextView MinWidth](<https://devfeed.tech/articles/controlling-textview-minwidth-38652.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2021_09_14_controlling_textview_minwidth/>)

Published: 2021-09-14T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [constraintlayout](<https://devfeed.tech/topics/constraintlayout.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-layout](<https://devfeed.tech/tags/android-layout.md>), [background](<https://devfeed.tech/tags/background.md>), [constraintlayout](<https://devfeed.tech/tags/constraintlayout.md>), [gravity](<https://devfeed.tech/tags/gravity.md>), [layout](<https://devfeed.tech/tags/layout.md>), [properties](<https://devfeed.tech/tags/properties.md>), [textview](<https://devfeed.tech/tags/textview.md>), [xml](<https://devfeed.tech/tags/xml.md>)

### AI overview

A technical explanation of how Android TextView minimum-width APIs interact. Setting minWidth or minimumWidth alone may not reset a dimension declared in XML; both properties must be cleared, and a background can still impose a minimum width.

### Source excerpt

Introduction Sometimes we might need our TextView with wrap_content width to occupy more space than it will based on amount of characters it displays. For that we can set minimum width. Usually, we do that via XML like this: <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/bg_text" android:gravity="center" android:minWidth="200dp" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> Having setup like this we ensure that our TextView will occupy a minimum of 200dp. Also, we can control minimum width programmatically via: TextView#setMinWidth. But controlling minimum width programmatically has one caveat that I'd like to describe below.

## Mocking Matchers API: Handling Nullable and Non-Nullable Arguments in mockito-kotlin

DevFeed: [Mocking Matchers API: Handling Nullable and Non-Nullable Arguments in mockito-kotlin](<https://devfeed.tech/articles/mocking-matchers-api-38651.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2021_09_11_mocking_matchers_api/>)

Published: 2021-09-11T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [Mocking](<https://devfeed.tech/topics/mocking.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Library](<https://devfeed.tech/topics/library.md>)

Tags: [article](<https://devfeed.tech/tags/article.md>), [code](<https://devfeed.tech/tags/code.md>), [exception](<https://devfeed.tech/tags/exception.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [library](<https://devfeed.tech/tags/library.md>), [mocking](<https://devfeed.tech/tags/mocking.md>)

### AI overview

This article examines how mocking libraries design their APIs, using mockito-kotlin to explain why matchers for nullable and non-nullable inputs behave differently. It also discusses duplication in mock setups and when a fake object may be preferable.

### Source excerpt

Introduction Recently, I faced an issue that in the first place I found weird. I even considered that the behavior is generally incorrect. Diving deeper I got few insights on the problem - and this is what I'd like to share with you. This is a story about the interesting behavior of mocking library and the difficulties of defining API surface for a library. Disclaimer In general, I favor fakes over mocks. In other words, instead of trying to implement emulation of the behavior as a mock - it is generally easier and safer to implement a simple fake object with all the logic (that can be covered with tests if needed). Though that doesn't mean that one should not use mocks at all. In my opinion, it depends on the use case. If you would like to stub some values - then going with a fake object sounds like a wise choice, but for verifying behavior (e.g. whether there were interactions with a particular object or not) using mocking libraries might provide a fast solution. Needed to say that even when trying to verify interactions one can use fake objects wrapped with spies. Regardless, this article is not about what approach is better, it is more about the behavior of mocking libraries and how their API is designed.

## JUnit Coroutines Runner

DevFeed: [JUnit Coroutines Runner](<https://devfeed.tech/articles/junit-coroutines-runner-38650.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2021_07_10_junit_coroutines_runner/>)

Published: 2021-07-10T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

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

Tags: [coroutines](<https://devfeed.tech/tags/coroutines.md>), [junit](<https://devfeed.tech/tags/junit.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-compiler](<https://devfeed.tech/tags/kotlin-compiler.md>), [runner](<https://devfeed.tech/tags/runner.md>), [suspend-function](<https://devfeed.tech/tags/suspend-function.md>), [tests](<https://devfeed.tech/tags/tests.md>)

### AI overview

This tutorial explores how to reduce repeated runBlockingTest setup in Kotlin coroutine tests by creating a custom JUnit rule. It explains the resulting suspend-function and bytecode validation issues and investigates their root cause.

### Source excerpt

Introduction Recently while writing tests for kotlin code with coroutines I found one annoying thing: almost all the tests start with runBlockingTest. Typing the same stuff repeatedly is something we can't accept! So, I decided to think about how to improve this. Disclaimer. Yes, this is an example of how to spend few hours to optimize some task that requires you 2 seconds to complete each time. Even on a scale of hundreds of usages such optimization most likely won't pay your time back. But it is always fun to do some weird things even if you understand that they are stupid.

## Kotlin flow: Nesting vs Chaining

DevFeed: [Kotlin flow: Nesting vs Chaining](<https://devfeed.tech/articles/kotlin-flow-nesting-vs-chaining-38649.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2021_07_08_kotlin_flow_nesting_vs_chaining/>)

Published: 2021-07-08T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [kotlin-flow](<https://devfeed.tech/topics/kotlin-flow.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Reactive Streams](<https://devfeed.tech/topics/reactive-streams.md>), [reactive](<https://devfeed.tech/topics/reactive.md>), [RxJava](<https://devfeed.tech/topics/rxjava.md>)

Tags: [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-flow](<https://devfeed.tech/tags/kotlin-flow.md>), [reactive](<https://devfeed.tech/tags/reactive.md>), [reactive-streams](<https://devfeed.tech/tags/reactive-streams.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>)

### AI overview

A tutorial comparing nesting and chaining in Kotlin Flow reactive streams. It explains that chaining can improve readability for simple sequential streams, while nesting is useful for sharing data across streams and managing stream lifecycles, such as conditionally observing a user's location.

### Source excerpt

Introduction When it comes to reactive streams it is likely everyone heard about huge 'Rx-chains'. But reactive streams are not only about chaining but also about nesting. Let's find out what are they, what are the differences, and why it matters. We'll use Kotlin Flow throughout the article, but everything can be applied to RxJava as well. First of all, we need to come up with definitions. For that, we'll take a look at some simple streams.

## Why custom website instead of Medium

DevFeed: [Why custom website instead of Medium](<https://devfeed.tech/articles/why-custom-website-instead-of-medium-38648.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2021_06_21_why_custom_website_instead_of_medium/>)

Published: 2021-06-21T00:00:00Z

Content type: opinion

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [Website](<https://devfeed.tech/topics/website.md>), [Development](<https://devfeed.tech/topics/development.md>)

Tags: [article](<https://devfeed.tech/tags/article.md>), [website](<https://devfeed.tech/tags/website.md>)

### AI overview

The author explains why they moved from Medium to a custom website, comparing the advantages and disadvantages of each. Medium offers free publishing, discoverability, embedded content, comments, collaboration, and possible earnings, while a personal website provides greater ownership of identity.

### Source excerpt

Introduction I like writing articles. This is the best format for me to share ideas, knowledge and also to better understand some topic. when writing something other people can read you have to dive deep enough so that the picture is complete. It helps systemize thoughts. Starting writing was challenging as you don't know what feedback you'll receive. It is always a bit tough to be not correct in something. Fear of making a mistake - while not being a bad thing, as we learn from mistakes - is still here. Don't make that fear stop you from doing what you feel is right. I started writing on Medium and publishing in various publications there but then switched to my website quite a while ago. After some time of running my stuff, I finally would like to share why I did so and what the pros and cons of that are.

## Custom Reactive JSON parsing

DevFeed: [Custom Reactive JSON parsing](<https://devfeed.tech/articles/custom-reactive-json-parsing-38647.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2021_06_08_custom_reactive_json_parsing/>)

Published: 2021-06-08T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [JSON](<https://devfeed.tech/topics/json.md>), [Parsing](<https://devfeed.tech/topics/parsing.md>), [Library](<https://devfeed.tech/topics/library.md>), [Android](<https://devfeed.tech/topics/android.md>), [client](<https://devfeed.tech/topics/client.md>), [multiplatform](<https://devfeed.tech/topics/multiplatform.md>), [Jetpack Compose](<https://devfeed.tech/topics/jetpack-compose.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [gson](<https://devfeed.tech/tags/gson.md>), [jackson](<https://devfeed.tech/tags/jackson.md>), [jetpack-compose](<https://devfeed.tech/tags/jetpack-compose.md>), [json](<https://devfeed.tech/tags/json.md>), [json-parsing](<https://devfeed.tech/tags/json-parsing.md>), [moshi](<https://devfeed.tech/tags/moshi.md>), [multiplatform](<https://devfeed.tech/tags/multiplatform.md>), [parsing](<https://devfeed.tech/tags/parsing.md>), [serialization](<https://devfeed.tech/tags/serialization.md>)

### AI overview

This tutorial introduces JSON parsing in Android applications, compares common libraries, and describes a pet-project weather app that bundles a JSON city list for offline selection. It notes that this approach involves workarounds and would not be suitable for production.

### Source excerpt

Introduction Parsing JSON strings is a must-have on most Android projects that have server-client communication (of course there are some other formats like XML or Protobuf, but I guess JSON is the most common one at least at the moment). Setting up this communication is relatively straightforward: choose a library, add it to a project, describe models, create mappers, and so on. There are a bunch of various libraries to parse JSON: good old Gson, Jackson, or more modern Moshi, kotlinx-serialization and there are more. Set up of these libraries is different, there are differences in the internal implementation, but the general idea is the same for most of them: you can convert JSON-string into a set of objects and vice versa.

## Bad Kotlin Extensions

DevFeed: [Bad Kotlin Extensions](<https://devfeed.tech/articles/bad-kotlin-extensions-38646.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2021_01_25_bad_kotlin_extensions/>)

Published: 2021-01-25T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

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

Tags: [article](<https://devfeed.tech/tags/article.md>), [code](<https://devfeed.tech/tags/code.md>), [extensions](<https://devfeed.tech/tags/extensions.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [readability](<https://devfeed.tech/tags/readability.md>)

### AI overview

This article explains how overusing Kotlin extension methods can make code harder to read. It defines the benefits and costs of extensions and examines overly clever public extensions, including an operator-overloading factorial example, that may increase readers' cognitive load.

### Source excerpt

Introduction Kotlin extensions are a cool feature. Though trying to write 'idiomatic' Kotlin code some developers tend to overuse that feature making code worse than it could be without extensions. In this article, we'll go through some examples of how not to write Kotlin extensions. First of all, we need to try to define what a good extension is. It is simple though vague: good extension solves some problems. When we talk about code the main feature extensions have is to improve readability. Extension methods are static methods with the first parameter being a receiver of the extension. For example, these are equivalents:

## Debugging Proguard configuration issues

DevFeed: [Debugging Proguard configuration issues](<https://devfeed.tech/articles/debugging-proguard-configuration-issues-38645.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2021_01_18_debugging_proguard_configuration_issues/>)

Published: 2021-01-18T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [debugging](<https://devfeed.tech/topics/debugging.md>), [Android](<https://devfeed.tech/topics/android.md>), [APK](<https://devfeed.tech/topics/apk.md>), [obfuscation](<https://devfeed.tech/topics/obfuscation.md>), [builds](<https://devfeed.tech/topics/builds.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [apk](<https://devfeed.tech/tags/apk.md>), [article](<https://devfeed.tech/tags/article.md>), [build](<https://devfeed.tech/tags/build.md>), [debugging](<https://devfeed.tech/tags/debugging.md>), [obfuscation](<https://devfeed.tech/tags/obfuscation.md>)

### AI overview

A tutorial on diagnosing Android release-build bugs caused by Proguard/R8 configuration. It outlines the roles of obfuscation, code optimization, and resource optimization, and recommends using crash logs and APK contents to investigate issues.

### Source excerpt

Introduction It might happen so that there is a bug in your release build while in debug everything works fine. In many cases, it might be an issue with Proguard/R8 configuration. Of course, it is better to test your code thoroughly, properly configure Proguard if you, let's say, load some classes only via reflection and so on. But reality sometimes strikes and bugs might go to production. In this case, the first thing that is needed is to find a bug and fix it. And only then have some retrospective to mitigate such situations in the future. When the bug is in production already every minute counts, therefore it is important to have some plan. Proguard configuration seems complex to someone who didn't work with it, so I recommend to take a look at its main features. Most of the time I'd say that issue is easy can be found and fixed by analyzing crash report logs. But sometimes the log is not that clear. In this article I'd like to introduce the plan to find what part of "Proguard" causing an issue, so you can debug more effectively.

## Android Room Hidden Costs

DevFeed: [Android Room Hidden Costs](<https://devfeed.tech/articles/android-room-hidden-costs-38643.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2020_12_18_android_room_hidden_costs/>)

Published: 2020-12-18T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [Databases](<https://devfeed.tech/topics/databases.md>), [kotlin-flow](<https://devfeed.tech/topics/kotlin-flow.md>), [SQLite](<https://devfeed.tech/topics/sqlite.md>), [Reactive Streams](<https://devfeed.tech/topics/reactive-streams.md>), [RxJava](<https://devfeed.tech/topics/rxjava.md>), [Android](<https://devfeed.tech/topics/android.md>), [Android Studio](<https://devfeed.tech/topics/android-studio.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-studio](<https://devfeed.tech/tags/android-studio.md>), [databases](<https://devfeed.tech/tags/databases.md>), [kotlin-flow](<https://devfeed.tech/tags/kotlin-flow.md>), [reactive-streams](<https://devfeed.tech/tags/reactive-streams.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>), [sqlite](<https://devfeed.tech/tags/sqlite.md>)

### AI overview

This article examines the hidden costs of using Android Room to support reactive streams. It explains how Room uses SQLite triggers and an internal invalidation table to detect changes, trigger callbacks, and automatically re-query data for observers.

### Source excerpt

Introduction Android Room is an awesome AndroidX library. It is great because it provides a clean way of how to deal with databases without introducing some heavy concepts. Out of the box with Room one gets: simplified code comparing with raw SQLite queries working via DAO interfaces and models instead of Cursors auto-generated "boilerplate" code for queries migration support Android Studio tooling (compile-time verification of queries and highlight) support for reactive streams (RxJava, Kotlin Flow) and more In this article, I'd like to discover some hidden costs Room applies to support reactive streams and how one can try to avoid them.

## Boolean not

DevFeed: [Boolean not](<https://devfeed.tech/articles/boolean-not-38642.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2020_10_31_boolean_not/>)

Published: 2020-10-31T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

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

Tags: [boolean](<https://devfeed.tech/tags/boolean.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [logic](<https://devfeed.tech/tags/logic.md>), [operator](<https://devfeed.tech/tags/operator.md>), [programming](<https://devfeed.tech/tags/programming.md>), [programming-languages](<https://devfeed.tech/tags/programming-languages.md>), [xor](<https://devfeed.tech/tags/xor.md>)

### AI overview

This Kotlin tutorial explains Boolean negation, focusing on the not() method and the readability of different ways to express negative conditions. It recommends positive function names in general, with negative forms added when they represent common business logic, and explains that not() is an operator function.

### Source excerpt

Introduction Boolean is one of the essential types in programming and probably one of the simplest because it has only two values: true and false. Boolean are usually used as flags for control flow, specifically, conditions. if (string.isEmpty()) { println("String is empty") } It is not much interesting in Boolean, but in Kotlin there is one thing which might be confusing if used - it is method not(). Negate Boolean If we look at declaration of Boolean class in Kotlin we'll see five methods, four of which are pretty obvious: and, or, xor and compareTo. And the fifth is not:

## Calculating Middle Points for Integer and Floating-Point Numbers

DevFeed: [Calculating Middle Points for Integer and Floating-Point Numbers](<https://devfeed.tech/articles/middle-point-38641.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2020_10_28_middle_point/>)

Published: 2020-10-28T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [Programming](<https://devfeed.tech/topics/programming.md>), [floating-point](<https://devfeed.tech/topics/floating-point.md>), [math](<https://devfeed.tech/topics/math.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [exception](<https://devfeed.tech/tags/exception.md>), [floating-point](<https://devfeed.tech/tags/floating-point.md>), [function](<https://devfeed.tech/tags/function.md>), [programming](<https://devfeed.tech/tags/programming.md>), [test](<https://devfeed.tech/tags/test.md>)

### AI overview

This programming article examines how to calculate the middle point between two numbers. It discusses representable numeric subsets, input ordering and equality, integer cases with odd distances, and floating-point numbers.

### Source excerpt

Introduction Working with numbers in programming never was a simple thing. In math, we deal with various sets of numbers - whole numbers, rational, complex. All these sets are infinite - that means that for any number we can find another smaller one and one which is bigger. In programming when we work with numbers we deal with some subset of these sets - that many that can be represented with a given amount of bits. When we want to work with whole numbers we can use e.g. Integer, which are the numbers being able to be represented usually with 4 bits. For floating-point numbers - say Double - it is 8 bits. There is no plus or minus infinity (in Double there are +/- infinity, though they are used for special cases).

## Kotlin Functional Interfaces: Function reference and SAM conversion

DevFeed: [Kotlin Functional Interfaces: Function reference and SAM conversion](<https://devfeed.tech/articles/kotlin-functional-interfaces-function-reference-and-sam-conversion-38640.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2020_10_17_kotlin_functional_interfaces_function_references_and_sam_conversion/>)

Published: 2020-10-17T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [callback](<https://devfeed.tech/topics/callback.md>), [interfaces](<https://devfeed.tech/topics/interfaces.md>), [function](<https://devfeed.tech/topics/function.md>), [Java](<https://devfeed.tech/topics/java.md>)

Tags: [bytecode](<https://devfeed.tech/tags/bytecode.md>), [callback](<https://devfeed.tech/tags/callback.md>), [class](<https://devfeed.tech/tags/class.md>), [code](<https://devfeed.tech/tags/code.md>), [function](<https://devfeed.tech/tags/function.md>), [function-reference](<https://devfeed.tech/tags/function-reference.md>), [functional](<https://devfeed.tech/tags/functional.md>), [interfaces](<https://devfeed.tech/tags/interfaces.md>), [interop](<https://devfeed.tech/tags/interop.md>), [introduction](<https://devfeed.tech/tags/introduction.md>), [java](<https://devfeed.tech/tags/java.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>)

### AI overview

This tutorial examines Kotlin functional interfaces, function references, and SAM conversion in a callback scenario. It explains that Kotlin 1.4 supports SAM conversion for functional interfaces, allowing callback objects to be created from function references. Although separate callback objects are created for different method calls, they delegate to the same function reference and the program behaves correctly; explicit callback instances can avoid repeated allocations.

### Source excerpt

Introduction About two years ago I made a post about a tricky case in Kotlin-Java interop related to the usage of function references and SAM conversion. One of the points there was that in Kotlin, if interface is declared instead of a function, one has to explicitly create an object, therefore no caveats as with interop: val callback = object : ThirdParty.Callback { override fun onValueChanged(value: Int) { this@App.onValueChanged(value) } } With Kotlin 1.4 there is now a "Functional interface" which supports SAM conversion. And I've been asked on how it works in a similar situation. Let's find out.

## Kotlin Code Review: Avoiding Unproductive Nitpicking Over Concise and Idiomatic Code

DevFeed: [Kotlin Code Review: Avoiding Unproductive Nitpicking Over Concise and Idiomatic Code](<https://devfeed.tech/articles/kotlin-nitpicker-s-guide-38639.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2020_10_14_kotlin_nitpickers_guide/>)

Published: 2020-10-14T00:00:00Z

Content type: tutorial

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

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

Tags: [code-review](<https://devfeed.tech/tags/code-review.md>), [code-style](<https://devfeed.tech/tags/code-style.md>), [development-process](<https://devfeed.tech/tags/development-process.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [quality](<https://devfeed.tech/tags/quality.md>)

### AI overview

This article examines how code review can become unproductive when reviewers focus excessively on style, concision, or idiomatic Kotlin patterns. It discusses the trade-offs behind some Kotlin constructs and argues that shorter code is not automatically better.

### Source excerpt

Introduction Code review is an essential tool for a development team, which helps ensure high-quality standards of code. While reviewing others' code one might find bugs, design issues, and so on. One another part of reviewing is getting used to the codebase and following team's code style for better maintenance. Though it is pretty cool in theory, in practice team might face few issues, one of which is nitpicking. When review is bloated with dozens of similar comments related to e.g. how beautifully code looks like. Common code style is important, but having a lot of similar comments in each review doesn't help. Instead of trying to understand what code is doing, nitpicker writes a lot of similar comments on the style. Back and forth discussions or fixes of such slow down development process and overall make team's morale worse.

## Kotlin Flow Compared with RxJava: Benefits and Trade-offs

DevFeed: [Kotlin Flow Compared with RxJava: Benefits and Trade-offs](<https://devfeed.tech/articles/the-real-kotlin-flow-benefits-over-rxjava-38638.md>)

Original publisher: [Read original article](<https://krossovochkin.com/posts/2020_05_17_the_real_kotlin_flow_benefits_over_rxjava/>)

Published: 2020-05-17T00:00:00Z

Content type: article

Language: en

Sources: [Vasya Drobushkov](<https://devfeed.tech/sources/vasya-drobushkov.md>)

Topics: [kotlin-flow](<https://devfeed.tech/topics/kotlin-flow.md>), [RxJava](<https://devfeed.tech/topics/rxjava.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>)

Tags: [article](<https://devfeed.tech/tags/article.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-flow](<https://devfeed.tech/tags/kotlin-flow.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>)

### AI overview

A follow-up analysis compares Kotlin Flow with RxJava, discussing claimed benefits, drawbacks, and trade-offs. The article examines channels, StateFlow, subjects, and experimental API compatibility.

### Source excerpt

Source Introduction Recently the article about Kotlin Flow benefits over RxJava was published by Antoni Castejón García: Kotlin Flow benefits over RxJava Though Antoni made a good work and many thanks to him for providing his feedback and experience (we need to share our thoughts, this improves community acknowledgment in various areas) -- I found few places in the article with which I don't fully or partially agree. Some points, in my opinion, were missing. So, I decided to make a follow-up feedback post on what I consider the real benefits of Kotlin Flow over RxJava. Feedback is also a good thing as it helps us to drive forward and maybe look at the same things from a different angle.

[Next page](<https://devfeed.tech/sources/vasya-drobushkov.md?cursor=WyIyMDIwLTA1LTE3VDAwOjAwOjAwKzAwOjAwIiwgIjA4ZmYzMjg5LWU1OWItNGQ3ZS05ODlkLTJlMTYwYjNiZWFiNCJd>)