Top 12 takeaways from Droidcon NYC 2025
Discover key lessons from Droidcon NYC 2025 to improve Android apps with Jetpack Compose and Kotlin.
Discover key lessons from Droidcon NYC 2025 to improve Android apps with Jetpack Compose and Kotlin.
This past June, we had the opportunity to attend Droidcon NYC. This is one of the premier conferences to learn about the cutting-edge tech in Android and how others from different companies are solving hard problems and delivering quality solutions. This year was special since Capital One was a silver sponsor for the conference and we had 49 associates from all over the U.S. that attended.
Here are some top takeaways we took from the conference and wanted to share more broadly.
1. Handling configuration changes in Jetpack Compose
A key takeaway was managing configuration changes smoothly in Jetpack Compose. For frequent changes, like on foldables, you can opt out of full Activity recreation. First, add android:configChanges="orientation|screenSize|..." to your AndroidManifest.xml. Then, in your Composables, use rememberSaveable to preserve simple UI state across these changes. This avoids the visual disruption of a full restart. For the standard Android behavior where the Activity is recreated, ViewModels remain the correct tool to hold and persist complex data.
Safety ratings for handling configuration changes outside of Android Activity recreation
2. AI in Android development: Smarter responses and documentation
A great way to make AI give better responses is to link your team’s documentation to provide it with richer context. Likewise, AI agents can create a draft of your documentation for you (though make sure to review it). While agent use isn’t yet approved for use at Capital One, be on the lookout for when it gets approved, and continue using Gemini and Copilot in the meantime.
3. The rise of server-driven UI in Android apps
Server-Driven UI (SDUI) is great for quick design updates and A/B testing, as it lets you change the UI without needing a new app release, often leading to smaller native app sizes and faster load times with good network conditions. However, SDUI struggles with complex animations, map interactions and purely static screens because it introduces network dependency and can add significant backend complexity, potentially impacting performance on slower connections. It's a powerful tool for dynamic content and rapid experimentation, but you need to carefully consider the trade-offs in terms of complexity and specific UI requirements.
4. Coroutine exception handling to prevent app crashes
By default, when a child coroutine fails, the exception propagates upwards, canceling its parent and all other sibling coroutines within that scope. To prevent an app crash from this unhandled exception, use a CoroutineExceptionHandler in the context of a top-level coroutine, like one launched from viewModelScope or rememberCoroutineScope(), because it stops exception propagation and avoids a program crash, preventing any leaks.
5. Understanding Compose rendering and UI tree management
When @Composable functions are invoked, they contribute nodes to an in-memory tree that represents the UI. This helps track state and efficiently update changes.
6. Using SubcomposeLayout for dynamic and adaptive UIs
If you are making UI that isn’t fully known until runtime (ex: SDUI or loading an image that you don’t know the dimensions of), you can use SubcomposeLayout to first measure certain children, and then, based on those measurements, compose and measure other children. SubcomposeLayout is particularly useful for Server-Driven UIs and dynamically sizing elements based on their contents, allowing for flexible and adaptive layouts that wouldn't otherwise be achievable with standard Compose layouts that follow a strict measure-then-layout-then-draw order.
7. Coroutines vs. threads: Why Kotlin wins for concurrency
The lightweight and non-blocking nature of coroutines allows for a graceful cancellation at different points of their execution, which makes management of concurrent tasks easy and efficient. Threads, on the other hand, are difficult to cancel gracefully since they often perform blocking I/O or computations without explicit "cancellation points," meaning a cancellation request can go unnoticed while the thread is stuck waiting for an external event, potentially leaving shared resources in an inconsistent state and leading to deadlocks if it's abruptly terminated mid-operation.
8. Managing ExecutorService and lifecycle in Android
It's crucial to shut down an ExecutorService in Android because its threads won't stop automatically, leading to memory leaks and battery drain. You must manually call shutdown() when the component using it, like a ViewModel, is destroyed. For modern apps, however, it's far better to use Kotlin Coroutines with a CoroutineScope, as they handle this lifecycle management automatically and prevent leaks by design.
9. Avoid breaking structured concurrency in coroutines
A parent coroutine always waits for its children to complete. This means it is imperative that we use the correct scope and context because creating a new CoroutineScope starts an independent coroutine that is not a child of the original scope, thus breaking structured concurrency.
10. Building custom layouts in Jetpack Compose
Custom layouts in Jetpack Compose give developers fine-grained control over measurement and placement, leading to better performance and more efficient UI rendering. They help avoid unnecessary recompositions by handling size and position logic in the measurement phase. This makes them especially valuable for complex or dynamic UIs where precision and optimization are critical.
11. Exploring Kotlin multiplatform and cross-platform integration
Even though we don’t currently use KMP, it enables us to share core business logic across Android, iOS and other platforms, reducing code duplication and ensuring consistency. This boosts developer efficiency, accelerates time-to-market and improves code quality through shared testing.
12. Scaling real-world Android apps under pressure
Scaling real-world apps under fire requires making tough architectural decisions quickly while maintaining app stability and user trust. It involves balancing short-term fixes with long-term scalability, often under high-pressure conditions like outages, rapid growth or organizational shifts.
Looking back at Droidcon NYC 2025
The most memorable part of Droidcon NYC 2025 wasn’t just the technical insights—it was connecting with so many Capital One associates and fellow Android developers from across the community. As a silver sponsor, Capital One was proud to support this year’s event and contribute to conversations shaping the future of Android development.

