jetc.dev Newsletter Issue #89

Published: 2021-11-02

The Android Dev Summit 2021 happened, and we have the YouTube links to prove it! 😁

We also look at the beta releases for Compose for Android and Compose Multiplatform, explore how to show half a menu item, learn what slot APIs really mean, and pick some colors. And, in the return of “…And One More Thing”, I point out how not all configuration changes are created equal, and what that might mean for your composable activities.

Summit Summary

Google hosted their Android Dev Summit 2021 last week. In this case, “hosted” was all virtual. There were a few live sessions, but mostly the material was pre-recorded, reminiscent of how Google I|O 2021 happened in May. But, as you might imagine, there were quite a few presentations on Compose, including:

Also, How to Build Modern App Widgets in Android 12 has a bit of material on Glance as applied to app widgets, and other presentations have bits of Compose-related material as well.

Beta Breakdown

Reviewing the release notes for the latest Jetpack Compose update!

Most of Compose moved to 1.1.0-beta01, marking the first beta for a minor release! 🎉

The exception was androidx.compose.material3, a new artifact that implements a tiny slice of Material 3. Early reports state that it is missing a lot of basic composables, and that the theme system was revamped, so be careful when you try adopting it.

There are hints at an upcoming “bring into view” API for telling a scrollable container to scroll such that a particular child composable is visible. However, this appears to tie into a BringIntoViewRequester that either has not shipped or did not get into the documentation.

In addition, there is better support for hover and focus states on ripples, which affects Button() and related Material composables.

One Off the Stack, One Off the Slack

You’ve got questions. That’s understandable!

Showing Half a Menu Item

Until BringIntoViewRequester is ready, we still encounter problems where we want to ensure that a certain composable is visible. In some cases, like DropDownMenu(), we could elect to expand the composable to help with matters, such as ensuring that half a row is visible at the bottom, so users know that the menu is scrollable. Learn how to implement this, in this week’s highlighted Stack Overflow question!

How Do We Observe Lifecycle Events?

You may have analytics code, or similar things, tied to onStart() of an activity-centric or fragment-centric app. Figuring out how to map that to the world of Compose is a two-tier problem: how to find out about onStart() in a composable, then deciding whether that is really a good idea. Learn more in this week’s highlighted Kotlinlang #compose Slack thread!

Composable Commentary

Posts, videos, and other new information related to Jetpack Compose!

Compose Multiplatform Goes Beta

Compose’s 1.1.0-beta01 was not the only beta of note in the Composiverse. JetBrains’ Compose Multiplatform — the wrapper around Compose for Desktop and Compose for Web, along with Compose for Android — also is now in beta. Not only have the Desktop and Web subsystems been improved, but they are starting to lock down the APIs in preparation for the upcoming stable release.

Video: Jetpack Compose Slot APIs

We hear about “slots” in Compose APIs a lot — in this video, Scott Stanchfield attempts to explain to us what slots are, what problems they solve, and how to implement them in your own composables. In particular, Scott ties the “slots” approach back to a decades-old software pattern: template methods.

Video: Screenshot Testing All the Things!

Our favorite Italian Compose dev screencasting duo is back at it, celebrating six months of writing composables and frequently getting them to work! This time, they have Mark Allison back as a guest, looking at using Shot and other techniques for implementing screenshot testing to detecting regressions in your composables’ output.

Slides: What About… a Desktop App?

Sebastiano Poggi does solo stuff too, outside of “Code with the Italians”! He delivered a presentation on Compose for Desktop and how Compose for Android developers can translate our skills to this new/old platform. The link is to a site with links to the slides and related resources.

Medium: Creating a Custom Theme in Jetpack Compose

Lucas Yuji Yoshimine reviews the basics of setting up a classic Compose Material theme using MaterialTheme(), including extending it for other types of themeable elements, such as standardized space sizes.

Resource Roundup

100% pure code!

GitHub: godaddy / compose-color-picker

Rebecca Franks released an HSV color picker, in the form of a ClassicColorPicker() composable. You supply a lambda expression to be invoked as the user chooses colors in the picker.

GitHub: farhanroy / compose-awesome-dialog

Farhan Roy created a library that implements a particular style of dialog, with success/failure/info icons along with a title, subtitle, and action buttons. This all gets wrapped up in a ComposeAwesomeDialog() composable to display when appropriate.

…And One More Thing

There seem to be two schools of thought in Google regarding configuration changes and Compose. One group recommends using the Jetpack ViewModel, much as you would in a pre-Compose app. The other group recommends avoiding the Android-specific ViewModel class and instead recommends opting out of all configuration changes via android:configChanges in the manifest.

In the beginning, I was not happy about that second approach. I would link to a particular Slack thread on it, but Slack’s search is… not good.

The concern that I cited at the time was developers not covering everything in android:configChanges. For example, what is documented for android:configChanges does not match what is in the source code. If you combine that with new configuration changes in the future and device manufacturer changes, I was concerned that we would miss changes that would trigger activity recreation.

This past weekend uncovered a new scenario for that: unblockable configuration changes. While historically this was limited to devices that had device-wide theme changers using RROs, on Android 12, changing wallpaper also triggers a unblockable configuration change. By “unblockable”, I mean that there is no available android:configChanges opt-out for the event. If the user changes their wallpaper on Android 12, your activities will be destroyed and recreated, whether you like it or not.

The counter-argument (originally from Google’s Adam Powell, IIRC), is that even in those edge cases, the behavior of the configuration change is very similar to that of process termination and rapid restart. If the user puts your UI in the background and returns to it within a half-hour, but Android terminated your process while your UI was in the background, Android will not only fork a new process for you but will restart whatever activity the user had been on. We rely on the saved instance state Bundle — or rememberSaveable() in Compose — to hold onto key data that we will need to restore the UI. Google’s Jim Sproch echoed that counter-argument recently in Twitter.

The catch is that activity recreation (after an unblockable or missed configuration change) is not the same as process recreation (after process termination and rapid restart). Your repositories, data sources, and other singletons remain intact after activity recreation, whereas they are created from scratch with process recreation. Ideally, if anything, this is a positive development: whatever you have cached in RAM is still there for your use. However, not all apps are well-architected, and I worry about developers not testing configuration changes, on the grounds that they think that they are opting out of all configuration changes.

Despite this weekend’s revelations, I have still come around to the second group’s line of thinking, and that we can try to opt out of configuration changes. Just make sure that you are testing these other edge cases as well. I suppose the nice thing about Android 12 is that it makes testing this edge case easy: just change your wallpaper.