<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Florina Muntenescu on Medium]]></title>
        <description><![CDATA[Stories by Florina Muntenescu on Medium]]></description>
        <link>https://medium.com/@florina.muntenescu?source=rss-d5885adb1ddf------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*z2H2HkOuv5bAOuIvUUN-5w.jpeg</url>
            <title>Stories by Florina Muntenescu on Medium</title>
            <link>https://medium.com/@florina.muntenescu?source=rss-d5885adb1ddf------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 31 May 2026 18:17:10 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@florina.muntenescu/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Room auto-migrations]]></title>
            <link>https://medium.com/androiddevelopers/room-auto-migrations-d5370b0ca6eb?source=rss-d5885adb1ddf------2</link>
            <guid isPermaLink="false">https://medium.com/p/d5370b0ca6eb</guid>
            <category><![CDATA[androiddev]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[room]]></category>
            <category><![CDATA[android-app-development]]></category>
            <dc:creator><![CDATA[Florina Muntenescu]]></dc:creator>
            <pubDate>Wed, 21 Apr 2021 19:00:31 GMT</pubDate>
            <atom:updated>2021-04-21T19:00:31.298Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4tGVzCBFAiGJ1gv_NLia_Q.png" /></figure><p><em>Easily move your tables between rooms</em></p><p>Implementing database migrations with Room just became easier, with the help of auto-migrations, introduced in version 2.4.0-alpha01. Until now, whenever your database schema changes you had to implement a Migration class and tell Room what exactly had changed. In most cases, this involved writing and executing complex SQL queries.</p><p>Now with the auto-migration feature, you indicate from which version to which version you want to migrate. Room can automatically generate migrations for simple cases like column addition, removal or new tables. For more ambiguous scenarios, Room will need some help. You’ll be able to provide concrete specifications — like a column or a table renamed or deleted — based on this, Room will generate and run the migration for you. Let’s check out some examples and see how this looks!</p><h3>Putting the auto in auto-migrations</h3><p>Let’s say that we’re adding a new column to a table, going from version 1 to version 2 of our database. We’ll have to update the @Database annotation by incrementing the version number and adding an auto-migration from version 1 to 2:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4a04cb5fb4e5ad28a06e698769823eb2/href">https://medium.com/media/4a04cb5fb4e5ad28a06e698769823eb2/href</a></iframe><p>Whenever your database version changes again, just update the list of auto-migrations adding the new one:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/743b6771145d6143e99740376f75ef79/href">https://medium.com/media/743b6771145d6143e99740376f75ef79/href</a></iframe><p>For entities declared in @Database schema changes like adding a new column or table, updating the primary key, foreign key or indices or changing the default value of a column and more are automatically detected by Room and don’t require any other input.</p><p>⚠️Note: Under the hood, Room auto-migrations rely on the generated database schema, so make sure that the exportSchema option in @Database is true while using autoMigrations. Otherwise it leads to an error: Cannot create auto-migrations when export schema is OFF.</p><h3>When auto-migrations need a little help</h3><p>Room auto-migrations can’t detect all the possible changes performed on the database, so sometimes they need some help. A common example is that Room can’t detect whether a table or a column was renamed or deleted. When this happens, Room will throw a compile time error asking you to implement a AutoMigrationSpec. This class allows you to specify the type of change you made. Implement an AutoMigrationSpec and annotate it with one or more of:</p><ul><li>@DeleteTable(tableName)</li><li>@RenameTable(fromTableName, toTableName)</li><li>@DeleteColumn(tableName, columnName)</li><li>@RenameColumn(tableName, fromColumnName, toColumnName)</li></ul><p>For example, let’s say that we’re renaming the Doggos table to GoodDoggos. Room can’t detect whether this is a completely new table and we deleted the Doggos table, or the table was renamed and all of the values need to be kept.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bffea571ff9032faf794c14bc0b7429a/href">https://medium.com/media/bffea571ff9032faf794c14bc0b7429a/href</a></iframe><h3>Migrations vs Auto-migrations</h3><h4>When to use Migrations</h4><p>To <a href="https://developer.android.com/training/data-storage/room/migrating-db-versions">manually handle migrations</a>, Room has offered the <a href="https://developer.android.com/reference/kotlin/androidx/room/migration/Migration">Migration</a> class since version 1.0. Whenever you have complex database schema changes to make, you’ll have to use this class. For example, let’s say that we’ve decided to split a table into 2 different tables. Room can’t detect how this split has been performed, and can’t automatically detect which data to move. So this is when you’ll have to implement a Migration class and add it to the databaseBuilder() via addMigrations() method:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/21597e1c54b2676d71cf871d9ea9e271/href">https://medium.com/media/21597e1c54b2676d71cf871d9ea9e271/href</a></iframe><h3>Combining migrations and auto-migrations</h3><p>Room allows combining migrations with auto-migrations. For example, migrating from version 1 to version 2 may be done using Migration, version 2 to version 3 using auto-migration etc. If you define a Migration and an auto-migration for the same version, then the Migration will be run.</p><p>Under the hood an auto-migration constructs a Migration class, so the same migration logic described in detail <a href="https://medium.com/androiddevelopers/understanding-migrations-with-room-f01e04b07929">here</a> still applies. TL;DR: When the database is first accessed, Room checks whether the current database version is different from the one in @Database. If yes, Room looks for migration paths going from one to the other. Migrations are then run consecutively.</p><h3>Testing auto-migrations</h3><p>To test auto-migrations, you can use the MigrationTestHelper test rule and call helper.runMigrationsAndValidate(), in the same way as when using the Migration class. Read more about testing migrations in our <a href="https://developer.android.com/training/data-storage/room/migrating-db-versions#single-migration-test">documentation</a>.</p><h3>Conclusion</h3><p>The auto-migration feature allows you to easily handle database schema changes by using the autoMigration parameter in @Database. While a lot of the basic cases can be handled by Room, for table / column delete or rename you’ll have to implement a AutoMigrationSpec. For all other cases, continue using Migrations.</p><p>This feature is currently in <strong>alpha</strong>. Help us make it better by providing feedback on our <a href="https://issuetracker.google.com/issues/new?component=413107&amp;template=1096568">issue tracker</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d5370b0ca6eb" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/room-auto-migrations-d5370b0ca6eb">Room auto-migrations</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[WorkManager — Kotlin APIs]]></title>
            <link>https://medium.com/androiddevelopers/workmanager-kotlin-apis-a0fb9dfbfeb6?source=rss-d5885adb1ddf------2</link>
            <guid isPermaLink="false">https://medium.com/p/a0fb9dfbfeb6</guid>
            <category><![CDATA[workmanager]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[kotlin]]></category>
            <dc:creator><![CDATA[Florina Muntenescu]]></dc:creator>
            <pubDate>Thu, 07 Jan 2021 17:58:35 GMT</pubDate>
            <atom:updated>2021-01-07T17:58:35.319Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*D2aKnfPkmj71LZWVghXjcQ.png" /></figure><h3>WorkManager — Kotlin APIs</h3><p><a href="https://developer.android.com/topic/libraries/architecture/workmanager">WorkManager</a> provides a set of APIs that makes it easy to schedule asynchronous tasks for immediate or deferred execution that are expected to run even if the app is closed or the device restarts. For Kotlin users, WorkManager provides first-class support for coroutines. In this post I’ll show you the basics of WorkManager with coroutines by building on the <a href="https://developer.android.com/codelabs/android-workmanager#0">WorkManager codelab</a>. So let’s get started!</p><h3>The basics of WorkManager</h3><p>The WorkManager library is the recommended choice for any task that should continue to run, even if the user navigates away from the particular screen, the user puts the application in background or the device restarts. Common tasks could be:</p><ul><li>Uploading logs or reporting data</li><li>Applying filters to images and saving the image</li><li>Periodically syncing local data with the network</li></ul><p>If your immediate task can end when the user leaves a certain scope such as a screen, we recommend you use Kotlin Coroutines directly.</p><p>The WorkManager codelab blurs images and saves the result on disk. Let’s see what was needed to achieve this.</p><p>We added the work-runtime-ktx dependency.</p><pre>implementation &quot;androidx.work:work-runtime-ktx:$work_version&quot;</pre><p>We started by implementing our own Worker class. This is where we put the code for the actual work you want to perform in the background. You’ll extend the Worker class and override the doWork() method. As this is the most important class we’ll go over it in detail later. Here’s what the initial implementation looks like.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2d56c8fdda1bfecd5a975b1533228505/href">https://medium.com/media/2d56c8fdda1bfecd5a975b1533228505/href</a></iframe><p>Then, we build our work request, in our case, we want to perform the work only once so we use a <a href="https://developer.android.com/reference/androidx/work/OneTimeWorkRequest.Builder">OneTimeWorkRequest.Builder</a>. As input, we set the Uri of the image we want to blur.</p><p>Kotlin tip: to create the input data, we can use the <a href="https://developer.android.com/reference/kotlin/androidx/work/package-summary#workdataof">workDataOf</a> function that creates the data builder, puts the key-value pair and creates the data for us.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/df9de57999a2463ec1c25fa494963073/href">https://medium.com/media/df9de57999a2463ec1c25fa494963073/href</a></iframe><p>To schedule the work and make it run, we use the WorkManager class. We can provide tasks to be done and constraints to these tasks.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/37354c4b8fabf77347dbd10acd1c28f6/href">https://medium.com/media/37354c4b8fabf77347dbd10acd1c28f6/href</a></iframe><h3>Make the Worker do the work</h3><p>When you use a <a href="https://developer.android.com/reference/androidx/work/Worker?hl=en">Worker</a>, WorkManager automatically calls Worker.doWork() on a background thread. The Result returned from doWork() informs the WorkManager service whether the work succeeded and, in the case of failure, whether or not the work should be retried.</p><p>Worker.doWork() is a synchronous call — you are expected to do the entirety of your background work in a blocking fashion and finish it by the time the method exits. If you call an asynchronous API in doWork() and return a Result, your callback may not operate properly.</p><h3>But what if we want to do asynchronous work?</h3><p>Let’s complicate our example and say that we want to save the Uris of all the files that have been blurred in the database.</p><p>For this I created:</p><ul><li>A simple BlurredImage entity</li><li>A dao class to insert and get images</li><li>The database</li></ul><p>Check out the implementation <a href="https://github.com/googlecodelabs/android-workmanager/pull/213">here</a>.</p><p>If you have to do asynchronous work, like saving data in the database or doing network requests, in Kotlin, we recommend using a <a href="https://developer.android.com/reference/kotlin/androidx/work/CoroutineWorker">CoroutineWorker</a>.</p><p>A CoroutineWorker allows us to do asynchronous work, using Kotlin coroutines.</p><p>The doWork() method is a suspend method. So this means that we can easily call our suspending dao here.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/518de3fb41da545ea3ff38ae3089ef32/href">https://medium.com/media/518de3fb41da545ea3ff38ae3089ef32/href</a></iframe><p>By default doWork() uses Dispatchers.Default. You can override this with the Dispatcher that you need. In our case, we don’t need to do this because Room already moves the insert work on a different Dispatcher. Check out the Room Kotlin APIs post for more details.</p><p>Start using CoroutineWorker to perform asynchronous work that needs to complete even if the user closes your app.</p><p>If you want to learn more about WorkManager, stay tuned for a future series dedicated to covering it in depth. Until then, check out our codelabs and documentation:</p><ul><li><a href="https://developer.android.com/topic/libraries/architecture/workmanager/">WorkManager documentation</a></li><li><a href="https://developer.android.com/codelabs/android-workmanager#0">Working with WorkManager</a> codelab</li><li><a href="https://developer.android.com/codelabs/android-adv-workmanager#0">Advanced WorkManager</a> codelab</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a0fb9dfbfeb6" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/workmanager-kotlin-apis-a0fb9dfbfeb6">WorkManager — Kotlin APIs</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using and testing Room Kotlin APIs]]></title>
            <link>https://medium.com/androiddevelopers/using-and-testing-room-kotlin-apis-4d69438f9334?source=rss-d5885adb1ddf------2</link>
            <guid isPermaLink="false">https://medium.com/p/4d69438f9334</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[room]]></category>
            <category><![CDATA[kotlin]]></category>
            <dc:creator><![CDATA[Florina Muntenescu]]></dc:creator>
            <pubDate>Tue, 05 Jan 2021 17:46:20 GMT</pubDate>
            <atom:updated>2021-01-05T17:46:20.647Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*D2aKnfPkmj71LZWVghXjcQ.png" /></figure><p><a href="https://developer.android.com/training/data-storage/room">Room</a> is a wrapper over SQLite and it makes working with databases on Android so much easier and is by far my favorite Jetpack library. In this post I want to tell you how to use and test Room Kotlin APIs and while we do that, I’ll also share how things work under the hood.</p><p>We’re going to use the <a href="https://developer.android.com/codelabs/android-room-with-a-view-kotlin#0">Room with a view codelab</a> as a basis. Here we’re building a list of words that are saved in the database and displayed on the screen. The user can also add words to the list.</p><h3>Define the database table</h3><p>In our database we have only one table: the one containing words. The Word class represents an entry in the table and it needs to be annotated with @Entity. We use @PrimaryKey to define the primary key for the table. Based on this, Room will generate a SQLite table, with the same name as the class name. Each member of the class becomes a different column in the table. The column name and type is given by the name and type of each field. You can change it by using the @ColumnInfo annotation.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/02ecbdc385e7f2b96f6bf84774b2b72e/href">https://medium.com/media/02ecbdc385e7f2b96f6bf84774b2b72e/href</a></iframe><p>We recommend you always use the @ColumnInfo annotation as it gives you more flexibility to rename the members without having to change the database column names. Changing the column names leads to a change in the database schema and therefore you need to implement a migration.</p><h3>Access the data in the table</h3><p>To access the data in the table we create a data access object (DAO). This will be an interface called WordDao, annotated with @Dao. We want to insert, delete and get data from the table so these will be defined as abstract methods in the DAO. Working with the database is a time consuming I/O operation, so this needs to be done on the background thread. We’ll use Room integration with Kotlin coroutines and Flow to achieve this.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/43a87115b7c45b92295c3c762d705b43/href">https://medium.com/media/43a87115b7c45b92295c3c762d705b43/href</a></iframe><p>We’ve covered the basics of working with coroutines in <a href="https://youtu.be/bM7PVVL_5GM?list=PLWz5rJ2EKKc_T0fSZc9obnmnWcjvmJdw_">this Kotlin vocabulary video</a>. Check out <a href="https://youtu.be/emk9_tVVLcc?list=PLWz5rJ2EKKc_T0fSZc9obnmnWcjvmJdw_">this video</a> for information about Flow.</p><h3>Insert data</h3><p>To insert data create an abstract suspend function that gets as parameter the Word to be inserted and annotate it with @Insert. Room will generate all the work that needs to be done to insert the data in the database and, because we made the function suspend, Room moves all the work to be done to a background thread. Thus, this suspend function is main-safe: safe to be called from the main thread.</p><pre>@Insert<br>suspend fun insert(word: Word)</pre><p>Under the hood Room generates the implementation of the Dao. Here’s how the implementation of our insert method looks like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/291e1d1a263ad0872033f7676a97e24b/href">https://medium.com/media/291e1d1a263ad0872033f7676a97e24b/href</a></iframe><p>CoroutinesRoom.execute() function is called, with 3 parameters: the database, a flag to indicate whether we’re in a transaction and a Callable object. Callable.call() contains the code that handles the database insertion.</p><p>If we check the CoroutinesRoom.execute() <a href="https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:room/ktx/src/main/java/androidx/room/CoroutinesRoom.kt;l=47?q=CoroutinesRoom">implementation</a>, we see that Room moves callable.call() to a different CoroutineContext. This is derived from the executors you provide when building your database or by default will use the Architecture Components IO Executor.</p><h3>Query data</h3><p>To query the table, we’ll create an abstract function and annotate it with @Query, passing in the SQL query needed to get the data we want: all words from the word table, ordered alphabetically.</p><p>We want to be notified whenever the data in the database changes, so we return a Flow&lt;List&lt;Word&gt;&gt;. Because of the return type, Room runs the query on the background thread.</p><pre>@Query(“SELECT * FROM word_table ORDER BY word ASC”)<br>fun getAlphabetizedWords(): Flow&lt;List&lt;Word&gt;&gt;</pre><p>Under the hood, Room generates the getAlphabetizedWords() for us:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5930d5e9476e800463886efaa75adefc/href">https://medium.com/media/5930d5e9476e800463886efaa75adefc/href</a></iframe><p>We see a CoroutinesRoom.createFlow() call, with 4 parameters: the database, a flag indicating whether we’re in a transaction, the list of tables that should be observed for changes (in our case just word_table) and a Callback. Callback.call() contains the implementation of the query to be triggered.</p><p>If we check the CoroutinesRoom.createFlow() <a href="https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:room/ktx/src/main/java/androidx/room/CoroutinesRoom.kt;l=99?q=CoroutinesRoom">implementation</a>, we see that here as well the query call is moved to a different CoroutineContext. Like with the insert call, this dispatcher is derived from the executors you provide when building your Database or by default will use the Architecture Components IO executor.</p><h3>Create the database</h3><p>We’ve defined the data to be stored in the database and how to access it, now it’s time to define the database itself. For this, we create an abstract class that extends RoomDatabase, annotate it with @Database, passing in Word as the entity to be stored, and 1 as database version.</p><p>We’ll define an abstract method that returns the WordDao. Everything is abstract because Room is the one that generates the implementation for us. Like this, there’s a lot of logic that we no longer need to implement.</p><p>The only step left is to build the database. We want to make sure we don’t have multiple database instances open at the same time, and we need the application context to initialise the database. So one way to handle this is to define a RoomDatabase instance in the companion object of our class, and a getDatabase function that builds the database. If we want Room queries to be executed on a different Executor than the IO Executor created by Room, we can pass it in the builder by calling <a href="https://developer.android.com/reference/androidx/room/RoomDatabase.Builder#setQueryExecutor(java.util.concurrent.Executor)">setQueryExecutor()</a>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/29ec8cf349e26f757a6cbeb2d62dc38c/href">https://medium.com/media/29ec8cf349e26f757a6cbeb2d62dc38c/href</a></iframe><h3>Testing the Dao</h3><p>To test the Dao we need to implement an AndroidJUnit test as Room creates an SQLite database on the device.</p><p>When implementing the Dao test, before each test is run, we create the database. After each test is run, we close the database. As we don’t need to save the data on the device, when creating the database, we can use an in-memory one. As this is a test, we can allow queries to be run on the main thread.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b8dda2fa6a310c894c8b6c1cbdf5537e/href">https://medium.com/media/b8dda2fa6a310c894c8b6c1cbdf5537e/href</a></iframe><p>To test if a word is inserted successfully, we’ll create a word, insert it, get the first word from the list of alphabetised words and ensure it’s the same as the word we created. As we’re calling suspend functions, we’ll run the test in a runBlocking block. Since this is a test, we don’t mind if the test blocks the test thread.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a6c2344b6559f4179ea086c2e4d0ee2f/href">https://medium.com/media/a6c2344b6559f4179ea086c2e4d0ee2f/href</a></iframe><p>Room offers a lot more functionality and flexibility than what we’ve covered — you can define how Room should handle database conflicts, you can store types that otherwise, natively with SQLite can’t be stored, <a href="https://medium.com/androiddevelopers/room-time-2b4cf9672b98">like </a><a href="https://medium.com/androiddevelopers/room-time-2b4cf9672b98">Date</a>, by creating TypeConverters, you can implement complex queries, using JOIN and other SQL functionality, <a href="https://developer.android.com/training/data-storage/room/creating-views">create database views</a>, pre-populate your database or trigger certain database actions whenever the database is created or opened.</p><p>Check out our <a href="https://developer.android.com/training/data-storage/room">Room documentation</a> for more information and the <a href="https://developer.android.com/codelabs/android-room-with-a-view-kotlin">Room with a view</a> codelab for hands-on learning.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4d69438f9334" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/using-and-testing-room-kotlin-apis-4d69438f9334">Using and testing Room Kotlin APIs</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[More productivity with Kotlin]]></title>
            <link>https://medium.com/androiddevelopers/more-productivity-with-kotlin-8ce7b7718f39?source=rss-d5885adb1ddf------2</link>
            <guid isPermaLink="false">https://medium.com/p/8ce7b7718f39</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[buildbetterapps]]></category>
            <dc:creator><![CDATA[Florina Muntenescu]]></dc:creator>
            <pubDate>Fri, 18 Dec 2020 18:01:33 GMT</pubDate>
            <atom:updated>2020-12-18T18:01:33.372Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*m5y6ZmDIkg-9Z8bGbgfCVQ.png" /></figure><p>Kotlin is known for its conciseness and this, in practice, translates into higher productivity. Even more, 67% of professional Android developers who use Kotlin say it has increased their productivity. In this blog post, I’ll share a couple of ways Kotlin has increased the productivity of our partners’ engineers and look at the Kotlin features that help with this.</p><blockquote>67% of professional Android developers surveyed who use Kotlin say it has increased their productivity</blockquote><h3>Conciseness, simplicity and productivity</h3><p>Kotlin’s conciseness has effects on all stages of development:</p><ul><li><strong>As an author</strong> it means that you can focus on the problem you need to solve, rather than on the syntax. Less code means less to test and less to debug and less chances of creating bugs.</li><li><strong>As a reviewer or maintainer</strong> it means that you have less code to read, making it easier to understand what the code does, and therefore easier to review or maintain.</li></ul><p>One example of this comes from the team at Flipkart:</p><blockquote>“During an internal survey, 50% of developers mentioned that they’d provide smaller estimates [to complete a feature] if the module was written in Kotlin.” (Flipkart)</blockquote><h3>Kotlin features and productivity</h3><p>The majority of Kotlin features result in higher productivity, both due to conciseness and higher readability so let’s look at some of the most used ones.</p><h3>Default arguments and builders</h3><p>In the Java programming language, when some of the parameters of your constructor are optional, you usually take one of two roads:</p><ul><li>Add multiple constructors</li><li>Apply the <a href="https://en.wikipedia.org/wiki/Builder_pattern">builder pattern</a></li></ul><p>With Kotlin neither of these is necessary due to the use of default arguments. Default arguments allow you to implement function overloads without the extra boilerplate.</p><blockquote>When the Cash App team started using Kotlin, they were able to eliminate many builders, and cut down on the amount of code they needed to write. In some cases, they saved 25% in code size.</blockquote><p>For example, here’s how the implementation of a Task object, where the name of the task is the only mandatory parameter would look like when using a builder or when using default arguments:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c340bd451ee11f4b1f719b81b02bd504/href">https://medium.com/media/c340bd451ee11f4b1f719b81b02bd504/href</a></iframe><p>Find out more about default arguments from our <a href="https://medium.com/androiddevelopers/dont-argue-with-default-arguments-2245b2c752c">Kotlin Vocabulary blog post</a>.</p><h3>Objects and singletons</h3><p>The <a href="https://en.wikipedia.org/wiki/Singleton_pattern">singleton pattern</a> is probably one of the most used patterns in software development — it helps you create a single instance of an object which can be accessed and shared by other objects.</p><p>To create a singleton you would need to control how the object is created, allowing only one instance of it and making sure that the code is thread safe. In Kotlin, you only need one keyword: object.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9a6061b674cdbdbc4c82b2bb35ca0046/href">https://medium.com/media/9a6061b674cdbdbc4c82b2bb35ca0046/href</a></iframe><h3>Operators, string templates and more</h3><p>The conciseness and simplicity of the Kotlin language is shown in features like operator overloading, destructuring or string templates — the resulting code gets so easy to read.</p><p>For example, let’s say that we have a library with books. To remove a book from the library, and then work only with the title and print it, the code we write can look like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/561702e742310540b5c216bb72918d58/href">https://medium.com/media/561702e742310540b5c216bb72918d58/href</a></iframe><p>Here are the Kotlin features used:</p><ul><li>-= is implemented using <a href="https://kotlinlang.org/docs/reference/operator-overloading.html">operator overloading</a></li><li>val (title, author) = book uses <a href="https://kotlinlang.org/docs/reference/multi-declarations.html">destructuring</a></li><li>println(“Borrowed $title”) uses <a href="https://kotlinlang.org/docs/reference/multi-declarations.html">string templates</a></li></ul><h3>Conclusion</h3><p>Kotlin makes it easy to read and write code. Patterns like <a href="https://medium.com/androiddevelopers/the-one-and-only-object-5dfd2cf7ab9b?source=false---------0">singleton</a> or <a href="https://medium.com/androiddevelopers/delegating-delegates-to-kotlin-ee0a0b21c52b">delegation</a> are part of the language, removing the need to write a lot of code that can lead to bugs being introduced and a higher maintenance burden. Features like <a href="https://kotlinlang.org/docs/reference/multi-declarations.html">string templates</a>, <a href="https://kotlinlang.org/docs/reference/lambdas.html#lambda-expressions-and-anonymous-functions">lambda expressions</a>, <a href="https://kotlinlang.org/docs/reference/functions.html#extension-functions">extension functions</a>, <a href="https://medium.com/androiddevelopers/code-expressivity-with-operator-overloading-ada22a0ca633">operator overloading</a> and more, make the code more concise and simple. Less code to write leads to less code to read, less code to maintain, fewer errors and higher productivity.</p><p>Read more about how you can <a href="http://d.android.com/kotlin/build-better-apps?utm_source=medium&amp;utm_medium=blog&amp;utm_campaign=bbamedium2">Build Better Apps with Kotlin</a>, and see how developers have benefited from Kotlin by reading our <a href="https://developer.android.com/kotlin/stories">case studies</a>. To make your first steps with<a href="http://d.android.com/kotlin"> Kotlin</a>, one of the most <a href="https://insights.stackoverflow.com/survey/2020">loved languages in the world</a>, check out our <a href="https://developer.android.com/kotlin/first">Getting started page</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8ce7b7718f39" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/more-productivity-with-kotlin-8ce7b7718f39">More productivity with Kotlin</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using KTX libraries]]></title>
            <link>https://medium.com/androiddevelopers/using-ktx-libraries-da1dc81c6ecf?source=rss-d5885adb1ddf------2</link>
            <guid isPermaLink="false">https://medium.com/p/da1dc81c6ecf</guid>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[mad-skills]]></category>
            <dc:creator><![CDATA[Florina Muntenescu]]></dc:creator>
            <pubDate>Tue, 15 Dec 2020 20:01:28 GMT</pubDate>
            <atom:updated>2020-12-17T11:02:06.132Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*D2aKnfPkmj71LZWVghXjcQ.png" /></figure><p>When using Android Java APIs in Kotlin, you quickly realise that you’re missing out on some of the Kotlin features that make coding so much easier and pleasant. Instead of writing your own wrappers and extension functions for these APIs, take a look at the Jetpack KTX libraries. Currently, more than 20 libraries have a KTX version, creating sweet idiomatic versions of Java APIs, ranging from Android platform APIs to ViewModels, SQLite and even Play Core. In this post we’ll look at some of the APIs available and peek under the hood to see how they were made.</p><p>If you prefer watching a video to reading a blog post check it out here:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FnKzvYBMdm54%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DnKzvYBMdm54&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FnKzvYBMdm54%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/eaf37fa5abc6e4a3b232782b9c527c13/href">https://medium.com/media/eaf37fa5abc6e4a3b232782b9c527c13/href</a></iframe><h3>Discoverability</h3><p>As a best practice, to ease the discoverability of ktx functionality, always import the -ktx artifact when available. As the -ktx artifact depends transitively on the non-ktx version, you don’t need to include the other artifact. For example, for viewmodel you get 2 artifacts: viewmodel and viewmodel-ktx. The -ktx artifact will contain the Kotlin extensions:</p><pre>// Java language implementation<br>implementation &quot;androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version&quot;</pre><pre>// Kotlin implementation<br>implementation &quot;androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version&quot;</pre><h4>Always import the -ktx artifact</h4><p>For extensions on the Android platform APIs, import the core-ktx artifact.</p><pre>implementation &quot;androidx.core:core-ktx:$corektx_version&quot;</pre><p>The majority of ktx functionality is implemented as <a href="https://medium.com/androiddevelopers/extend-your-code-readability-with-kotlin-extensions-542bf702aa36">extension functions</a> so you’ll be able to easily find them by using auto-complete in Android Studio.</p><p>Other functionality, like the destructuring and operator overloading available on classes like <a href="https://developer.android.com/kotlin/ktx/extensions-list#for_androidgraphicscolor">Color</a> can be discovered by checking out the list of <a href="https://developer.android.com/kotlin/ktx/extensions-list#androidxactivity">KTX extensions</a>.</p><h3>Platform APIs — core-ktx</h3><p>core-ktx provides idiomatic Kotlin functionality for APIs coming from the Android platform.</p><p>For example, if you’re working with SharedPreferences, when you want to update a value, instead of executing 3 different calls, you can just do one:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ec4c1c62b4c8e73698b86ea173444ef7/href">https://medium.com/media/ec4c1c62b4c8e73698b86ea173444ef7/href</a></iframe><p>Under the hood, <a href="https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:core/core-ktx/src/main/java/androidx/core/content/SharedPreferences.kt;l=39">the ktx edit method</a> calls the same functionality, providing a good commit default option: apply(). apply(), unlike commit(), commits the changes on disk asynchronously:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d1e18447bb62de3b2a8fbeae452ce89b/href">https://medium.com/media/d1e18447bb62de3b2a8fbeae452ce89b/href</a></iframe><p>In core-ktx you’ll also find an easier way of handling frequently used platform listeners. For example, if you want to trigger an action when text was changed in an EditText, you’d have to implement all the methods of the TextWatcher, even if you’re only interested in onTextChanged(). core-ktx creates the corresponding TextWatcher methods: <a href="https://developer.android.com/reference/kotlin/androidx/core/widget/package-summary#doontextchanged">doOnTextChanged</a>, <a href="https://developer.android.com/reference/kotlin/androidx/core/widget/package-summary#doaftertextchanged">doAfterTextChanged</a> and <a href="https://developer.android.com/reference/kotlin/androidx/core/widget/package-summary#dobeforetextchanged">doBeforeTextChanged</a>, but in your Kotlin code, you just use the one you need:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/00fcb6323f3853906f999c71bf54d1a3/href">https://medium.com/media/00fcb6323f3853906f999c71bf54d1a3/href</a></iframe><p>This brings several benefits: your code becomes easier to read, as it’s more concise and you get better naming and nullability annotations.</p><p>You’ll find similar listener APIs for <a href="https://developer.android.com/reference/kotlin/androidx/core/animation/package-summary#(android.animation.Animator).addListener(kotlin.Function1,%20kotlin.Function1,%20kotlin.Function1,%20kotlin.Function1)">AnimatorListener</a> and <a href="https://developer.android.com/reference/kotlin/androidx/core/transition/package-summary#(android.transition.Transition).addListener(kotlin.Function1,%20kotlin.Function1,%20kotlin.Function1,%20kotlin.Function1,%20kotlin.Function1)">TransitionListener</a>.</p><p>Under the hood, <a href="https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:core/core-ktx/src/main/java/androidx/core/widget/TextView.kt;l=42?q=doOnTextChanged">doOnTextChanged</a> is implemented as an extension function on TextView — the class that also has the addTextChangedListener method. doOnTextChanged creates <a href="https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:core/core-ktx/src/main/java/androidx/core/widget/TextView.kt;l=65">empty implementations</a> for the other functions of the TextWatcher.</p><h3>Jetpack APIs</h3><p>The majority of extensions available are for Jetpack APIs. Here I’ll just go over some of the ones I found myself using most often.</p><h3>LiveData</h3><p>A lot of the LiveData functionality is implemented as extension functions as well: methods like <a href="https://developer.android.com/reference/kotlin/androidx/lifecycle/package-summary#map">map</a>, <a href="https://developer.android.com/reference/kotlin/androidx/lifecycle/package-summary#switchmap">switchMap</a> or <a href="https://developer.android.com/reference/kotlin/androidx/lifecycle/package-summary#distinctuntilchanged">distinctUntilChanged</a> (<a href="https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:lifecycle/lifecycle-livedata-ktx/src/main/java/androidx/lifecycle/Transformations.kt;l=35">source</a>).</p><p>For example, using <a href="https://developer.android.com/reference/kotlin/androidx/lifecycle/package-summary#map">map</a> from livedata-ktx removes the need to call Transformations.map(livedata) { /* map function */ }, and allows us to call directly liveData.map in a more Kotlin idiomatic way.</p><p>When you observe a LiveData object, you’ll have to implement an <a href="https://developer.android.com/reference/kotlin/androidx/lifecycle/Observer">Observer</a>. But using the observe from lifecycle-ktx, the code becomes simpler. Make sure you call import androidx.lifecycle.observe if the method isn’t found.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8f1016b334728170b5d2f6cae7715bb5/href">https://medium.com/media/8f1016b334728170b5d2f6cae7715bb5/href</a></iframe><p>LiveData is ideal for exposing data to be consumed by the UI so, to convert from Flow to LiveData and from LiveData to Flow, the lifecycle-livedata-ktx artifact provides two handy extension functions: <a href="https://developer.android.com/reference/kotlin/androidx/lifecycle/package-summary#aslivedata">Flow.asLiveData()</a> and <a href="https://developer.android.com/reference/kotlin/androidx/lifecycle/package-summary#asflow">LiveData.asFlow()</a>.</p><h3>Activity / Fragment and ViewModel</h3><p>To construct a ViewModel, you would extend the <a href="https://developer.android.com/reference/androidx/lifecycle/ViewModel">ViewModel</a> class and implement <a href="https://developer.android.com/reference/androidx/lifecycle/ViewModelProvider.Factory">ViewModelProvider.Factory</a> if your ViewModel has dependencies. To instantiate it, use the <a href="https://developer.android.com/reference/kotlin/androidx/activity/package-summary#(androidx.activity.ComponentActivity).viewModels(kotlin.Function0)">viewModels</a> delegate (read more about delegates <a href="https://medium.com/androiddevelopers/delegating-delegates-to-kotlin-ee0a0b21c52b">here</a>): by viewModels(factory):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0cec9dc4658101bbff5cf0e44264c94f/href">https://medium.com/media/0cec9dc4658101bbff5cf0e44264c94f/href</a></iframe><p>viewModels is available in the -ktx artifact of activity and fragment.</p><p>When working with coroutines, you’ll find yourself needing to launch a coroutine in the ViewModel. The work done by the coroutine should be cancelled when the ViewModel is destroyed. Instead of implementing your own CoroutineScope, use <a href="https://developer.android.com/reference/kotlin/androidx/lifecycle/package-summary#viewmodelscope">viewModelScope</a>. The cancellation will be done automatically for you, in <a href="https://developer.android.com/reference/kotlin/androidx/lifecycle/ViewModel#oncleared">ViewModel.onCleared()</a>. Find out the ins and outs of viewModelScope from <a href="https://medium.com/androiddevelopers/easy-coroutines-in-android-viewmodelscope-25bffb605471">this blog post</a>.</p><h3>Room and WorkManager</h3><p>Both Room and WorkManager offer coroutines support via their -ktx artifacts. As we think it’s worth covering those more in depth, stay tuned for MAD Skills articles focused on those specific libraries!</p><h3>Other KTX modules</h3><p>AndroidX artifacts are not the only ones to provide KTX versions:</p><ul><li>Firebase has created <a href="https://firebaseopensource.com/projects/firebase/firebase-android-sdk/docs/ktx/common.md">common Kotlin extensions</a></li><li>Google Maps offers <a href="https://developers.google.com/maps/documentation/android-sdk/ktx">Maps</a> and <a href="https://developers.google.com/places/android-sdk/ktx">Places</a> ktx libraries</li><li>Play Core has a core-ktx artifact, providing coroutines support for monitoring in-app updates</li></ul><p>Concise, readable and Kotlin idiomatic — these are the features that will benefit your code, once you start using -ktx extensions. Stay tuned for more ways to take advantage of Kotlin and Jetpack in your app!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=da1dc81c6ecf" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/using-ktx-libraries-da1dc81c6ecf">Using KTX libraries</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Data classes — the classy way to hold data]]></title>
            <link>https://medium.com/androiddevelopers/data-classes-the-classy-way-to-hold-data-ab3b11ea4939?source=rss-d5885adb1ddf------2</link>
            <guid isPermaLink="false">https://medium.com/p/ab3b11ea4939</guid>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[kotlin-vocabulary]]></category>
            <category><![CDATA[android]]></category>
            <dc:creator><![CDATA[Florina Muntenescu]]></dc:creator>
            <pubDate>Tue, 03 Nov 2020 16:02:17 GMT</pubDate>
            <atom:updated>2020-11-03T16:02:17.994Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*X0QJqxE7mPdvAWzGCdat6g.png" /></figure><h3>Data classes — the classy way to hold data</h3><h4>Kotlin Vocabulary: data classes</h4><p>A Puppy has a name, a breed and a whole lot of cuteness. To model a class that holds just data, you should use a data class. The compiler simplifies your work by auto generating toString(), equals() and hashCode() for you and providing <a href="https://medium.com/androiddevelopers/breaking-down-destructuring-declarations-e21334ac1e9">destructuring</a> and copy functionality out of the box letting you focus on the data you need to represent. Read on to learn more about other advantages of data classes, their restrictions and to take a look under the hood of how they’re implemented.</p><h3>Usage overview</h3><p>To declare a data class, use the data modifier and specify the properties of the class as val or var parameters in the constructor. As with any function or constructor, you can also provide default arguments, you can directly access and modify properties and define functions inside your class.</p><p>But, you get several advantages over regular classes:</p><ul><li><strong>toString(), </strong><strong>equals() and </strong><strong>hashCode() are implemented</strong> for you, by the Kotlin compiler, avoiding a series of small human errors that can cause bugs: like forgetting to update them every time you add or update your properties, logic mistakes when implementing hashCode, forgetting to implement hashCode when you’re implementing equals and more.</li><li><strong>destructuring</strong></li><li><strong>ease of copying </strong>by calling the copy() method:</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d7a76b96f86a41100a77127aa0ddc873/href">https://medium.com/media/d7a76b96f86a41100a77127aa0ddc873/href</a></iframe><h3>Restrictions</h3><p>Data classes come with a series of restrictions.</p><h3>Constructor parameters</h3><p>Data classes were created as a data holder. To enforce this role, you have to pass at least one parameter to the primary constructor and the parameters need to be <strong>val or </strong><strong>var </strong><a href="https://kotlinlang.org/docs/reference/properties.html"><strong>properties</strong></a>. Trying to add a parameter without val/var leads to a compile error.</p><p>As a best practice, consider using vals instead of vars, to promote immutability. Otherwise, subtle issues can appear for example when using data classes as keys for HashMap objects, as the container can get in an invalid state when the var value changes.</p><p>Similarly, trying to add a vararg parameter in the primary constructor leads to a compile error as well:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/31085da52caf9eef9252fd64be80802f/href">https://medium.com/media/31085da52caf9eef9252fd64be80802f/href</a></iframe><p>vararg is not allowed due to how equals() works on the JVM for arrays and collections. Andrey Breslav <a href="https://blog.jetbrains.com/kotlin/2015/09/feedback-request-limitations-on-data-classes/">explains</a>:</p><blockquote>Collections are compared structurally, while arrays are not, equals() for them simply resorts to referential equality: this === other.</blockquote><h3>Inheritance</h3><p>Data classes can inherit from interfaces, abstract classes and classes but cannot inherit from other data classes. Data classes also can’t be marked as open. For example, adding open will result in an error: Modifier ‘open’ is incompatible with ‘data’.</p><h3>Under the hood</h3><p>Let’s check what exactly does Kotlin generate to be able to understand how some of these features are possible. To do this, we’ll look at the Java decompiled code: Tools -&gt; Kotlin -&gt; Show Kotlin Bytecode then press the Decompile button.</p><h3>Properties</h3><p>Like with a regular class, Puppy is a public final class, containing the properties we defined and the getters and setters for them:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cf17dee54237e95cd16f0cfe1ee4147d/href">https://medium.com/media/cf17dee54237e95cd16f0cfe1ee4147d/href</a></iframe><h3>Constructor(s)</h3><p>The constructor we defined is generated. Because we use a default argument in the constructor, then we get the 2nd synthetic constructor as well.</p><p>To find out more about default arguments and the generated code, check out this blog post.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/acb39b186c3c08fae9d19be2c077d394/href">https://medium.com/media/acb39b186c3c08fae9d19be2c077d394/href</a></iframe><h3>toString(), hashCode(), equals()</h3><p>Kotlin generates the toString(), hashCode() and equals() methods. When you modify the data class, updating properties, the right method implementations are generated for you, automatically. Like this, you know that hashCode() and equals() will never be out of sync. Here’s how they look for our Puppy class:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c94584c9f4145f5321e5c5ab111de78d/href">https://medium.com/media/c94584c9f4145f5321e5c5ab111de78d/href</a></iframe><p>While toString and hashCode are quite straightforward an look similar to the way you’d implement it, equals uses <a href="https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/Intrinsics.java#L166">Intrinsics.areEqual</a> that performs a structural equality:</p><pre>public static boolean areEqual(Object first, Object second) {<br>    return first == null ? second == null : first.equals(second);<br>}</pre><p>By using a method call rather than the direct implementation, the Kotlin language developers get more flexibility, as they can change the implementation of areEqual in future language versions, if needed.</p><h3>Components</h3><p>To enable destructuring, data classes generate componentN() methods that just return a field. The component number follows the order of the constructor parameters:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1ff9cbd34fae11cc408482aa18377380/href">https://medium.com/media/1ff9cbd34fae11cc408482aa18377380/href</a></iframe><p>Find out more about destructuring from our <a href="https://medium.com/androiddevelopers/breaking-down-destructuring-declarations-e21334ac1e9">Kotlin Vocabulary post</a>.</p><h3>Copy</h3><p>Data classes generate a copy() method that can be used to create a new instance of the object, keeping 0 or more of the original values. You can think of copy() as a method that gets all fields of the data class as parameters, with the values of the fields as default values. Knowing this, you won’t be surprised that Kotlin generates 2 copy() methods: copy and copy$default. The latter is a synthetic method that ensures that when a value isn’t passed in for a parameter, then the right value is used from the base class:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7992da30308995f03ed23d4cf8c78a7d/href">https://medium.com/media/7992da30308995f03ed23d4cf8c78a7d/href</a></iframe><h3>Conclusion</h3><p>Data classes are one of the most used Kotlin features and for a good reason — they decrease the boilerplate code you need to write, enable features like destructuring and copying an object and let you focus on what matters: your app.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ab3b11ea4939" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/data-classes-the-classy-way-to-hold-data-ab3b11ea4939">Data classes — the classy way to hold data</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Should I learn Kotlin for Android and other FAQs]]></title>
            <link>https://medium.com/androiddevelopers/should-i-learn-kotlin-for-android-and-other-faqs-88a2bb281a60?source=rss-d5885adb1ddf------2</link>
            <guid isPermaLink="false">https://medium.com/p/88a2bb281a60</guid>
            <category><![CDATA[androiddev]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[kotlin-beginners]]></category>
            <dc:creator><![CDATA[Florina Muntenescu]]></dc:creator>
            <pubDate>Tue, 03 Nov 2020 15:58:24 GMT</pubDate>
            <atom:updated>2020-11-03T15:58:24.397Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zs_ArMJPix6FS-WHJWXvBQ.png" /></figure><p>Ever since we announced our Kotlin support in 2017 we’ve been getting a lot of questions about Kotlin on Android: you wanted to know whether it’s time to learn it, to introduce it to your app, what the best course or tutorial to learn Kotlin is, whether Google is using Kotlin internally and what our plans for the Java programming language are. In this post, I want to answer some of these questions.</p><h3>Q: Should I learn Kotlin for Android?</h3><p>The questions we get most often are on the same line:</p><ul><li><em>“What should I choose to learn between Kotlin and the Java programming language for a beginner?”</em></li><li><em>​”I’ve done the basics of the Java programming language, is it the right time for me to switch to Kotlin for Android development?”</em></li><li><em>“For an old time Java developer wanting to learn Android development, do you recommend going straight to Kotlin or learning in Java?”</em></li></ul><p>Short answer:</p><blockquote>Yes! Start learning and using Kotlin!</blockquote><p>Long answer:</p><h3>Kotlin &amp; Android</h3><p>In 2017 we announced Kotlin support at Google I/O. That’s when we started making the first steps towards ensuring that our APIs, docs and samples are Kotlin friendly. In 2019 Android became Kotlin-first, so we started relying even more on Kotlin features. As an example, Coroutines became our recommended solution for running asynchronous work. Here’s what else we’ve done:</p><h4>Kotlin-first libraries</h4><p>We started by adding first class support for Kotlin Coroutines to several of our Android Jetpack APIs, like Room, LiveData, ViewModel and WorkManager, transforming the way we do async operations on Android. The Firebase Android SDK and many Jetpack libraries have <a href="https://developer.android.com/kotlin/ktx">Kotlin extension libraries</a> (KTX) to make using them even more fluent with Kotlin.</p><p>Now, many of our libraries such as Paging 3.0 and DataStore are Kotlin-first. <a href="https://developer.android.com/jetpack/compose">Jetpack Compose</a>, our new, unbundled, declarative UI toolkit, is written from the ground up in Kotlin.</p><h4>Tooling</h4><p>Development productivity comes from great tooling. As such, we’ve been making many improvements for Kotlin to the compilation toolchain, including enhancements to the Kotlin JVM compiler, Kotlin-specific R8 optimizations, and even developing new tools like <a href="http://goo.gle/ksp">Kotlin Symbol Processing</a>. We’ve added built-in Android Kotlin Live templates, which allow you to use shorthand to add common Android constructs to your Kotlin app. At the same time, new Kotlin-specific Lint checks help you make Kotlin code more language idiomatic. This is especially useful as you’re transitioning from the Java programming language to Kotlin.</p><h3>Q: Is Google using Kotlin internally?</h3><p>Within Google we’re also doubling down on Kotlin. Over 60 of our apps (like Google Home, Drive, Maps and others) have added Kotlin to their codebases. Our large internal codebase counts <strong>over two million lines</strong> of Kotlin code.</p><h3>Q: Should I migrate my app to Kotlin?</h3><p>We often get this question, but the answer here depends on you. If you’re happy with your current codebase and tech stack, are proficiently using your solution for managing async tasks, and have an efficient way to catch errors, migrating may not be the solution for you</p><p>If you like what you’ve seen with Kotlin from either trying it or learning the language through some of the courses mentioned below, and you also want to take advantage of the latest Jetpack APIs, then you should consider adding Kotlin to your app. One of the advantages of Kotlin is it’s great interop with the Java programming language. You can take small, incremental steps in adopting it — maybe first trying it out on tests, then on new features and then you can try converting some of the older code as you touch it.</p><p>To make your first steps towards migrating to idiomatic Kotlin check out our <a href="https://codelabs.developers.google.com/codelabs/java-to-kotlin#0">Converting to Kotlin codelab</a>.</p><h3>Q: What about the Java programming language in Android?</h3><p>We added Kotlin support in addition to Java as they both compile to the same bytecode and can exist alongside each other. We love Kotlin for its expressive, safer way to write code. We continue to <a href="https://developer.android.com/studio/write/java8-support">maintain and evolve our Java support as well</a>. For example, in Android 11, we added support for a number of APIs from newer OpenJDK releases all the way up to version 13 and Android Studio even lets you use some of these APIs on all Android devices, regardless of their OS version. Read more about the support for newer language APIs <a href="https://medium.com/androiddevelopers/support-for-newer-java-language-apis-bca79fc8ef65">here</a>.</p><h3>Q: What’s the best way to learn Kotlin?</h3><p>Adopting a new language is not an easy task, but we’re trying to make it as easy as possible:</p><ul><li>Get started with the training <a href="https://developer.android.com/kotlin/campaign/learn">courses</a> — they address developers of all levels, from beginners to pros, that will help you advance your Kotlin on Android skills, from <a href="https://developer.android.com/courses/android-basics-kotlin/course">Android Basics in Kotlin</a>, a new online course for people <strong>without programming experience</strong>, to advanced tutorials that teach you <a href="https://codelabs.developers.google.com/codelabs/advanced-kotlin-coroutines/index.html?index=..%2F..index#0">how to use Coroutines</a>.</li><li>All of our documentation pages contain Kotlin code snippets, so you can easily compare how our APIs work in both languages, and all of our <a href="http://github.com/android">samples</a> have Kotlin versions.</li><li>Check out our <a href="http://goo.gle/kotlin-posts">articles</a> and <a href="http://goo.gle/kotlin-videos">videos</a> that teach you a wide range of Kotlin topics.</li><li>Read the guidance for <a href="https://developer.android.com/kotlin/learn">developers</a> and <a href="https://developer.android.com/kotlin/adopt-for-large-teams">teams</a> who want to <a href="https://developer.android.com/kotlin/add-kotlin">switch to Kotlin</a> on our <a href="http://developers.android.com/kotlin">developers.android.com/kotlin</a> pages.</li></ul><p>Since officially adding support for Kotlin 3 years ago, we’ve been stepping up to support this awesome language and ecosystem. Together with JetBrains, we’ve formed a foundation for Kotlin to ensure the language ages well, for example through a careful process for vetting breaking changes. Our contributions extend beyond that: Google has a team of engineers contributing to the Kotlin compiler as their full-time job, the Jetpack APIs we’re building are not only supporting Kotlin but they are Kotlin-first, and we’re committed to making Kotlin on Android a seamless experience.</p><p><em>Java is a registered trademark of Oracle and/or its affiliates.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=88a2bb281a60" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/should-i-learn-kotlin-for-android-and-other-faqs-88a2bb281a60">Should I learn Kotlin for Android and other FAQs</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fewer crashes and more stability with Kotlin]]></title>
            <link>https://medium.com/androiddevelopers/fewer-crashes-and-more-stability-with-kotlin-b606c6a6ac04?source=rss-d5885adb1ddf------2</link>
            <guid isPermaLink="false">https://medium.com/p/b606c6a6ac04</guid>
            <category><![CDATA[kotlin-beginners]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[buildbetterapps]]></category>
            <dc:creator><![CDATA[Florina Muntenescu]]></dc:creator>
            <pubDate>Thu, 29 Oct 2020 15:10:47 GMT</pubDate>
            <atom:updated>2020-10-29T15:10:47.776Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xpV09u6FyIP96us3K7nDIg.jpeg" /></figure><p>Users expect to have a seamless experience with your app. Crashes can lead to an increase in poor reviews, uninstalls and even damaging your brand perception. From talking to the community we know that one of the main reasons to adopt Kotlin is safer code. In this post I’ll share a couple of the ways Kotlin improved the stability of a few of our partners’ code but we’ll also look at the results of some Google Play store stats and see if there’s a correlation between using Kotlin and the number of crashes (spoilers: there is!).</p><h3>App quality</h3><p>The quality of your app doesn’t only have an impact on your user experience. There are several other elements that will be affected by a high number of crashes:</p><ul><li><strong>App discoverability</strong> — Google Play store’s recommendations are composed of a mix of human curation and algorithmic calculations, of which quality is one of the largest considerations.</li><li><strong>Brand</strong> — Your product performance can impact your ratings and reviews, which can impact brand perception.</li><li><strong>Higher number of (engaged) users</strong> — Having improved organic traffic and brand perception can lead to better user acquisition and retention, which can also impact engagement and lower funnel metrics.</li></ul><blockquote>Apps built with Kotlin are 20% less likely to crash.</blockquote><p>What role does Kotlin play in this? We looked at the top 1,000 apps on Google Play and we saw those that use Kotlin have 20% fewer crashes per user than those that don’t.</p><p>One example of this comes from the engineering team at Swiggy, where 74% of their code is in Kotlin — they saw a <strong>50% reduction in crashes</strong> since moving new feature development to Kotlin.</p><h3>Avoiding NullPointerExceptions</h3><p>The #1 cause of crashes on Google Play are NullPointerExceptions. In 2018, the Google Home team started writing all new features in Kotlin and saw a <a href="https://android-developers.googleblog.com/2020/07/Google-home-reduces-crashes.html">33% decrease in Null Pointer crashes</a> over one year.</p><blockquote>Google Home saw a 33% decrease in NullPointerExceptions</blockquote><p>To avoid NullPointerExceptions, you need to make sure that the object references you’re working with are non-null before calling methods on them or trying to access their members. In Kotlin, nullability is part of the type system. For example, a variable needs to be declared from the beginning as nullable or non-nullable. By making nullability part of the type system you don’t have to rely on your memory and knowledge of the codebase, or on compile time warnings (if you annotate your fields / parameters with @Nullable) but rather nullability gets enforced, so you’ll get compile time errors, not just warnings. For ways to handle nullability check out <a href="https://developer.android.com/topic/performance/vitals/crash#prevent-crashes-null-pointer">this page</a>.</p><h3>Avoiding common issues</h3><p>There are a lot of issues that we developers introduce without realising and a lot of them can be quite subtle and hard to investigate. Here are just a few of these issues that are avoided when using Kotlin.</p><h4>hashCode() and equals()</h4><p>If two objects are equal, then their hashcode should be the same — but yet, it’s common to forget to implement one of these methods or to update them when new properties are added to the class. When working with classes whose role is to just hold data, use Kotlin <a href="https://kotlinlang.org/docs/reference/data-classes.html">data classes</a>. With data classes <strong>hashCode() and </strong><strong>equals() is generated for you by the compiler</strong> and therefore automatically updated when you change the class’s properties.</p><h3>Structural vs referential equality</h3><p>Are two objects structurally equal (have equivalent content) or referentially equal (their pointers are the same)? In the Java programming language, for primitives you would always use ==, therefore, a common mistake is to call == (referential equality) for objects as well, when you actually want to check if they are structurally equal (checked by calling equals()). First, <strong>Kotlin doesn’t have primitive types</strong>, it uses classes like Int or String; so this means that you don’t need to make this differentiation between objects and primitive types anymore as everything is an object. Second, Kotlin defined == for structural equality and === for referential equality so <strong>you won’t be checking for referential equality when you shouldn’t</strong>.</p><h3>When if else if else if else is not enough</h3><p>When working with enums, you often need to ensure that you’re covering all the possible cases. This leads to using a switch or a chain of if elses. When you modify your enum to add a new value, you then have to manually check each code snippet where you’re using the enum and make sure you’re handling the new case. But this is error prone. In Kotlin, you can <strong>rely on the compiler</strong> for this, if you’re using when as an expression: you’ll get a compiler error if you’re not covering all possible branches.</p><h3>Conclusion</h3><p>The stability of your app is important for your users and your brand. Start using Kotlin to reduce crash rates, keep your users happy and stay on top of your retention and acquisition by keeping a high app rating.</p><p>Read more about how you can <a href="https://developer.android.com/kotlin/build-better-apps">Build Better Apps with Kotlin</a>, and see how developers have benefited from Kotlin by reading our <a href="https://developer.android.com/kotlin/stories">case studies</a>. To make your first steps with<a href="http://d.android.com/kotlin"> Kotlin</a>, one of the most <a href="https://insights.stackoverflow.com/survey/2020">loved languages in the world</a>, check out our <a href="https://developer.android.com/kotlin/first">Getting started page</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b606c6a6ac04" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/fewer-crashes-and-more-stability-with-kotlin-b606c6a6ac04">Fewer crashes and more stability with Kotlin</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Breaking down destructuring declarations]]></title>
            <link>https://medium.com/androiddevelopers/breaking-down-destructuring-declarations-e21334ac1e9?source=rss-d5885adb1ddf------2</link>
            <guid isPermaLink="false">https://medium.com/p/e21334ac1e9</guid>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[kotlin-beginners]]></category>
            <category><![CDATA[kotlin-vocabulary]]></category>
            <dc:creator><![CDATA[Florina Muntenescu]]></dc:creator>
            <pubDate>Tue, 27 Oct 2020 16:02:39 GMT</pubDate>
            <atom:updated>2020-10-27T16:02:39.426Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="Illustration of mobile phone with Kotlin and Android logos around it." src="https://cdn-images-1.medium.com/max/1024/1*X0QJqxE7mPdvAWzGCdat6g.png" /></figure><h4>Kotlin Vocabulary — destructuring</h4><p>Sometimes you just want to break down one object that contains multiple fields to initialize several separate variables. To achieve this, you can use Kotlin’s destructuring declarations. Read on to find out how to use this feature, what Kotlin types offer it by default, how to implement it in your own classes or for classes that you don’t control but you think would benefit from destructuring and how everything works under the hood.</p><h3>Usage</h3><p>Destructuring declarations allows us to define <strong>local</strong> values/variables as such:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/64d402039380ba1111fc965b89c20868/href">https://medium.com/media/64d402039380ba1111fc965b89c20868/href</a></iframe><p>It’s a convenient way to work with data coming from functions or collections:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ca3a9f2e3682d6efe8f52d0a02bf8c59/href">https://medium.com/media/ca3a9f2e3682d6efe8f52d0a02bf8c59/href</a></iframe><p>By default, all data classes support destructuring.</p><p>You can decide to only use a subset of variables from your class’s fields:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/386b754b20fd64812e5a4675599a1818/href">https://medium.com/media/386b754b20fd64812e5a4675599a1818/href</a></iframe><p>Destructuring doesn’t allow you to pick exactly <strong>which</strong> fields you want to use; it will always use the first x fields, where x is the number of variables you declare. The downside of this is that it’s easy to make mistakes. For example the following snippet might provide an unexpected result:</p><pre>val (name, rating) = goodDoggo</pre><p>The rating value will actually hold the value of goodDoggo.breed. You will get a warning saying: “Variable name ‘rating’ matches the name of a different component” and a suggestion to rename the rating to breed. As this is only in the IDE and not a compile warning it might be easy to miss.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*gYYP640wiKB1RCFA" /></figure><p>Using a wrong destructuring variable declaration</p><p>If you only need a subset of non-consecutive fields, use _ for those you’re not interested in, Kotlin will just skip them. The example above becomes:</p><pre>val (name, _, rating) = goodDoggo</pre><h3>Under the hood</h3><p>Let’s take a look at a decompiled data class to see what’s going on. In this post we’ll only focus on the functions generated for destructuring. For more information on data classes in general, stay tuned for a future post.</p><p>To see the Java decompiled code, go to Tools -&gt; Kotlin -&gt; Show Kotlin Bytecode then press the Decompile button.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2fd890f1423b18336e0cf679e6dc4914/href">https://medium.com/media/2fd890f1423b18336e0cf679e6dc4914/href</a></iframe><p>We see that functions called componentN are generated for every property declared in the primary constructor, where N is the index of the field in the primary constructor.</p><h3>Implementing destructuring</h3><p>As we’ve seen, destructuring relies on componentN functions. So if you want to add the destructuring functionality to a class that doesn’t support it, then just implement the corresponding componentN operator function. Make sure you prefix them with the operator keyword.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/49be2d4cefd25dfe76b561c61ff73212/href">https://medium.com/media/49be2d4cefd25dfe76b561c61ff73212/href</a></iframe><h3>Implementing destructuring for classes you don’t own</h3><p>Kotlin allows you to implement destructuring for classes you don’t own via extension functions. For example, <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/-entry/">Map.Entry</a> is just an interface and by default it does not support destructuring. To overcome this, component1() and component2() functions were created, that return the key and value of Map.Entry.</p><h3>Conclusion</h3><p>Use destructuring whenever you need to unpack the fields of an object to values/variables. Under the hood destructuring is implemented by providing componentN operator functions, so you can provide those yourself for classes that you think benefit from this functionality.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e21334ac1e9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/breaking-down-destructuring-declarations-e21334ac1e9">Breaking down destructuring declarations</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Don’t argue with default arguments]]></title>
            <link>https://medium.com/androiddevelopers/dont-argue-with-default-arguments-2245b2c752c?source=rss-d5885adb1ddf------2</link>
            <guid isPermaLink="false">https://medium.com/p/2245b2c752c</guid>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[kotlin-beginners]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[kotlin-vocabulary]]></category>
            <dc:creator><![CDATA[Florina Muntenescu]]></dc:creator>
            <pubDate>Thu, 08 Oct 2020 14:32:38 GMT</pubDate>
            <atom:updated>2020-10-08T14:32:38.550Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*X0QJqxE7mPdvAWzGCdat6g.png" /></figure><p><em>Kotlin Vocabulary</em></p><p>Short and easy to use, <a href="https://kotlinlang.org/docs/reference/functions.html#default-arguments">default arguments</a> allow you to implement function overloads without the boilerplate. Like many Kotlin features, this can feel like magic. Are you curious to learn its secrets? Read on to find out how default arguments work under the hood.</p><h3>Basic usage</h3><p>If you need to overload a function, instead of implementing the same function multiple times, you can use default arguments:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/33e02247ad8b6bde81b9066058e0aa7d/href">https://medium.com/media/33e02247ad8b6bde81b9066058e0aa7d/href</a></iframe><p>Default arguments can be applied to constructors as well:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2e8f7fe2f79cf44dc36b5521d4f298cb/href">https://medium.com/media/2e8f7fe2f79cf44dc36b5521d4f298cb/href</a></iframe><h3>Java interop</h3><p>By default, Java doesn’t recognize the default value overload:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e090023723e4ab6e2bbe4f68c9854c33/href">https://medium.com/media/e090023723e4ab6e2bbe4f68c9854c33/href</a></iframe><p>To instruct the compiler to generate the overload methods, use the <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-jvm-overloads/">@JvmOverloads</a> annotation on your Kotlin function:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/63d0067c37722a174f9fea31c3a07a97/href">https://medium.com/media/63d0067c37722a174f9fea31c3a07a97/href</a></iframe><h3>Under the hood</h3><p>Let’s look at the Java decompiled code to see what the compiler generates for us: Tools -&gt; Kotlin -&gt; Show Kotlin Bytecode then press the Decompile button.</p><h4>Functions</h4><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/94e92296d335113d400b696961cbac04/href">https://medium.com/media/94e92296d335113d400b696961cbac04/href</a></iframe><p>We see that the compiler generates 2 functions:</p><ul><li>play — that has 1 parameter: Toy and is called when default arguments are not used</li><li>a synthetic method play$default — that has 3 parameters: Toy, an int and an Object; it’s called whenever the default arguments are used. The Object parameter is always null but the value of the int differs. Let’s see how!</li></ul><h4>The int parameter</h4><p>The value of the int parameter of play$default is computed based on the number and the index of the arguments that have a default argument passed in. Based on the value of this parameter, the Kotlin compiler knows with which parameters to call the play function.</p><p>In our play() example call, the argument at index 0 is using the default argument. Therefore, play$default is called with int var1 = 2⁰:</p><pre>play$default((Toy)null, 1, (Object)null);</pre><p>The play$default implementation then knows that the value of var0 should be replaced with the default value.</p><p>Let’s take a more complex example to see how the int parameter behaves. Let’s expand our play function and, at the call site, use the default argument for doggo and toy:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/63cf74cd65bf12f1596a338406c7d32f/href">https://medium.com/media/63cf74cd65bf12f1596a338406c7d32f/href</a></iframe><p>Let’s see what happened in the decompiled code:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d3148b6924191df2e75bc35cbc65ecd4/href">https://medium.com/media/d3148b6924191df2e75bc35cbc65ecd4/href</a></iframe><p>We see that now, our int parameter is 5. Here’s how this was computed: the parameters at positions 0 and 2 are using the default argument so var3 = 2⁰ + 2² = 5. In a <a href="https://en.wikipedia.org/wiki/Bitwise_operation#AND">bitwise </a><a href="https://en.wikipedia.org/wiki/Bitwise_operation#AND">&amp; operation</a>, the parameters get evaluated as such:</p><ul><li>var3 &amp; 1 != 0 is true so var0 = goodDoggo</li><li>var3 &amp; 2 != 0 is false so var1 is not replaced</li><li>var3 &amp; 4 != 0 is true so var2 = SqueakyToy</li></ul><p>Based on the bitmask applied to var3, the compiler can compute which parameters should be replaced with default values.</p><h3>The Object parameter</h3><p>In the examples above you might have noticed that the value of the Object parameter is always null and that it’s actually never used in the play$default function. This parameter is connected to supporting default values in overriding functions.</p><h3>Default arguments and Inheritance</h3><p>What happens when we want to override a function with default arguments?</p><p>Let’s change the example above and:</p><ul><li>Make play an open function of Doggo and Doggo an open class.</li><li>Create a new PlayfulDoggo class, that extends Doggo and overrides play</li></ul><p>When we want to set a default value in PlayfulDoggo.play we see that we are not allowed: <strong>An overriding function is not allowed to specify default values for its parameters</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2622a26fc1c26e5264a423ca329042fa/href">https://medium.com/media/2622a26fc1c26e5264a423ca329042fa/href</a></iframe><p>If we remove the override and we check the decompiled code, PlayfulDoggo.play() looks like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/abd099e30c262ef37332b32d0850566f/href">https://medium.com/media/abd099e30c262ef37332b32d0850566f/href</a></iframe><p>Does this mean that super calls with default arguments will be supported in the future? We’ll just have to wait and see.</p><h3>Constructors</h3><p>For constructors, the decompiled Java code has only one difference. Let’s take a look:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/debc9e1a730ab4b4101e54f5a069f343/href">https://medium.com/media/debc9e1a730ab4b4101e54f5a069f343/href</a></iframe><p>Constructors also create a synthetic method but, instead of the Object used in functions, constructors use a <a href="https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/DefaultConstructorMarker.java">DefaultConstructorMarker</a> which is called with null:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/91d916dbcdc88670334bb4ff86a40d0d/href">https://medium.com/media/91d916dbcdc88670334bb4ff86a40d0d/href</a></iframe><p>Secondary constructors with default arguments will also generate another synthetic method using a DefaultConstructorMarker, like primary constructors:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/871393b2f20db055180cd4af375d2166/href">https://medium.com/media/871393b2f20db055180cd4af375d2166/href</a></iframe><h3>Conclusion</h3><p>Simple and sweet, default arguments decrease the amount of boilerplate code we need to write when dealing with overloaded methods, allowing us to set default values for our parameters. As is the case for a lot of Kotlin keywords, when can understand their magic by peeking at the code it writes for us. Check out our other Kotlin Vocabulary posts for more.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2245b2c752c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/androiddevelopers/dont-argue-with-default-arguments-2245b2c752c">Don’t argue with default arguments</a> was originally published in <a href="https://medium.com/androiddevelopers">Android Developers</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>