Tag Archives: Kotlin

Meet the Android Studio Team: A Conversation with Engineering Director, Tor Norbye

Posted by Ashley Tschudin – Social Media Specialist, MTP at Google

Welcome to "Meet the Android Studio Team," our new ongoing blog series. Each week, we'll introduce you to the talented people behind Android Studio. Get to know the engineers, designers, product managers, and more who create the best possible experience for Android developers like you. Join us and explore their unique perspectives.


Tor Norbye: Building Android Studio for You

Trevor Johns, Staff Developer Programs Engineer

Meet Tor Norbye, an Engineering Director at Google leading the development of Android Studio.

From his early days of coding to leading the charge on AI-powered development tools, Tor shares his insights on the evolution of Android and the vital role Android Studio plays in its future.

We'll delve into the challenges of creating developer tools, the importance of community feedback, and how Google strives to empower developers worldwide.


Can you tell us about your journey to becoming a part of the Android Studio team? What sparked your interest in Android development?

I grew up in Norway and I was fascinated by programming; my first exposure was as a middle schooler reading program listings in magazines (yes, in the early 80s, monthly computer magazines would include source code!) and in 1983 I got my hands on a microcomputer, and knew immediately that's what I wanted to do as a career. And now, 40+ years later, I still love programming. It's not my day-job anymore, but I still write bits and pieces of code for Android Studio on the shuttle and during quiet periods.

I've worked on developer tools my whole career - first, 14 years at Sun Microsystems after college. In 2010 I got increasingly interested in the rise of mobile computing and really wanted to be part of it, so I joined the Android team, and I've been here since.

Back then there was no "Android Studio". At the time we were working on Eclipse-based tooling for Android development. But we all knew that IntelliJ was the gold-standard for Java development, so a couple years later we began the work on building Android Studio on top of IntelliJ and with various new and ported code from our Eclipse plugins. I then had the honor of doing the unveiling demo at Google I/O in 2013.

How has the integration of AI and machine learning impacted Android developer capabilities, and how do you see it evolving in the future?

The integration of artificial intelligence has absolutely impacted Android developer capabilities, and this is just the beginning.

I felt very fortunate to be part of bringing about the massive shift from desktop computing to mobile computing when I joined Android, and I can't believe I get to be in the middle of a second massive industry shift as well, with AI and large language models.

I actually spend a lot of my time on this, working with Studio engineers, UX and product managers on our various AI related features, and talking to partner AI teams at Google. We've made a huge amount of progress in the last couple of years, both on the Studio feature integration side, as well as Google-wide on the AI side. While there is some skepticism that we're just doing AI features for AI's sake, I don't see it that way. With AI, we can suddenly, with relatively low effort, build useful features not previously possible.

Here's a very simple example from the latest Studio version: When you invoke the Rename refactoring feature, we use Gemini to add additional naming suggestions into the name popup based on what your code is doing. Here we're helping you pick good names – and naming is famously one of the two hardest problems in computer science – naming, cache invalidation and off-by-one errors. Yet LLMs are good at this – so coupled with the safe refactoring machinery in the IDE, we were able to safely add a useful feature with relatively low engineering cost on the IDE side (of course, this is building on top of a massive investment from Google over on the Gemini side).

The field is moving incredibly quickly, so it's hard to predict where things are going, but we're actively working in several areas, making the AI more aware of your codebase, and making it handle larger, complex tasks via AI Agents, and so much more.

What are some of the biggest challenges you've faced in your career as a developer, and how have those experiences shaped your approach to your job?

Earlier in my career, at a different company, we had big annual releases. I took a lot of pride in my productivity, and as my responsibilities grew, I'd try to do the impossible and deliver, no matter what. I'd not only work long hours, but I'd also try to work as quickly as I can. This led to a lot of stress. I remember putting my (at the time) young children to bed and impatiently waiting for them to fall asleep such that I could head back out to the garage office and start the evening coding shift. And I knew that stress isn't healthy, so I'd also stress about being stressed! This obviously wasn't sustainable.

Now, I emphasize work life balance not only for myself, but also for our team. I want to make sure our work is sustainable, and that people can thrive and be in it for the long term. It's a marathon, not a sprint.

Can you share an example of how feedback from the developer community has directly influenced a feature or improvement?

We have a number of feedback channels; the most important one is the Android Studio issue tracker.

We still have a very large backlog of bugs, so it's easy to get the impression that we're ignoring user reports, but that's not true. As a team, we've actually fixed several thousand bugs in 2024 alone. The best bugs are those that are clear and actionable, ideally with steps to reproduce.

I'm also very thankful to everyone who turns on data sharing in Studio; if you don't already, please consider it! Our analytics is more of an indirect, but still vital, feedback channel from the community. In addition to collecting information on, for example, which menu items are clicked, we also use it to collect quality metrics on system health. For instance, when we detect that the UI is lagging (such as a 1+ second freeze in the UI thread), we grab a thread dump and send it to the server, then aggregate these into a dashboard where we can see top freeze spots in the IDE across the user population, and can focus our efforts on fixing those.

How does the Studio team contribute to Google's broader vision for the Android platform?

In Android Studio we're always making sure we support the latest technologies and recommendations from Android, Firebase, Material, and other Google technologies. That way, it's easier for developers to adopt recommendations, like using Kotlin, Coroutines, Compose, Material, and so on.

Explore the Power of AI

Unlock the full potential of AI in your Android development journey. Explore the latest advancements in Android Studio, including intelligent code completion, automated refactoring, and other AI-driven tools.

Stay tuned!

Don't miss our next and final installment in the "Meet the Android Studio Team" series; we'll feature one more talented team member and share their unique perspective. Stay tuned to learn more about the amazing people behind Android Studio.

Find Tor Norbye on Bluesky.

Meet the Android Studio Team: A Conversation with Staff Developer Programs Engineer, Trevor Johns

Posted by Ashley Tschudin – Social Media Specialist, MTP at Google

Android Studio isn't just code and algorithms – it's built by real people with fascinating stories. Our "Meet the Android Studio Team" series gives you a glimpse into the lives and passions of the talented individuals who craft the tools you use every day. Tune in each month to meet new team members and discover their unique journey.


Trevor Johns: Building Android Studio for You

Trevor Johns, Staff Developer Programs Engineer

Meet Trevor Johns, a seasoned Staff Developer Programs Engineer at Google.

Reflecting on his journey, Trevor sheds light on the most impactful advancements in the Android ecosystem and offers a glimpse into his vision for the future where AI plays a pivotal role in streamlining development workflows.

Trevor discusses the Android Studio team's dedication to enhancing developer productivity through AI, highlighting their focus on understanding and addressing developer needs, and reflects on the dynamic journey of Android development while sharing valuable insights.


Can you tell us about your journey to becoming a part of the Android Studio team? What sparked your interest in Android development?

I've been at Google in various roles since Google since 2007, and transferred to Android team in 2009 shortly after the launch of the HTC G1 — the first publicly available Android phone. Even in those early days it was clear that mobile computing was a unique opportunity to reimagine many of the limitations of desktop computers and how users interact with the digital world.

Among my first projects were helping developers optimize their apps for the MyTouch 3G and Motorola Droid, as well as creating developer resources for Android's 1.6 Donut release.

Over the years, I've worked on various parts of the Android OS including our first tablet devices, Android Wear, helping develop the original Android support libraries (which later became Jetpack), and the migration to Kotlin.

Recently I joined the Android Studio team to help improve developer productivity, using AI to streamline common developer tasks and help developers have more time to focus on creativity.

How does the Android Studio team ensure that products or features meet the ever-changing needs of developers?

Like the rest of Android, we approach development of new features by listening to our developer community. We hold regular listening sessions with publishers, work with our UX research team to conduct case studies, and participate in online discussions to get a sense for where developers face the most friction — and then try to find ways to reduce that friction.

For example, we developed Gemini in Android Studio's integration with Play Vitals and Firebase Crashlytics based on feedback from members of the developer community who commented to let us know where they would find AI most useful across their developer workflow.

Speaking of, if you'd like to provide us with feedback, you can always file a bug or feature request on the Android Studio issue tracker.

How does the Studio team contribute to Google's broader vision for the Android platform?

In addition to listening to the Android community, we also keep an eye on what's being developed across the rest of the Android team and make sure that Android Studio has the right tools to help developers quickly migrate between Android versions and adopt those new platform features.

Beyond that, the Studio team provides leading edge editing tools to make sure that Android remains one of the easiest computing platforms to develop for — unlocking this unique computing platform for millions of developers.

In your opinion, what is the most impactful feature or improvement the Android team has introduced in recent years, and why?

For developers, my answer would have to be the migration to Kotlin. This language has modernized the Android developer experience — letting developers write apps with less code and fewer errors. It's also the foundation for Jetpack Compose, which is the future of Android UI development.

If you could wave a magic wand and add one dream feature to the Android universe, what would it be and why?

I'd love to see Gemini be able to not just autocomplete code for me, but generate scaffolds for new projects. That way I can focus on building features rather than worrying about basic structure when starting a new project.

Develop Android Apps with Kotlin

Follow Trevor's lead and embrace the power of Kotlin for modern Android development. Enhance your skills and write better Android apps faster with Kotlin.

Stay tuned!

Get ready for another inspiring story! The "Meet the Android Studio Team" series continues next week with a new team member in the spotlight. Don't miss their unique insights and journey.

Find Trevor Johns on LinkedIn, X, Bluesky, and Medium.

Media3 1.5.0 — what’s new?

Posted by Kristina Simakova – Engineering Manager

This article is cross-published on Medium

Media3 1.5.0 is now available!

Transformer now supports motion photos and faster image encoding. We’ve also simplified the setup for DefaultPreloadManager and ExoPlayer, making it easier to use. But that’s not all! We’ve included a new IAMF decoder, a Kotlin listener extension, and easier Player optimization through delegation.

To learn more about all new APIs and bug fixes, check out the full release notes.

Transformer improvements

Motion photo support

Transformer now supports exporting motion photos. The motion photo’s image is exported if the corresponding MediaItem’s image duration is set (see MediaItem.Builder().setImageDurationMs()) Otherwise, the motion photo’s video is exported. Note that the EditedMediaItem’s duration should not be set in either case as it will automatically be set to the corresponding MediaItem’s image duration.

Faster image encoding

This release accelerates image-to-video encoding, thanks to optimizations in DefaultVideoFrameProcessor.queueInputBitmap(). DefaultVideoFrameProcessor now treats the Bitmap given to queueInputBitmap() as immutable. The GL pipeline will resample and color-convert the input Bitmap only once. As a result, Transformer operations that take large (e.g. 12 megapixels) images as input execute faster.

AudioEncoderSettings

Similar to VideoEncoderSettings, Transformer now supports AudioEncoderSettings which can be used to set the desired encoding profile and bitrate.

Edit list support

Transformer now shifts the first video frame to start from 0. This fixes A/V sync issues in some files where an edit list is present.

Unsupported track type logging

This release includes improved logging for unsupported track types, providing more detailed information for troubleshooting and debugging.

Media3 muxer

In one of the previous releases we added a new muxer library which can be used to create MP4 container files. The media3 muxer offers support for a wide range of audio and video codecs, enabling seamless handling of diverse media formats. This new library also brings advanced features including:

    • B-frame support
    • Fragmented MP4 output
    • Edit list support

The muxer library can be included as a gradle dependency:

implementation ("androidx.media3:media3-muxer:1.5.0")

Media3 muxer with Transformer

To use the media3 muxer with Transformer, set an InAppMuxer.Factory (which internally wraps media3 muxer) as the muxer factory when creating a Transformer:

val transformer = Transformer.Builder(context)
    .setMuxerFactory(InAppMuxer.Factory.Builder().build())
    .build()

Simpler setup for DefaultPreloadManager and ExoPlayer

With Media3 1.5.0, we added DefaultPreloadManager.Builder, which makes it much easier to build the preload components and the player. Previously we asked you to instantiate several required components (RenderersFactory, TrackSelectorFactory, LoadControl, BandwidthMeter and preload / playback Looper) first, and be super cautious on correctly sharing those components when injecting them into the DefaultPreloadManager constructor and the ExoPlayer.Builder. With the new DefaultPreloadManager.Builder this becomes a lot simpler:

    • Build a DefaultPreloadManager and ExoPlayer instances with all default components.
val preloadManagerBuilder = DefaultPreloadManager.Builder()
val preloadManager = preloadManagerBuilder.build()
val player = preloadManagerBuilder.buildExoPlayer()

    • Build a DefaultPreloadManager and ExoPlayer instances with custom sharing components.
val preloadManagerBuilder = DefaultPreloadManager.Builder().setRenderersFactory(customRenderersFactory)
// The resulting preloadManager uses customRenderersFactory
val preloadManager = preloadManagerBuilder.build()
// The resulting player uses customRenderersFactory
val player = preloadManagerBuilder.buildExoPlayer()

    • Build a DefaultPreloadManager and ExoPlayer instances, while setting the custom playback-only configurations on the ExoPlayers.
val preloadManagerBuilder = DefaultPreloadManager.Builder()
val preloadManager = preloadManagerBuilder.build()
// Tune the playback-only configurations
val playerBuilder = ExoPlayer.Builder().setFooEnabled()
// The resulting player will have playback feature "Foo" enabled
val player = preloadManagerBuilder.buildExoPlayer(playerBuilder)

Preloading the next playlist item

We’ve added the ability to preload the next item in the playlist of ExoPlayer. By default, playlist preloading is disabled but can be enabled by setting the duration which should be preloaded to memory:

player.preloadConfiguration =
    PreloadConfiguration(/* targetPreloadDurationUs= */ 5_000_000L)

With the PreloadConfiguration above, the player tries to preload five seconds of media for the next item in the playlist. Preloading is only started when no media is being loaded that is required for the ongoing playback. This way preloading doesn’t compete for bandwidth with the primary playback.

When enabled, preloading can help minimize join latency when a user skips to the next item before the playback buffer reaches the next item. The first period of the next window is prepared and video, audio and text samples are preloaded into its sample queues. The preloaded period is later queued into the player with preloaded samples immediately available and ready to be fed to the codec for rendering.

Once opted-in, playlist preloading can be turned off again by using PreloadConfiguration.DEFAULT to disable playlist preloading:

player.preloadConfiguration = PreloadConfiguration.DEFAULT

New IAMF decoder and Kotlin listener extension

The 1.5.0 release includes a new media3-decoder-iamf module, which allows playback of IAMF immersive audio tracks in MP4 files. Apps wanting to try this out will need to build the libiamf decoder locally. See the media3 README for full instructions.

implementation ("androidx.media3:media3-decoder-iamf:1.5.0")

This release also includes a new media3-common-ktx module, a home for Kotlin-specific functionality. The first version of this module contains a suspend function that lets the caller listen to Player.Listener.onEvents. This is a building block that’s used by the upcoming media3-ui-compose module (launching with media3 1.6.0) to power a Jetpack Compose playback UI.

implementation ("androidx.media3:media3-common-ktx:1.5.0")

Easier Player customization via delegation

Media3 has provided a ForwardingPlayer implementation since version 1.0.0, and we have previously suggested that apps should use it when they want to customize the way certain Player operations work, by using the decorator pattern. One very common use-case is to allow or disallow certain player commands (in order to show/hide certain buttons in a UI). Unfortunately, doing this correctly with ForwardingPlayer is surprisingly hard and error-prone, because you have to consistently override multiple methods, and handle the listener as well. The example code to demonstrate how fiddly this is too long for this blog, so we’ve put it in a gist instead.

In order to make these sorts of customizations easier, 1.5.0 includes a new ForwardingSimpleBasePlayer, which builds on the consistency guarantees provided by SimpleBasePlayer to make it easier to create consistent Player implementations following the decorator pattern. The same command-modifying Player is now much simpler to implement:

class PlayerWithoutSeekToNext(player: Player) : ForwardingSimpleBasePlayer(player) {
  override fun getState(): State {
    val state = super.getState()
    return state
      .buildUpon()
      .setAvailableCommands(
        state.availableCommands.buildUpon().remove(COMMAND_SEEK_TO_NEXT).build()
      )
      .build()
  }

  // We don't need to override handleSeek, because it is guaranteed not to be called for
  // COMMAND_SEEK_TO_NEXT since we've marked that command unavailable.
}

MediaSession: Command button for media items

Command buttons for media items allow a session app to declare commands supported by certain media items that then can be conveniently displayed and executed by a MediaController or MediaBrowser:

image of command buttons for media items in the Media Center of android Automotive OS
Screenshot: Command buttons for media items in the Media Center of Android Automotive OS.

You'll find the detailed documentation on android.developer.com.

This is the Media3 equivalent of the legacy “custom browse actions” API, with which Media3 is fully interoperable. Unlike the legacy API, command buttons for media items do not require a MediaLibraryService but are a feature of the Media3 MediaSession instead. Hence they are available for MediaController and MediaBrowser in the same way.


If you encounter any issues, have feature requests, or want to share feedback, please let us know using the Media3 issue tracker on GitHub. We look forward to hearing from you!


This blog post is a part of Camera and Media Spotlight Week. We're providing resources – blog posts, videos, sample code, and more – all designed to help you uplevel the media experiences in your app.

To learn more about what Spotlight Week has to offer and how it can benefit you, be sure to read our overview blog post.

Google @ KotlinConf 2024: A Look Inside Multiplatform Development with KMP and more

Posted by Murat Yener – Developer Relations Engineer

Following our recent Google I/O announcement recommending Kotlin Multiplatform (KMP) for sharing business logic across mobile, web, server, and desktop platforms, and our move to use KMP in Google Workspace, KotlinConf 2024 was the next moment to share the highlights and connect with the Kotlin community.

Kotlin Multiplatform, developed by JetBrains, allows developers to build cross-platform apps by compiling Kotlin code into platform-native binaries while leveraging the full capabilities of a modern, memory-managed language. This approach has been a long-term investment for the Google Workspace team, enabling them to share the business logic between different platforms.

The Android team has been working to support KMP and recently released an alpha version of Room with KMP support. As of today, Annotations, Collections and DataStore are already in stable with KMP support . We've also commonified Lifecycle, ViewModel and Paging libraries to allow integrations with non-Android platforms.

Keynotes and Technical Sessions

The conference kicked off with a keynote, as part of which, Google’s Jeffrey van Gogh gave an overview of Google’s contributions to the Kotlin ecosystem. As part of this, Jeffrey delved into how Google leverages Kotlin Multiplatform (KMP) to streamline development across its own product portfolio. Jeffrey highlighted the benefits of code sharing and efficiency that KMP brings to Google's projects, aligning with our recent recommendations for Android app development.

Our technical sessions at KotlinConf 2024 span a range of topics:

  • A Tale of Two Languages by John Pampuch offered an engaging comparison of Java and Kotlin's evolution, highlighting their symbiotic relationship and mutual influence.
  • The Android Jetpack team, represented by Elif Bilgin, Yigit Boyar, and Daniel Santiago Rivera, unveiled Enabling Kotlin Multiplatform Success: The Android Jetpack Journey. They provided insights into the current state of KMP in Jetpack, shared updates on KMP-enabled Jetpack libraries, and explored the migration process of a well-established Jetpack library to KMP.
  • Going Fast with Kotlin by Andrei Shikov shared valuable insights gained from optimizing Compose for Android. Andrei highlighted interesting performance nuances in Kotlin and the guardrails the Compose team established to ensure optimal performance.
  • Kotlin Multiplatform in Google Workspace by Jason Parachoniak discussed Google Workspace's ongoing migration from a Java-oriented multiplatform foundation to Kotlin Multiplatform, aligning with Google's broader adoption of KMP. Jason shared lessons learned and the current state of this ambitious transition.
  • Write Your Own Kotlin Lint Checks! by Tor Norbye, Android Studio Engineering Director, empowered developers to extend Android Lint, a static analysis tool used by millions, by creating their own checks. Despite the name, it's not actually Android specific -- it's also used to analyze server Kotlin and Java code inside of Google!

Community Engagement at KotlinConf

We are always looking into ways to be actively engaged with the Kotlin community. If you attended KotlinConf, we hope you got a chance to check out our booth, with opportunities to chat with our engineers, get your questions answered, and learn more about how you can leverage Kotlin and KMP.

Learn more about KMP

In addition, you can view updated docs and a new mobile sample on KMP. These resources should have what you need to start learning KMP and if you have any feedback or come across any issues, please share them through this link.

Looking Ahead

We are excited about the future of Kotlin and are planning to add KMP support to more AndroidX libraries. We are looking forward to seeing how you will adopt and build the next generation of apps using KMP.

Thanks to KotlinConf organizers, speakers, attendees, and the entire Kotlin community for making this event happen and bringing Kotlin enthusiasts together.

Android Support for Kotlin Multiplatform to Share Business Logic Across Mobile, Web, Server, and Desktop Platforms

Posted by Maru Ahues Bouza – Director, Product Management, and Jeffrey van Gogh – Director, Engineering

Traditionally, developers must either write code individually for each platform they want to target, or make a number of compromises in order to reuse code across platforms. Android has been actively supporting Kotlin since 2017, and today we are excited to announce we are supporting Kotlin Multiplatform on Android, which enables sharing code across mobile, web, server, and desktop platforms. This helps increase productivity for developers, and fits great with Android's Kotlin-first approach, resulting in higher quality Android apps. Our focus is to support sharing business logic (the parts that are most agnostic to the user interfaces) because we've seen Android developers get the most value in not having to maintain duplicate copies of this code.

Kotlin Multiplatform (KMP) has been a long-standing investment for the team behind Google Workspace, allowing for flexibility and speed in delivering valuable cross-platform experiences. The Google Workspace team is enthusiastic about KMP's potential as the direction for its multi-platform architecture investment, confident in its ability to meet performance expectations for various workloads.

The initial step in this journey is the rollout of the Google Docs app for Android, iOS, and Web, which leverages KMP for shared business logic, validating its readiness for production use at Google scale. The Google Workspace team is thrilled to continue exploring the possibilities of KMP across its product suite, aiming to enhance productivity and deliver seamless experiences to users on all platforms.

We see a lot of companies successfully leveraging Kotlin Multiplatform for cross-platform development of their apps, learn how they apply different code-sharing strategies here.

Kotlin Multiplatform, developed by JetBrains, provides a novel approach to sharing code across platforms by compiling Kotlin to platform-native binaries. Kotlin is able to provide the full, modern, memory managed language to native platforms enabling native interoperability and incremental adoption. Kotlin on Android, combined with Kotlin Multiplatform on other platforms, provides a great way to increase productivity and quality, without compromising on performance or interoperability.

Architecture overview for Kotlin Multiplatform (KMP)
Kotlin Multiplatform Architecture

Current Status of Support

Many widely-used libraries offer built-in support for Kotlin Multiplatform, streamlining your cross-platform development experience. These libraries work seamlessly together. For example, Ktor simplifies networking tasks by handling REST service consumption, while kotlinx.serialization converts data to formats like JSON, and Okio manages essential file I/O. Additionally, SKIE facilitates the use of modern types and coroutines on iOS, and CocoaPods integration enables the use of iOS-specific dependencies.

We've worked with JetBrains and the Kotlin developer community to add Kotlin Multiplatform support to a number of Jetpack libraries and in some cases provide the iOS platform targets, while in others, JetBrains and the community provide the multiplatform distributions.

Today, the Annotations, Collections, and DataStore libraries all have support for Kotlin Multiplatform in stable versions. We are also adding support to validate binary compatibility for the iOS platform targets, bringing them on a par with the quality standards for Android. In addition to the libraries above, we've also begun working on Kotlin Multiplatform support for Room, Lifecycle, and ViewModels with alpha versions now available. To better understand which classes and functions are available where, the library reference documentation now indicates "common" and platform support.

Indication of Common, Native and Android support in documentation
Indication of Common, Native and Android support in documentation

Android engineers have collaborated with JetBrains on the Kotlin compiler to improve runtime performance in Kotlin/Native (for iOS & native desktop operating systems), showing 18% runtime performance improvements in compiler benchmarks. In addition the Android team contributed to build time performance improvements for the Kotlin Native Compiler of up to 2x speed ups.

The Android Gradle Plugin now has official support for Kotlin Multiplatform, enabling a concise build definition for setting up Android as a platform target for shared code as shown below:

plugins {
    id("org.jetbrains.kotlin.multiplatform")
    id("com.android.library")
}

kotlin {
    androidTarget {
        compilations.all {
            kotlinOptions {
                jvmTarget = "11"
            }
        }
    }  
    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "Shared"
            isStatic = true
        }
    }    
    sourceSets {
        commonMain.dependencies {
            // put your Multiplatform dependencies here
        }
    }
}
KMP Support in the Android Gradle Plugin DSL

As Android Studio is based on the IntelliJ Platform from JetBrains, it inherits support for Kotlin Multiplatform code editing and many other development features. Other Android development tools like Android Lint and Kotlin Symbol Processing (KSP) are also beginning to add more Kotlin Multiplatform support as well.

Google Chrome now has official support for WasmGC which is used by Kotlin Multiplatform's WebAssembly platform target to enable code sharing with the browser in an efficient and performant way.

Latest details on these projects are available on the updated Android Kotlin Multiplatform page.

Future Areas of Work

We've heard from many Android developers and Google engineering teams that they want expanded support for Kotlin Multiplatform so they can more easily share code with other platforms. Android plans to continue collaborating with JetBrains, Google engineering teams, and the community on a variety of projects, including:

    • Expanding and stabilizing Jetpack libraries with Kotlin Multiplatform support
    • Wasm platform target support in Jetpack libraries
    • Kotlin/Native build performance
    • Kotlin/Native debugging
    • Expanding Kotlin Multiplatform support in Android Studio

Learn More and Try It Out

Sharing code with Kotlin Multiplatform between Android and other platforms enables higher developer productivity and quality so we hope you will give it a try! You can use the Kotlin Multiplatform wizard to create a new KMP project. Learn more in the documentation.

Alternatively, explore one of these sample projects showcasing how to use some of the Jetpack libraries with Kotlin Multiplatform:

If there are additional areas you would like Android to work on let us know and also be a part of our vibrant Android Developer community on LinkedIn, Medium, YouTube, and X.

Jetpack Compose compiler moving to the Kotlin repository

Posted by Ben Trengrove - Developer Relations Engineer, Nick Butcher - Product Manager for Jetpack Compose

We are excited to announce that with the upcoming release of Kotlin 2.0, the Jetpack Compose compiler will move to the Kotlin repository. This means that a matching Compose compiler will release alongside each release of Kotlin. You will no longer have to wait for a matching Compose compiler release before upgrading the Kotlin version in your Compose app. The Compose team at Google will continue to be responsible for developing the compiler and will work closely with JetBrains, our co-founders of the Kotlin Foundation. The version of the Compose compiler now always matches the Kotlin version. The compiler version is therefore jumping to 2.0.0.

To simplify the set up of Compose, we are also releasing a new Compose Compiler Gradle plugin which lets you configure the Compose compiler with a type safe API. The Compose Compiler Gradle plugin’s versioning matches Kotlin’s, and it is available from Kotlin 2.0.0.

To migrate to the new plugin, add the Compose Compiler Gradle plugin dependency to the plugins section of your Gradle version catalog:

[versions]
kotlin = "2.0.0"

[plugins]
org-jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

// Add the Compose Compiler Gradle plugin, the version matches the Kotlin plugin
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }

In your project’s root level Gradle file, add the plugin:

plugins {
   // Existing plugins 
   alias(libs.plugins.compose.compiler) apply false
}

Then in modules that use Compose, apply the plugin:

plugins {
   // Existing plugins
   alias(libs.plugins.compose.compiler)
}

The kotlinCompilerExtensionVersion is no longer required to be configured in composeOptions and can be removed.

composeOptions {
   kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get()
}

If required, you can now add a top level section to the same Gradle file to configure options for the Compose compiler.

android { ... }

composeCompiler {
   enableStrongSkippingMode = true
}

You might currently directly referencing the Compose compiler in your build setup, rather than using AGP to apply the compose compiler plugin. If that is the case, note that the maven artifacts will also change:

Old

New

androidx.compose.compiler:compiler

org.jetbrains.kotlin:kotlin-compose-compiler-plugin-embeddable

androidx.compose.compiler:compiler-hosted

org.jetbrains.kotlin:kotlin-compose-compiler-plugin


For an example of this migration, see this pull request.

For more information on migrating to the new Compose compiler artifact, including instructions for non-version catalog setups, see our updated documentation.

KSP2 Preview: Kotlin K2 and Standalone Source Generator

Posted by Ting-Yuan Huang – Software Engineer, and Jiaxiang Chen – Software Engineer

The Kotlin Symbol Processing (KSP) tool provides a high-level API for doing meta-programming in Kotlin. Many tools have been built on KSP, enabling Kotlin code to be generated at compile time. For example, Jetpack Room uses KSP to generate code for accessing the database, based on an interface provided by the developer, like:

@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll(): List<User>
}

KSP provides the API to the Kotlin code so that Room in this case can generate the actual implementation of that interface. While KSP has become a core foundation for meta-programing in Kotlin, its current implementation has some gaps which we are aiming to resolve with a new KSP2 architecture. This blog details those architectural changes and the impact for plugins built on KSP.

In addition, KSP2 has preview support for:

    • The new Kotlin compiler (code-named K2)
    • A new standalone source generator that provides more flexibility and features than the current Kotlin compiler plugin

After getting feedback on the new architecture and continuing to address gaps we will work towards releasing KSP 2.0 where these changes will be the default.

Enabling the KSP2 Preview

The new preview changes can be enabled in KSP 1.0.14 or newer using a flag in gradle.properties:

ksp.useKSP2=true

Note: You might need to enlarge the heap size of the Gradle daemon now that KSP and processors run in the Gradle daemon instead of the Kotlin compiler’s daemon (which has larger default heap size), e.g. org.gradle.jvmargs=-Xmx4096M -XX:MaxMetaspaceSize=1024m

KSP2 and K2

Internally KSP2 uses the Beta Kotlin K2 compiler (which will be the default compiler in Kotlin 2.0). You can use KSP2 before switching your Kotlin compiler to K2 (via the languageVersion setting) but if you want to use K2 for compiling your code, check out: Try the K2 compiler in your Android projects.

Standalone Source Generator

KSP1 is implemented as a Kotlin 1.x compiler plugin. Running KSP requires running the compiler and specifying KSP and its plugin options. In Gradle, KSP’s tasks are customized compilation tasks, which dispatch real work to KotlinCompileDaemon by default. This makes debugging and testing somewhat difficult, because KotlinCompileDaemon runs in its own process, outside of Gradle.

In KSP2, the implementation can be thought of as a library with a main entry point. Build systems and tools can call KSP with this entry point, without setting up the compiler. This makes it very easy to call KSP programmatically and is very useful especially for debugging and testing. With KSP2 you can set breakpoints in KSP processors without having to perform any other / irregular setup tasks to enable debugging.

Everything becomes much easier because KSP2 now controls its lifecycle and can be called as a standalone program or programmatically, like:

val kspConfig = KSPJvmConfig.Builder().apply {
  // All configurations happen here.
}.build()
val exitCode = KotlinSymbolProcessing(kspConfig, listOfProcessors, kspLoggerImpl).execute()

KSP2 API Behavior Changes

With the new implementation, it is also a great opportunity to introduce some refinements in the API behavior so that developers building on KSP will be more productive, have better debuggability and error recovery. For example, when resolving Map<String, NonExistentType>, KSP1 simply returns an error type. In KSP2, Map<String, ErrorType> will be returned instead. Here is a list of the current API behavior changes we plan on making in KSP2:

    1. Resolve implicit type from function call: val error = mutableMapOf<String, NonExistType>()
      KSP1: The whole type will be an error type due to failed type resolution
      KSP2: It will successfully resolve the container type, and for the non-existent type in the type argument, it will correctly report errors on the specific type argument.
    2. Unbounded type parameter
      KSP1: No bounds
      KSP2: An upper bound of Any? is always inserted for consistency
    3. Resolving references to type aliases in function types and annotations
      KSP1: Expanded to the underlying, non-alias type
      KSP2: Not expanded, like uses in other places.
    4. Fully qualified names
      KSP1: Constructors have FQN if the constructor is from source, but not if the constructor is from a library.
      KSP2: Constructors do not have FQN
    5. Type arguments of inner types
      KSP1: Inner types has arguments from outer types
      KSP2: Inner types has no arguments from outer types
    6. Type arguments of star projections
      KSP1: Star projections have type arguments that are expanded to the effective variances according to the declaration sites.
      KSP2: No expansion. Star projections have nulls in their type arguments.
    7. Variance of Java Array
      KSP1: Java Array has a invariant upper bound
      KSP2: Java Array has a covariant upper bound
    8. Enum entries
      KSP1: An enum entry has its own subtype with a supertype of the enum class (incorrect behavior from language point of view)
      KSP2: An enum entry's type is the type of the enclosing enum class
    9. Multi-override scenario

      For example
      interface GrandBaseInterface1 {
          fun foo(): Unit
      }
      
      interface GrandBaseInterface2 {
          fun foo(): Unit
      }
      
      interface BaseInterface1 : GrandBaseInterface1 {
      }
      
      interface BaseInterface2 : GrandBaseInterface2 {
      }
      
      class OverrideOrder1 : BaseInterface1, GrandBaseInterface2 {
          override fun foo() = TODO()
      }
      class OverrideOrder2 : BaseInterface2, GrandBaseInterface1 {
          override fun foo() = TODO()
      }
      

      KSP1:
      Find overridden symbols in BFS order, first super type found on direct super type list that contains overridden symbol is returned For the example, KSP will say OverrideOrder1.foo() overrides GrandBaseInterface2.foo() and OverrideOrder2.foo() overrides GrandBaseInterface1.foo()
      KSP2:
      DFS order, first super type found overridden symbols (with recursive super type look up) in direct super type list is returned.
      For the example, KSP will say OverrideOrder1.foo() overrides GrandBaseInterface1.foo() and OverrideOrder2.foo() overrides GrandBaseInterface2.foo()
    10. Java modifier
      KSP1: Transient/volatile fields are final by default
      KSP2: Transient/volatile fields are open by default
    11. Type annotations
      KSP1: Type annotations on a type argument is only reflected on the type argument symbol
      KSP2: Type annotations on a type argument now present in the resolved type as well
    12. vararg parameters
      KSP1: Considered an Array type
      KSP2: Not considered an Array type
    13. Synthesized members of Enums
      KSP1: values and valueOf are missing if the enum is defined in Kotlin sources
      KSP2: values and valueOf are always present
    14. Synthesized members of data classes
      KSP1: componentN and copy are missing if the data class is defined in Kotlin sources
      KSP2: componentN and copy are always present

New Multiplatform Processing Scheme

When it comes to the processing scheme, i.e. what sources are processed when, the principle of KSP is to be consistent with the build's existing compilation scheme. In other words, what the compiler sees is what processors see, plus the source code that is generated by processors.

What processors see Kotlin compiler see

ClassA.kt, UtilB.kt, InterfaceC.kt ... ClassA.kt, UtilB.kt, InterfaceC.kt ... + GeneratedFromA.kt, ...

In KSP1's current compilation scheme, common / shared source sets are processed and compiled multiple times, with each target. For example, commonMain is processed and compiled 3 times in the following project layout. Being able to process all the sources from dependencies is convenient with one exception: Processors don’t see the sources generated from commonMain when processing jvmMain and jsMain. Everything must be re-processed and that can be inefficient.

Flow diagram illustrating sources generated from jvmMain and jsMain processing to commonMain

tasks

inputs

outputs

kspKotlinCommonMainMetadata

commonMain

generatedCommon

kspKotlinJvm

commonMain, jvmMain

generatedCommonJvm

kspKotlinJs

commonMain, jsMain

generatedCommonJs

compileKotlinCommonMainMetadata

commonaMain, generatedCommon

common.klib

compileKotlinJvm

commonMain, jvmMain, generatedCommonJvm

app.jar

compileKotlinJs

commonMain, jsMain, generatedCommonJs

main.js

In KSP2, we plan to add an experimental mode that tries to align to how source sets are compiled in K2 better. All sources can be processed only once with the available new processing scheme:

tasks

inputs

outputs

Resolvable but not available in 

getAllFiles / 

getSymbolsWithAnnotation

kspKotlinCommonMainMetadata

commonMain

generatedCommon


kspKotlinJvm

jvmMain

generatedJvm

commonMain, generatedCommon

kspKotlinJs

jsMain

generatedJs

commonaMain, generatedCommon

compileKotlinCommonMainMetadata

commonaMain, generatedCommon

common.klib


compileKotlinJvm

commonMain, jvmMain, generatedCommon, generatedJvm

app.jar


compileKotlinJs

commonMain, jsMain, generatedCommon, generatedJs

main.js


Please note that Kotlin 2.0 is still in beta and the compilation model is subject to change. Please let us know how this works for you and give us feedback.

KSP2 Preview Feedback

KSP2 is in preview but there is still more work to be done before a stable release. We hope these new features will ultimately help you be more productive when using KSP! Please provide us with your feedback so we can make these improvements awesome as they progress towards being stable.

Bringing Kotlin to the Web

Posted by Vivek Sekhar, Product Manager

This post describes early experimental work from JetBrains and Google. You can learn more in the session on WebAssembly at Google I/O 2023.

Application developers want to reach as many users on as many platforms as they can. Until now, that goal has meant building an app on each of Android, iOS and the Web, as well as building the backend servers and infrastructure to power them.

Image showing infrastructure of Web, Android, and iOS Apps in relation to backend servers and programming support - JavaScript, Kotlin, and Swift respectively

To reduce effort, some developers use multiplatform languages and frameworks to develop their app's business logic and UI. Bringing these multiplatform apps to the Web has previously meant "compiling" shared application code to a slower JavaScript version that can run in the browser. Instead, developers often rewrite their apps in JavaScript, or simply direct Web users to download their native mobile apps.

The Web community is developing a better alternative: direct Web support for modern languages thanks to a new technology called WebAssembly GC. This new Web feature allows cross-platform code written in supported languages to run with near-native performance inside all major browsers.

We're excited to roll-out experimental support for this new capability on the Web for Kotlin, unlocking new code sharing opportunities with faster performance for Android and Web developers.


Kotlin Multiplatform Development on the Web

Kotlin is a productive and powerful language used in 95% of the top 1,000 Android apps. Developers say they are more productive and produce fewer bugs after switching to Kotlin.

The Kotlin Multiplatform Mobile and Compose Multiplatform frameworks from JetBrains help developers share code between their Android and iOS apps. These frameworks now offer experimental support for Kotlin compilation to WebAssembly. Early experiments indicate Kotlin code runs up to 2x faster on the Web using WebAssembly instead of JavaScript.

Image showing infrastructure of Web, Android, and iOS Apps in relation to backend servers and programming support - JavaScript, Kotlin, and Swift respectively

JetBrains shares more details in the release notes for version 1.18.20 of their K2 compiler, as well as documentation on how you can try Kotlin/Wasm with your app.


Pulling it off

Bringing modern mobile languages like Kotlin to the Web required solving challenging technical problems like multi-language garbage collection and JavaScript interoperability. You can learn more in the session on new WebAssembly languages from this year's Google I/O conference.

This work wouldn't have been possible without an open collaboration between browser vendors, academics, and service providers across the Web as part of the W3C WebAssembly Community Group. In the coming weeks, we'll share technical details about this innovative work on the V8 Blog.


Looking ahead: Web and Native Development

For decades, developers have dreamed of the Web as a kind of "universal runtime," while at the same time acknowledging certain feature or performance gaps relative to native platforms. Developers have long had to switch between working on the Web or their native mobile apps.

However, we want to make it possible for you to work on the Web and your native experiences together, not only to help you reduce effort, but also to help you tap into the Web's unique superpowers.

On the open web, your app is just a click away from new users, who can discover it and share it just as easily as they share a web page, with no app stores getting in the way and no revenue split affecting your profitability.

The productivity of cross-platform development, the performance of native mobile apps and the openness of the web. That's why we love WebAssembly.

We can't wait to see what you build next!


"The productivity of cross-platform development, the performance of native mobile apps, and the openness of the Web."

Kotlin DSL is Now the Default for New Gradle Builds

Posted by James Ward, Product Manager, Kotlin and Boris Farber, Developer Relations Engineer

Android has been Kotlin-first for four years and many Android developers have made the switch resulting in higher productivity and more stable apps. However the default language to define builds has been Groovy (build.gradle), even though a Kotlin (build.gradle.kts) option has existed in Gradle for a number of years.

Today we're excited to announce that we're switching the default language for build scripts to Kotlin! This means that Kotlin is the single default language used for all project code, including UI with Jetpack Compose, and now build scripts! We've been working with the Gradle and JetBrains teams on this improvement, and you can read more in their related announcements: Gradle Blog; JetBrains Blog.

This doesn’t affect existing projects using Groovy, as those will continue working with no plans for deprecation. But if you are creating new projects or modules starting from Android Studio Giraffe, you now get the Kotlin DSL by default. The updated project templates are an easy way to get started with the new Kotlin DSL build scripts. To migrate existing builds, check out the Kotlin DSL migration guide.

While the Kotlin DSL is the default for new projects, large, existing Groovy DSL based projects should wait on migrating while Gradle, JetBrains, and Google work on improving build performance further. This work is ongoing and we will share updates as we make progress. Specifically, script compilation performance is slower than with the Groovy DSL. However, unlike with the Groovy DSL, the Kotlin DSL script compilation results are stored in Gradle local and remote caches so that subsequent builds do not need recompilation.

Having a single language for all code in a project isn't the only benefit to this change, so let's look at some other great things about using the Kotlin DSL for Gradle builds.

  • Kotlin is statically typed so you get quick and accurate code hints while editing Kotlin DSL build scripts:
  • Syntax errors are more accurate, and they’re displayed while editing Kotlin DSL build scripts, instead of when trying to sync the project:
  • Get type and method documentation by pressing Control+Q (Command+B on macOS).If you need more details you can go to the underlying source code by pressing Control+Click (Command+Click):
  • You can mix Groovy DSL build scripts and Kotlin DSL build scripts in one project and migrate incrementally module by module. This enables new modules to use the Kotlin DSL while keeping existing modules on Groovy.

An associated change we are also making to the New Project templates is an experimental option to use Gradle Version Catalogs with Kotlin DSL build scripts.

Version Catalogs give you a centralized, scalable way of defining your project’s dependencies. While using Version Catalogs is optional, they pair great with the Kotlin DSL by providing more type safety in your build definitions.

To learn about migrating to Version Catalogs, check out the migration guide.

The new Kotlin DSL default change is available now in Android Studio Giraffe previews. Please try it and let us know how it goes!

Google at KotlinConf ‘23

Posted by Márton Braun, Developer Relations Engineer

As part of Google’s ongoing commitment to supporting the Kotlin language, we are really excited to be a gold level sponsor for KotlinConf again this year. Grace Kloba shared the story of Google’s investments in Kotlin within the keynote, which is recapped in this post. You’ll also find the list of talks by Google from the event’s schedule below, make sure you catch these on the live stream.

For a summary of all KotlinConf keynote announcements, read the blog post by JetBrains.

Kotlin for Android

Kotlin started gaining popularity in the Android community around 2016. We were also impressed with Kotlin’s concise syntax, modern features, and safety. In 2017, we announced official support for Kotlin on Android, and committed to its future by creating the Kotlin Foundation with JetBrains.

Since then we invested in Kotlin by adding support in Android Studio, teaching the language to developers, and going Kotlin-first with our libraries, documentation, and samples. We also built Kotlin Symbol Processing, an API that enables annotation processors to run up to twice as fast as previous solutions.

Today, Kotlin is the most popular language for Android development. Over 95% of the top 1000 Android apps use Kotlin, and over 50% of professional Android developers use Kotlin as their primary language (compared with 25% choosing the Java programming language).

Among professional Android developers using Kotlin, we saw a 96.9% positive satisfaction rate in our latest annual survey, which is 9-points higher than their Java counterparts.

As our final step in making Kotlin the single language for Android development, we’re excited to announce today that the Gradle Kotlin DSL is becoming the default build language for Android apps, starting in Android Studio Giraffe. Read the blog post to learn more.

Jetpack Compose

Since going Kotlin-first, all new Jetpack libraries are written in Kotlin. Jetpack Compose, our modern toolkit for building Android apps, is Kotlin-only. It makes extensive use of Kotlin’s language features, and its implementation is made possible by Kotlin’s rich compiler API, which allows us to generate state management logic for you.

Jetpack Compose is changing the way developers build apps. The team from Clue shared with us that their development speed increased up to 3x after rewriting their app in Compose. Over 23% of the top 1000 Android apps ship with Compose, more than double year over year.

There are many resources available to learn Compose. For existing Android developers looking to expand their knowledge, we’ve published the Jetpack Compose for Android Developers course. For beginners to programming, we recommend taking the Android Basics with Compose course to learn Kotlin, Android, and Compose.

Kotlin at Google

Kotlin became generally available for Android development within Google in 2019. Since then, most of our Android apps are being built with Kotlin. As an example of the benefits, when the Google Home team migrated to Kotlin they saw a 33% decrease in NullPointerExceptions, which greatly improved the end user experience.

However, Google’s interest in Kotlin does not stop at Android apps. More than 45% of our engineers who write Kotlin use it for server development. We have over 15 million lines of Kotlin code in Google’s source control system, and this has been doubling year over year.

To support this, we have a dedicated team building tools to integrate Kotlin into Google’s ecosystem. You can catch the Adopting Kotlin at Google scale session for more details.

We’re looking forward to the new compiler in Kotlin 2.0, which will be a major improvement for developer productivity. We have a dedicated team working with JetBrains on the compiler, and we’re working to incorporate it into our tooling, including Android Studio, KSP, and the Compose compiler. We’re also leveraging our large internal codebase of Kotlin code to verify the compatibility of the new compiler.

Multiplatform

Looking forward, we are experimenting with Kotlin Multiplatform. This includes the Google Workspace team, who have a prototype with the business logic of Google Docs running on iOS using Kotlin Multiplatform and Kotlin/Native. Check out the Kotlin Multiplatform in Google Workspace lightning talk to learn more.

As part of our explorations into Kotlin Multiplatform, we’ve also made contributions that will benefit the community:

  • We’ve ported a set of Jetpack libraries to multiplatform. This allows you to use tools and APIs you know and love from Android and apply them to multiplatform. 
  • We’ve contributed to the Kotlin/Native toolchain, improving its performance. 
  • We’ve been helping out with the Gradle plugin for Kotlin Multiplatform, to give you more control over each target platform while still sharing as much code as possible.

Kotlin Foundation

As a founding member of the Kotlin Foundation, we’re excited about the Foundation’s expansions announced at KotlinConf:

  • Inviting more companies to collaborate on the development and promotion of Kotlin through a membership program
  • Offering funding for individual authors of actively maintained, open source Kotlin Multiplatform libraries.

With these steps, we continue to foster a healthy ecosystem for the language, and ensure its future advancement.

Catch us at KotlinConf

We look forward to sharing more in our sessions at KotlinConf, which you can tune in to on the live stream. If you’re attending in person, you can also visit us at our booth to have a chat about Kotlin.

April 13 schedule

Adopting Kotlin at Google scale
Jeffrey van Gogh, John Pampuch

Spring + Kotlin = Modern + Reactive + Productive
Josh Long, James Ward

Kotlin Multiplatform in Google Workspace
Jason Parachoniak

Kotlin Multiplatform Conversions at Android Jetpack Scale
Dustin Lam, James Ward

Untangling Coroutine Testing
Márton Braun

Adventures building a Kotlin Multiplatform Benchmarking Library
Rahul Ravikumar

April 14 schedule

Tracing coroutines in the JVM
Tyson Henning

Preventing Data Races in Async Coroutines
Kevin Bierhoff

Avoiding common coroutines mistakes in Compose
Márton Braun

*Java is a trademark or registered trademark of Oracle and/or its affiliates.