# Stories by Niek Haarman on Medium

Stories by Niek Haarman 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.

## Back to basics: Plugging in the Activity

DevFeed: [Back to basics: Plugging in the Activity](<https://devfeed.tech/articles/back-to-basics-plugging-in-the-activity-26000.md>)

Original publisher: [Read original article](<https://medium.com/@nhaarman/back-to-basics-plugging-in-the-activity-cc1e6a7f0ea4?source=rss-fceb7a60a849------2>)

Author: Niek Haarman

Published: 2019-01-28T23:06:32Z

Content type: tutorial

Language: en

Sources: [Stories by Niek Haarman on Medium](<https://devfeed.tech/sources/stories-by-niek-haarman-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [navigation](<https://devfeed.tech/topics/navigation.md>), [Application Development](<https://devfeed.tech/topics/application-development.md>), [Development](<https://devfeed.tech/topics/development.md>), [User interface design](<https://devfeed.tech/topics/ui-design.md>), [Testing](<https://devfeed.tech/topics/testing.md>), [Logging](<https://devfeed.tech/topics/logging.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [application-development](<https://devfeed.tech/tags/application-development.md>), [development](<https://devfeed.tech/tags/development.md>), [logging](<https://devfeed.tech/tags/logging.md>), [navigation](<https://devfeed.tech/tags/navigation.md>), [navigation-architecture](<https://devfeed.tech/tags/navigation-architecture.md>), [testing](<https://devfeed.tech/tags/testing.md>), [user-interface](<https://devfeed.tech/tags/user-interface.md>)

### AI overview

This tutorial explains how to use an Android Activity as a pluggable window for displaying screens managed by a composable navigator tree. It contrasts this approach with traditional multi-Activity applications, single-Activity applications using Fragments, and the Navigation Architecture Component.

### Source excerpt

...and wrapping up this series. In previous articles, I wrote about how you can create screens and navigators as composable building blocks for your application. Screens become little independent blocks of code that take input and produce an output, navigators tie these screens together by providing the input and listening for the output. Navigators in turn can be composable as well and accept input and provide output. In the end, you may end up with a tree of navigators with screens at their leafs. An example of navigation through an application where the user registers and enters the main application flow. See Back to basics: Navigation for more information. At the root of the tree, this leaves us with a stream of active screens which we can use for several things, like for testing, analytics or logging. But above all, this leaves us with a perfect hook to provide the user interface! Presenting screens In traditional Android application development, an Activity represented a single screen. To navigate to a different screen, you would start a new Activity and the OS would add it to a back stack for you. Activities have their own lifecycles and deal with their own layout. Unfortunately, the Activity class is a God class, and quickly leads to messy implementations. Over the years a lot of developers have switched to so called 'single Activity' applications, where the app would utilize a single Activity class to host the entire application flow. The most straightforward way to do this is using Fragments and the back stack in the FragmentManager. More recently, the Navigation Architecture Component provides another way to implement a single Activity application. Fragments however are just as messy as their Activity counter parts. In fact, Fragments are designed to be able to do everything an Activity can do! Displaying screens Instead, we can take our Activity instance and treat it as nothing more than a window that can display a user interface. It registers a listener w

## Back to basics: Navigation

DevFeed: [Back to basics: Navigation](<https://devfeed.tech/articles/back-to-basics-navigation-25999.md>)

Original publisher: [Read original article](<https://medium.com/@nhaarman/back-to-basics-navigation-9c08dacff228?source=rss-fceb7a60a849------2>)

Author: Niek Haarman

Published: 2018-10-25T09:12:40Z

Content type: tutorial

Language: en

Sources: [Stories by Niek Haarman on Medium](<https://devfeed.tech/sources/stories-by-niek-haarman-on-medium.md>)

Topics: [navigation](<https://devfeed.tech/topics/navigation.md>), [Android](<https://devfeed.tech/topics/android.md>), [Mobile](<https://devfeed.tech/topics/mobile.md>), [Development](<https://devfeed.tech/topics/development.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [android-development](<https://devfeed.tech/tags/android-development.md>), [androiddev](<https://devfeed.tech/tags/androiddev.md>), [development](<https://devfeed.tech/tags/development.md>), [flow](<https://devfeed.tech/tags/flow.md>), [fragments](<https://devfeed.tech/tags/fragments.md>), [login](<https://devfeed.tech/tags/login.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [navigation](<https://devfeed.tech/tags/navigation.md>), [onboarding](<https://devfeed.tech/tags/onboarding.md>), [payment](<https://devfeed.tech/tags/payment.md>), [screen](<https://devfeed.tech/tags/screen.md>), [shopping](<https://devfeed.tech/tags/shopping.md>), [state](<https://devfeed.tech/tags/state.md>)

### AI overview

A fundamentals-focused guide to in-app navigation in Android applications. It explains the back stack, reusable navigation flows, conditional paths based on user state, and how navigation responsibilities are handled by Activities and Fragments.

### Source excerpt

Previously I talked about the unfortunate design of the Activity class, and I went back to basics regarding screens in an application. This time, we're going back to basics regarding in-app navigation. What is meant by 'navigation'? In a typical mobile application, a user can navigate from one screen to another. Traveling through an application builds up a navigational state; in Android this is traditionally done with a back stack. Activities can start new Activities which get pushed upon a stack. When the user presses back, the top Activity gets popped off the stack, to reveal the previous Activity. You can modify how Activities are created and pushed upon the stack with several flags and attributes, which are described at length on the Understand Tasks and Back Stack page. The back stackFlows In a non-trivial application, there are often multiple 'flows' that can be defined: there might be a login flow, an onboarding flow, or a flow that takes you through a payment process. In the latter case, you might have a series of screens that start with a description of the user's shopping cart, followed by forms to enter shipping and payment information. Such flows are usually completely self contained, and can be reused when necessary. It may be possible to start a specific flow from anywhere in the app, allowing for dozens of paths through your application to exist. An example payment flow for a shopping application.Conditional navigation In your typical application, there is no strict sequence of screens that will appear in a fixed order. Depending on user input, the user can travel through different paths through your application. A dashboard screen for example can have multiple buttons that all lead the user to a different screen. Another thing to consider is that the next state of the navigation state is dependent on the some conditional state. If the user already has entered shipping and payment info a previous time, we may want to skip these forms and go straight t

## Back to basics: Screens

DevFeed: [Back to basics: Screens](<https://devfeed.tech/articles/back-to-basics-screens-26001.md>)

Original publisher: [Read original article](<https://medium.com/@nhaarman/back-to-basics-screens-5f15992ba796?source=rss-fceb7a60a849------2>)

Author: Niek Haarman

Published: 2018-09-30T19:10:45Z

Content type: tutorial

Language: en

Sources: [Stories by Niek Haarman on Medium](<https://devfeed.tech/sources/stories-by-niek-haarman-on-medium.md>)

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

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [business-logic](<https://devfeed.tech/tags/business-logic.md>), [interface](<https://devfeed.tech/tags/interface.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [user-interface](<https://devfeed.tech/tags/user-interface.md>)

### AI overview

The article examines screens in mobile applications as presentation-layer destinations composed of components for specific use cases. It argues that business logic should remain outside screens, and discusses lifecycle handling, user-interface responsibilities, and preserving state when Android processes are killed.

### Source excerpt

In a previous article, I talked about things that are wrong with the Activity class, the main conclusion being that it does too much. This time I want to look at an alternative way of looking at the concept of screens, stepping away from the design flaws of the Activity class. What is a screen? In a typical mobile application, the user can navigate from one destination to another. Each of these destinations can be regarded as a 'screen': a set of components that fulfill a very specific use case. For example, the main screen of a Twitter client may show a list of tweets to the user. The notion of 'screen' here is very much tied to the presentation layer of the application: when talking about screens, you're inevitably talking about UI and navigating through them. This means that business logic, such as processing use cases, calculating values and fetching network results has nothing to do in there. The lifecycle A lot of people have difficulties grasping the concept of the Activity lifecycle, but this part is one thing the Activity (somewhat) did right. When a screen becomes active in the application, it may want to start calling use cases in the business layer to retrieve some data. When it becomes visible to the user, it may want to register listeners to the UI to react to events. When it is replaced by another screen, it may need to stop listening for updates, and when it is destroyed (by popping it from a back stack for example), it may need to do some cleanup. Lifecycle callbacks are an excellent way to go and handle these scenarios. The user interface Usually, screens have something to show to the user. A screen may gather the data to show and pass this to the user interface, which uses this data and turns it in something visual for the user to interact with. This is one case where the Activity violates the single responsibility principle: next to handling lifecycle events, it is also responsible for inflating the user interface. Saving state Android's multitas

## Android Activities and Fragments: Responsibilities and Design Challenges

DevFeed: [Android Activities and Fragments: Responsibilities and Design Challenges](<https://devfeed.tech/articles/everything-that-s-wrong-with-android-s-activities-26002.md>)

Original publisher: [Read original article](<https://medium.com/@nhaarman/everything-thats-wrong-with-android-s-activities-ee784a84d775?source=rss-fceb7a60a849------2>)

Author: Niek Haarman

Published: 2018-08-27T19:38:46Z

Content type: article

Language: en

Sources: [Stories by Niek Haarman on Medium](<https://devfeed.tech/sources/stories-by-niek-haarman-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [App](<https://devfeed.tech/topics/app.md>), [configuration](<https://devfeed.tech/topics/configuration.md>), [navigation](<https://devfeed.tech/topics/navigation.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [applications](<https://devfeed.tech/tags/applications.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [lifecycle](<https://devfeed.tech/tags/lifecycle.md>), [memory](<https://devfeed.tech/tags/memory.md>), [multitasking](<https://devfeed.tech/tags/multitasking.md>), [navigation](<https://devfeed.tech/tags/navigation.md>), [permissions](<https://devfeed.tech/tags/permissions.md>)

### AI overview

The article examines the many responsibilities of Android Activities, including serving as application entry points, hosting user interfaces, managing lifecycles and state restoration, handling configuration changes, navigation, permissions, menus, and toolbars. It presents these responsibilities as valid use cases while highlighting the resulting design challenges.

### Source excerpt

..and Fragments, for that matter. Let's just kick off and have a look at what an Activity is capable of: 1. The Activity is an entry point The Activity is an entry point into your application that the user sees when they open your application. Upon clicking your application icon from a launcher app, an Activity instance is created and presented to the user. 2. The Activity hosts the window that interacts with the user. By calling setContentView in your Activity, you can inflate a layout that is bound to a Window instance hosted by the Activity. This allows the user to see and interact with your application. 3. The Activity has a lifecycle Android's multitasking mechanism allows for applications to be put in the background temporarily, and navigated back to when the user sees fit. To be able to react to these events, the Activity provides a set of callbacks you can implement. 4. The Activity needs state restoration Android's multitasking mechanism combined with limited memory can cause applications to be killed. To prevent a bad user experience when the user loses a message he or she was typing due to this, the Activity allows its state to be saved to a bundle. 5. An Activity can have a result Applications can start other applications to request a particular result. For example, the Contacts app can be launched to select a particular contact. When this is done, the result is sent back to the original application that started the request. Now these are all very valid use cases. They make up the foundation of all applications, and allow for perfectly fine applications to be created. But wait, there's more! 6. The Activity is destroyed on configuration changes When a device configuration changes, such as an orientation change or when the system local has changed, the Activity is destroyed and recreated with a new Resources set for the new configuration. 7. The Activity handles navigation When a user clicks an item in an item list Activity, the Activity can start a new A

## Reflecting on Android application development

DevFeed: [Reflecting on Android application development](<https://devfeed.tech/articles/reflecting-on-android-application-development-26003.md>)

Original publisher: [Read original article](<https://medium.com/@nhaarman/reflecting-on-android-application-development-49c397c7957c?source=rss-fceb7a60a849------2>)

Author: Niek Haarman

Published: 2018-08-22T19:35:54Z

Content type: article

Language: en

Sources: [Stories by Niek Haarman on Medium](<https://devfeed.tech/sources/stories-by-niek-haarman-on-medium.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [Development](<https://devfeed.tech/topics/development.md>), [Application Development](<https://devfeed.tech/topics/application-development.md>), [navigation](<https://devfeed.tech/topics/navigation.md>), [Processes](<https://devfeed.tech/topics/processes.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>), [application-development](<https://devfeed.tech/tags/application-development.md>), [development](<https://devfeed.tech/tags/development.md>), [mobile](<https://devfeed.tech/tags/mobile.md>), [navigation](<https://devfeed.tech/tags/navigation.md>), [process](<https://devfeed.tech/tags/process.md>)

### AI overview

A reflective overview of Android application development, tracing how early platform constraints shaped application states, lifecycles, Activities, navigation, multitasking, and process-death handling. It also discusses Fragments and the rise of single-Activity approaches.

### Source excerpt

In this article I want to go back to the Android system as of Android 1.0, and look at the reasons that make Android app development what it is today and why certain decisions were made. Back in 2008, mobile devices were not the almighty powerful devices with 4GB of RAM and octo-core processors we have in our pockets today. Instead, storage was limited, memory was scarce and the network was slow. Despite of all this, users were able to switch between multiple applications on their phones, 'talk' to other applications to request data, and you might have guessed it, even take phone calls! The launcher app in Android 1.1 I will be reflecting on the fundamentals of developing applications for Android, looking at application states, lifecycles, monolith activities and modern approaches. TL;DR Dealing with process deaths is important; Lifecycles are useful, not difficult; Dealing with Fragments is hard; Single-Activity approaches are rising; The back stack is hard. In-app navigation A typical Android application has more than one screen to present to the user. A messaging app for example could start with a screen that shows a list of message threads. By clicking a specific thread, the application navigates to a new screen that shows the thread and allows the user to send messages. From here, the user might even be able to go to a screen that shows the details of the contact he is messaging with. To return to the first screen, the user can simply press the back button a couple of times. In the beginning of Android app development, this was typically done by defining an Activity for each screen in the application. The OS starts the 'main' Activity when the app is launched, and by navigating through the application Activities are pushed and popped off a stack, which is where the name 'back stack' comes from. Additionally, developers can use flags when starting Activities to manipulate the stack. Multitasking and process deaths Multitasking in Android meant that you could swi

## A dive into Async-Await on Android

DevFeed: [A dive into Async-Await on Android](<https://devfeed.tech/articles/a-dive-into-async-await-on-android-25997.md>)

Original publisher: [Read original article](<https://medium.com/@nhaarman/a-dive-into-async-await-on-android-5a6699029aa3?source=rss-fceb7a60a849------2>)

Author: Niek Haarman

Published: 2016-11-03T16:09:29Z

Content type: tutorial

Language: en

Sources: [Stories by Niek Haarman on Medium](<https://devfeed.tech/sources/stories-by-niek-haarman-on-medium.md>)

Topics: [async/await](<https://devfeed.tech/topics/async-await.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [Code](<https://devfeed.tech/topics/code.md>), [ui](<https://devfeed.tech/topics/ui.md>), [Network](<https://devfeed.tech/topics/network.md>), [Database](<https://devfeed.tech/topics/database.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [async](<https://devfeed.tech/tags/async.md>), [asynchronous](<https://devfeed.tech/tags/asynchronous.md>), [await](<https://devfeed.tech/tags/await.md>), [blocking](<https://devfeed.tech/tags/blocking.md>), [callback](<https://devfeed.tech/tags/callback.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [database](<https://devfeed.tech/tags/database.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-compiler](<https://devfeed.tech/tags/kotlin-compiler.md>), [main-thread](<https://devfeed.tech/tags/main-thread.md>), [network](<https://devfeed.tech/tags/network.md>), [textview](<https://devfeed.tech/tags/textview.md>)

### AI overview

This tutorial explains async-await on Android using Kotlin coroutines, focusing on handling long-running network and database operations without blocking the UI thread. It contrasts nested callbacks with suspension functions such as asyncUI and await, and describes how the Kotlin compiler transforms the code.

### Source excerpt

Note: this article was written for a preview version of coroutines for Kotlin. Its details have changed since then. In a previous article I provided a glimpse into the world of async-await on Android. Now it's time to dive a little bit deeper in this upcoming functionality in Kotlin 1.1 What is async-await for? When dealing with long-running operations like network calls or database transactions, you need to make sure you schedule this work to a background thread. If you forget to do this, you may end up with blocking the UI thread until the task is finished. During that time, the user cannot interact with your application. Unfortunately when you schedule a new task in the background, you cannot use its result directly. Instead, you're gonna have to use some sort of callback. When that callback is invoked with the result of the operation, you can continue with what you want to do, for example run another network request. This easily flows in what people call a 'callback hell': multiple nested callbacks, all waiting to be invoked when some long-running task has finished. fun retrieveIssues() { githubApi.retrieveUser() { user -> githubApi.repositoriesFor(user) { repositories -> githubApi.issueFor(repositories.first()) { issues -> handler.post { textView.text = "You have issues!" } } } } } This snippet of code does three network requests, and finally posts a message to the main thread to update the text of some TextView. Fixing this with async-await With async-await, you can program that same function in a more imperative way. Instead of passing a callback to the function, you can call a suspension function await which lets you use the result of the task in a way that resembles normal synchronous code: fun retrieveIssues() = asyncUI { val user = await(githubApi.retrieveUser()) val repositories = await(githubApi.repositoriesFor(user)) val issues = await(githubApi.issueFor(repositories.first())) textView.text = "You have issues!" } This snippet of code still does three n

## A glimpse of Async-Await on Android

DevFeed: [A glimpse of Async-Await on Android](<https://devfeed.tech/articles/a-glimpse-of-async-await-on-android-25998.md>)

Original publisher: [Read original article](<https://medium.com/@nhaarman/async-await-in-android-f0202cf31088?source=rss-fceb7a60a849------2>)

Author: Niek Haarman

Published: 2016-10-31T12:25:13Z

Content type: tutorial

Language: en

Sources: [Stories by Niek Haarman on Medium](<https://devfeed.tech/sources/stories-by-niek-haarman-on-medium.md>)

Topics: [async/await](<https://devfeed.tech/topics/async-await.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [Android](<https://devfeed.tech/topics/android.md>), [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [API](<https://devfeed.tech/topics/api.md>), [GitHub API](<https://devfeed.tech/topics/github-api.md>), [Database](<https://devfeed.tech/topics/database.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-app-development](<https://devfeed.tech/tags/android-app-development.md>), [async](<https://devfeed.tech/tags/async.md>), [await](<https://devfeed.tech/tags/await.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [database](<https://devfeed.tech/tags/database.md>), [developer](<https://devfeed.tech/tags/developer.md>), [github](<https://devfeed.tech/tags/github.md>), [i](<https://devfeed.tech/tags/i.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [network](<https://devfeed.tech/tags/network.md>), [techniques](<https://devfeed.tech/tags/techniques.md>), [thread](<https://devfeed.tech/tags/thread.md>), [threads](<https://devfeed.tech/tags/threads.md>), [ui](<https://devfeed.tech/tags/ui.md>)

### AI overview

This Android developer article compares several ways to perform network and I/O work without blocking the main thread, including threads, AsyncTask, callbacks, Rx, and Kotlin coroutines with async-await. Using a GitHub API example, it shows how coroutines can suspend computation while allowing continuation on the main thread, improving code readability. The article notes that it targets a preview version of Kotlin coroutines and omits cancellation and listener-removal details.

### Source excerpt

Note: this article was written for a preview version of coroutines for Kotlin. Its details have changed since then. Kotlin 1.1 will bring coroutines to the language, which allows computations to be suspended at some points and continue later on. The obvious example is async-await, as introduced a couple of years ago in C#. Every Android developer knows that when you deal with network requests and other I/O tasks, you will need to make sure you don't block the main thread, and don't touch the UI from a background thread. Over the years dozens of techniques have come and gone. This article lists a few of the most used ones, and shows an example of the goodness that async-await can bring. The scenario We will fetch a user instance from the Github api and store it in some database. When this is done we show the result on-screen. I won't be explaining the techniques, as they should speak for themselves. Plain old threads Manual, full control fun threads() { val handler = Handler() Thread { try { val user = githubApi.user() userRepository.store(user) handler.post { threadsTV.text = "threads: [$user]" } } catch(e: IOException) { handler.post { threadsTV.text = "threads: [User retrieval failed.]" } } }.start() }Android's AsyncTask Nobody uses these anymore, right? fun asyncTask() { object : AsyncTask<Unit, Unit, GithubUser?>() { private var exception: IOException? = null override fun doInBackground(vararg params: Unit): GithubUser? { try { val user = githubApi.user() userRepository.store(user) return user } catch(e: IOException) { exception = e return null } } override fun onPostExecute(user: GithubUser?) { if (user != null) { asyncTaskTV.text = "asyncTask: [$user]" } else { asyncTaskTV.text = "asyncTask: [User retrieval failed.]" } } }.execute() }Callbacks Callback-hell, anyone? fun callbacks() { githubApi.userFromCall().enqueue(object : Callback<GithubUser> { override fun onResponse(call: Call<GithubUser>, response: Response<GithubUser>) { val user = response.body() userR