<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pavel Sveda</title>
    <description>The latest articles on DEV Community by Pavel Sveda (@xsveda).</description>
    <link>https://dev.to/xsveda</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F319899%2Ff4bd0eac-f96b-41d0-8113-cb7b75e9ca16.jpeg</url>
      <title>DEV Community: Pavel Sveda</title>
      <link>https://dev.to/xsveda</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xsveda"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Pavel Sveda</dc:creator>
      <pubDate>Fri, 26 Dec 2025 13:39:54 +0000</pubDate>
      <link>https://dev.to/xsveda/-1jl4</link>
      <guid>https://dev.to/xsveda/-1jl4</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/adiozdaniel/are-we-losing-our-manners-in-software-development-1c55" class="crayons-story__hidden-navigation-link"&gt;Are We Losing Our Manners in Software Development?&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/adiozdaniel" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F807835%2Fb4d8170d-7d69-45d1-ad50-87d155e3cbcd.jpeg" alt="adiozdaniel profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/adiozdaniel" class="crayons-story__secondary fw-medium m:hidden"&gt;
              adiozdaniel
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                adiozdaniel
                
              
              &lt;div id="story-author-preview-content-3112613" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/adiozdaniel" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F807835%2Fb4d8170d-7d69-45d1-ad50-87d155e3cbcd.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;adiozdaniel&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/adiozdaniel/are-we-losing-our-manners-in-software-development-1c55" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Dec 18 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/adiozdaniel/are-we-losing-our-manners-in-software-development-1c55" id="article-link-3112613"&gt;
          Are We Losing Our Manners in Software Development?
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag crayons-tag--filled  " href="/t/discuss"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;discuss&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/performance"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;performance&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/softwaredevelopment"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;softwaredevelopment&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/adiozdaniel/are-we-losing-our-manners-in-software-development-1c55" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;55&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/adiozdaniel/are-we-losing-our-manners-in-software-development-1c55#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              31&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>discuss</category>
      <category>performance</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Apple Silicon chip performance in Android development</title>
      <dc:creator>Pavel Sveda</dc:creator>
      <pubDate>Sun, 11 Apr 2021 09:12:42 +0000</pubDate>
      <link>https://dev.to/xsveda/apple-silicon-chip-performance-in-android-development-45ld</link>
      <guid>https://dev.to/xsveda/apple-silicon-chip-performance-in-android-development-45ld</guid>
      <description>&lt;p&gt;After many years when Intel and AMD dominate the world of workstation CPUs with x86 chips there seems a new era to come. The era of ARM.&lt;/p&gt;

&lt;p&gt;Apple has introduced its ARM-based Apple Silicon M1 chip in late 2020 and the first benchmarks were for a lot of people too good to be true.&lt;/p&gt;

&lt;h1&gt;
  
  
  Motivation
&lt;/h1&gt;

&lt;p&gt;I'm an Android developer so what bothers me most is how performant is the chip in Android development.&lt;/p&gt;

&lt;p&gt;Official benchmarks are great to get some overview about CPU capabilities but they cannot answer my question as they are mostly based on rendering video or running demanding games which is a different kind of task.&lt;br&gt;
Also it would not be fair to do the comparison right away at the end of 2020 as the Android ecosystem was not compatible with Apple Silicon chips natively and the tools were running through the &lt;strong&gt;Rosetta 2&lt;/strong&gt; application compatibility layer.&lt;/p&gt;

&lt;p&gt;Now, after a few months since Apple Silicon launch there are first &lt;a href="https://www.azul.com/downloads/zulu-community/?version=java-11-lts&amp;amp;os=macos&amp;amp;architecture=arm-64-bit&amp;amp;package=jdk"&gt;OpenJDK builds with native support&lt;/a&gt; and &lt;a href="https://docs.gradle.org/7.0/release-notes.html#apple-silicon"&gt;Gradle supports it natively since version 7.0&lt;/a&gt;. That's all we need to make an Android project build times comparison!&lt;/p&gt;

&lt;h1&gt;
  
  
  Test
&lt;/h1&gt;

&lt;p&gt;We have 4 competitors in the test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2019 Dell Precision 5530, i7-8850H, 6 cores/12 threads, 32 GB RAM&lt;/li&gt;
&lt;li&gt;2020 MacBook Pro 16", i7-9750H, 6 cores/12 threads, 16 GB RAM&lt;/li&gt;
&lt;li&gt;2021 MacBook Pro 13", M1, 8 cores/8 threads, 16 GB RAM&lt;/li&gt;
&lt;li&gt;2021 MacMini, M1, 8 cores/8 threads, 16 GB RAM&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The test is to be done on 3 selected Android projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Small project (13k LoC, 1 APK, 1 module)&lt;/li&gt;
&lt;li&gt;Medium project (37k LoC, 1 APK, 36 modules)&lt;/li&gt;
&lt;li&gt;Bigger project (144k LoC, 6 APKs, 30 modules)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To compare the build times, I would first run the &lt;code&gt;gradlew assembleDebug&lt;/code&gt; to warm up the Gradle daemon and fetch all the dependencies and then make an average build time from 5-10 runs of the same task in offline without any help of cached results:&lt;br&gt;
&lt;code&gt;gradlew assembleDebug --offline --rerun-tasks --profile&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Main questions to ask are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Will MacBook Pro 13" with M1 chip beat the bigger Intel-based brother?&lt;/li&gt;
&lt;li&gt;Will MacMini beat the MacBook Pro 13" with the same HW equipment thanks to its desktop nature and possible more power or better cooling?&lt;/li&gt;
&lt;li&gt;Will 8 cores be enough for modularized projects?&lt;/li&gt;
&lt;li&gt;Will 16 GB of RAM be enough even for bigger projects?&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Results
&lt;/h1&gt;

&lt;p&gt;Here are the average build times for competitors on the test projects. Some were run both with Gradle 7.0 with native Apple Silicon support and Gradle 6.8 that uses Rosetta 2 compatibility layer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1feTaoUt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/joweuhne1716q3oxo2tu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1feTaoUt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/joweuhne1716q3oxo2tu.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;em&gt;Small, single-module project cannot be parallelized much but the M1 chip did the job in half the time then Intel i7 chip in MacBook Pro 16".&lt;br&gt;
Gradle 7.0 with native Apple Silicon support is certainly faster than Gradle 6.8 that uses Rosetta 2, but the difference is almost negligible.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LwHSLOMF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ck19vxbklxjqq8z4f35r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LwHSLOMF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ck19vxbklxjqq8z4f35r.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;em&gt;Similar results are to be seen on medium and well modularized project. Dell's and Mac's 12 threads Intel i7 chip were still too slow against M1.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bqQEYto---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n5vyerhud4hpmrbznrb8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bqQEYto---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n5vyerhud4hpmrbznrb8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;em&gt;On bigger project the difference in speed isn't so enormous but still the M1 outclassed the rivals. In this run the MacBook Pro 16" did a worse job than the technically slower Dell Precision probably due to smaller RAM.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Answers
&lt;/h1&gt;

&lt;p&gt;I leave the results evaluation on each of you but let me just try to answer the main questions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Will MacBook Pro 13" with M1 chip beat the bigger Intel-based brother?&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Yes, no doubt about it!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Will MacMini beat the MacBook Pro 13" with the same HW equipment thanks to its desktop nature and possible more power or better cooling?&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;No, this test didn't show any difference in performance of those two. Maybe when an IDE and Emulator will be running for 8 hours a day the MacMini might be more stable but that would be a more subjective observation.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Will 8 cores be enough for modularized projects?&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Yes, the difference in performance on single-module and highly modularized project were similar.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Will 16 GB of RAM be enough even for bigger projects?&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Yes-ish. Macs with M1 chip were fine with 16 GB RAM during the test but the older MacBook Pro 16" seems to have a problem on the bigger project. Also, IDE and Emulator were off during the test so in real-world use it might be a little limiting. One way or another, the power of M1 would overcome this limitation.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Main article image by &lt;a href="https://unsplash.com/@jason_corey_?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Jason Corey&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/velocity?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>apple</category>
      <category>m1</category>
      <category>benchmark</category>
    </item>
    <item>
      <title>What's new in Android Gradle Plugin 3.6</title>
      <dc:creator>Pavel Sveda</dc:creator>
      <pubDate>Sun, 03 May 2020 08:15:49 +0000</pubDate>
      <link>https://dev.to/xsveda/what-s-new-in-android-gradle-plugin-3-6-c8n</link>
      <guid>https://dev.to/xsveda/what-s-new-in-android-gradle-plugin-3-6-c8n</guid>
      <description>&lt;p&gt;February 2020 was quite busy as we got 4.1 Canary release of Android Studio and Android Gradle Plugin (AGP), former 4.0 Canary was bumped to Beta and we got Stable version of 3.6.&lt;br&gt;
&lt;a href="https://developer.android.com/studio/releases/gradle-plugin#3-6-0"&gt;Android Gradle Plugin 3.6&lt;/a&gt; is the last version in 3.x series and the last version that will work with Gradle 5.x. In tradition of minor version updates, it brings few smaller enhancements, but this is time it has also a new Feature with big &lt;em&gt;F&lt;/em&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  View Binding (&lt;a href="https://developer.android.com/topic/libraries/view-binding"&gt;docs&lt;/a&gt;)
&lt;/h1&gt;

&lt;p&gt;What is the most famous function on Android?&lt;br&gt;
Probably &lt;code&gt;View.findViewById()&lt;/code&gt;. For various reasons developers are trying to avoid using it as much as possible.&lt;br&gt;
There is a complete history of 3&lt;sup&gt;rd&lt;/sup&gt; party libraries and frameworks like &lt;em&gt;Kotlin Android Extensions&lt;/em&gt;, &lt;em&gt;Butter Knife&lt;/em&gt; or &lt;em&gt;Android Annotations&lt;/em&gt; that are trying to hide it behind a nicer API or annotations.&lt;br&gt;
Also Google contributed to this list with &lt;em&gt;Data Binding&lt;/em&gt; that also might serve as a replacement for binding &lt;code&gt;View&lt;/code&gt;s defined in &lt;code&gt;layout.xml&lt;/code&gt; and i.e. &lt;code&gt;Fragment&lt;/code&gt;'s code, although it is maybe too heavy to be used for binding views only.&lt;br&gt;
Maybe this was the reason why a new Google tool called &lt;code&gt;View Binding&lt;/code&gt; was created.&lt;/p&gt;
&lt;h3&gt;
  
  
  How does it work?
&lt;/h3&gt;

&lt;p&gt;I won't go into details about what it does and how you can use it as we have already a plenty of other blog posts out there. &lt;br&gt;
But there is one technical detail I didn't find anywhere. From the docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Once view binding is enabled in a module, it generates a binding class for each XML layout file present in that module.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;But who generates the code?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It cannot be an &lt;em&gt;Annotation Processor&lt;/em&gt; as in comparison to &lt;em&gt;Data Binding&lt;/em&gt;, &lt;em&gt;View Binding&lt;/em&gt; is said to require no annotation processing for faster compilation.&lt;/li&gt;
&lt;li&gt;It cannot be &lt;em&gt;Kotlin Compiler Plugin&lt;/em&gt; as &lt;em&gt;View Binding&lt;/em&gt; works also for Java code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I cannot find the answer anywhere, so I asked &lt;a href="https://twitter.com/JakeWharton"&gt;the author&lt;/a&gt;. It turns out that &lt;em&gt;View Binding&lt;/em&gt; is a standalone tool that consist of three components.&lt;/p&gt;
&lt;h3&gt;
  
  
  Code Generator
&lt;/h3&gt;

&lt;p&gt;This is the actual &lt;em&gt;View Binding&lt;/em&gt;'s engine.&lt;br&gt;
It creates a &lt;a href="https://android.googlesource.com/platform/frameworks/data-binding/+/studio-master-dev/compilerCommon/src/main/kotlin/android/databinding/tool/writer/ViewBinder.kt"&gt;ViewBinder.kt&lt;/a&gt; model for each layout in the project that requires a &lt;code&gt;*Binding&lt;/code&gt; class to be generated.&lt;br&gt;
Then there is &lt;a href="https://android.googlesource.com/platform/frameworks/data-binding/+/studio-master-dev/compilerCommon/src/main/kotlin/android/databinding/tool/writer/ViewBinderGenerateSource.kt"&gt;ViewBinderGenerateSource.kt&lt;/a&gt; that takes the outputs of &lt;em&gt;Data Binding&lt;/em&gt; XML layout parser and generates binding code using &lt;a href="https://github.com/square/javapoet"&gt;JavaPoet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Artifact: &lt;code&gt;androidx.databinding:databinding-compiler-common&lt;/code&gt; (&lt;a href="https://mvnrepository.com/artifact/androidx.databinding/databinding-compiler-common?repo=google"&gt;link&lt;/a&gt;)&lt;/p&gt;
&lt;h3&gt;
  
  
  Build Hook
&lt;/h3&gt;

&lt;p&gt;Code generation is invoked by Android Gradle Plugin during build. There is no much difference from how &lt;em&gt;Data Binding&lt;/em&gt; is configured in &lt;a href="https://android.googlesource.com/platform/tools/base/+/studio-master-dev/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/TaskManager.java#2400"&gt;TaskManager.java&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Artifact: &lt;code&gt;com.android.tools.build:gradle&lt;/code&gt; (&lt;a href="https://mvnrepository.com/artifact/com.android.tools.build/gradle?repo=google"&gt;link&lt;/a&gt;)&lt;/p&gt;
&lt;h3&gt;
  
  
  Feature API
&lt;/h3&gt;

&lt;p&gt;Last piece of the puzzle. &lt;em&gt;View Binding&lt;/em&gt; has a tiny public API available to developers that consists of single class: &lt;a href="https://android.googlesource.com/platform/frameworks/data-binding/+/studio-master-dev/extensions/viewbinding/src/main/java/androidx/viewbinding/ViewBinding.java"&gt;ViewBinding.java&lt;/a&gt;. It serves as &lt;em&gt;marker interface&lt;/em&gt; for all generated &lt;code&gt;*Binding&lt;/code&gt; classes.&lt;/p&gt;

&lt;p&gt;Artifact: &lt;code&gt;androidx.databinding:viewbinding&lt;/code&gt; (&lt;a href="https://mvnrepository.com/artifact/androidx.databinding/viewbinding?repo=google"&gt;link&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So, who generates the code?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Annotation Processors&lt;/em&gt; tend to be problematic in terms of configuration and performance. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Kotlin Compiler Plugins&lt;/em&gt; tend to be problematic to work with Java code (joke). &lt;/p&gt;

&lt;p&gt;&lt;em&gt;View Binding&lt;/em&gt; tend to be tiny, simple and quick. It shows us that sometimes there is a better way how to solve a problem out of "standard tools". In this case, it is one's own code generator baked to the Android Gradle Plugin.&lt;/p&gt;
&lt;h1&gt;
  
  
  Maven Publish plugin support (&lt;a href="https://developer.android.com/studio/build/maven-publish-plugin"&gt;docs&lt;/a&gt;)
&lt;/h1&gt;

&lt;p&gt;Android Gradle Plugin 3.6 is not all about &lt;em&gt;View Binding&lt;/em&gt;. If you are on a bigger project where dependencies are not shared as source code dependency but rather as compiled artifact dependency through artifact repository, it might be handy for you that AGP now supports Gradle's built-in &lt;a href="https://docs.gradle.org/current/userguide/publishing_maven.html"&gt;Maven Publish plugin&lt;/a&gt;.&lt;br&gt;
For most of the projects this might save a few tens lines of Gradle publishing logic. &lt;/p&gt;
&lt;h1&gt;
  
  
  Enhancements on R class generation
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;R&lt;/code&gt; class serves as a static list of application resources known at compile time. As projects grow their &lt;code&gt;R&lt;/code&gt; classes might easily get a few hundred thousand or even million lines of code that need to be compiled.&lt;/p&gt;

&lt;p&gt;To optimize the build performance AGP 3.6 starts to generate the Java bytecode directly so you don't have compile it. It means that instead of &lt;code&gt;R.java&lt;/code&gt; file in &lt;code&gt;build/generated&lt;/code&gt; directory you can find &lt;code&gt;R.jar&lt;/code&gt; file in &lt;code&gt;build/intermediates&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another change is that there is &lt;a href="https://developer.android.com/studio/releases/gradle-plugin#simplified-r-class"&gt;only one &lt;code&gt;R&lt;/code&gt; class generated per library module&lt;/a&gt;. This forces you to have a unique package name for each project module. If you need help with this requirement, there is a &lt;a href="https://dev.to/xsveda/what-s-new-in-android-gradle-plugin-3-4-3ki1#unique-package-names"&gt;check introduced in AGP 3.4&lt;/a&gt; that might serve you.&lt;/p&gt;

&lt;p&gt;But what is the main reason that &lt;code&gt;R&lt;/code&gt; classes are so big? By default, the module &lt;code&gt;R&lt;/code&gt; class contains references to all module resources but also inherits all references from other module dependencies.&lt;br&gt;
Example: Do you depend on &lt;em&gt;Material Design Components&lt;/em&gt; library in your base module? Sorry, all of your project module &lt;code&gt;R&lt;/code&gt; classes will contain few thousand of MDC fields. Bummer!&lt;br&gt;
But there is a cure. AGP 3.3 introduces &lt;a href="https://twitter.com/JakeWharton/status/1032396242062594048"&gt;not very well documented flag&lt;/a&gt;. When you enabled it in &lt;code&gt;gradle.properties&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;android.namespacedRClass=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it prevents references from dependencies being included in your module &lt;code&gt;R&lt;/code&gt; class.&lt;br&gt;
It also makes your module better isolated from architecture point of view as, unless you use explicitly import &lt;code&gt;R&lt;/code&gt; class from other module, you can use only your module's resources. It prevents you to accidentally use a drawable or a string from another module.&lt;/p&gt;
&lt;h1&gt;
  
  
  New default packaging tool (&lt;a href="https://developer.android.com/studio/releases/gradle-plugin#zipflinger"&gt;docs&lt;/a&gt;)
&lt;/h1&gt;

&lt;p&gt;It is called &lt;em&gt;zipflinger&lt;/em&gt; and you should not care unless you are doing some custom app packaging magic or so.&lt;br&gt;
In such case, or in case you are somehow struggling with the new packaging tool, you can disable it in &lt;code&gt;gradle.properties&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;android.useNewApkCreator=false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;So that's it for Android Gradle Plugin 3.x series. Next time let's check what's new in Gradle 6.x and Android Gradle Plugin 4.x !!!&lt;/p&gt;

</description>
      <category>gradle</category>
      <category>android</category>
      <category>kotlin</category>
      <category>build</category>
    </item>
    <item>
      <title>What's new in Android Gradle Plugin 3.5</title>
      <dc:creator>Pavel Sveda</dc:creator>
      <pubDate>Mon, 20 Apr 2020 17:59:20 +0000</pubDate>
      <link>https://dev.to/xsveda/what-s-new-in-android-gradle-plugin-3-5-157k</link>
      <guid>https://dev.to/xsveda/what-s-new-in-android-gradle-plugin-3-5-157k</guid>
      <description>&lt;p&gt;Android Gradle Plugin 3.5 came out in August 2019 as a part of Project Marble that focuses on making Android Studio and build tools more stable and polished. Thus, the only notable update is Data Binding now supports &lt;em&gt;incremental annotation processing&lt;/em&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Incremental annotation processing on Android
&lt;/h1&gt;

&lt;p&gt;Having Data Binding annotation processor support incremental processing is just a small part of much bigger puzzle. Let's have a look on how annotation processing on Android evolves and what configuration do we need to run it incrementally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Short history of annotation processing on Android
&lt;/h2&gt;

&lt;p&gt;The source-level annotation processing first appeared in Java 5 long before we heard about Android.&lt;/p&gt;

&lt;p&gt;Annotation processing in context of Android development appeared around 2013 with libraries like &lt;em&gt;Dagger&lt;/em&gt; or &lt;em&gt;Butter Knife&lt;/em&gt; that helps to reduce writing boilerplate code i.e. for Android system bindings.&lt;/p&gt;

&lt;p&gt;But, as Android projects grew, the build times become longer. And there appeared the need for incremental annotation processing that promises to lower the build times.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gradle's part
&lt;/h2&gt;

&lt;p&gt;The first step for incremental annotation processing is to have a support during build orchestration in build system - Gradle in our case. It took a couple years to make it, but finally in April 2018 Gradle 4.7 came out. Unfortunately, the incremental annotation processing is challenging and it was not possible to have for all the annotation processors incremental out of the box. &lt;/p&gt;

&lt;h2&gt;
  
  
  Annotation processor libraries
&lt;/h2&gt;

&lt;p&gt;Gradle 4.7 came with a new annotation processing API that allows annotation processors to work incrementally. In &lt;a href="https://dev.to/xsveda/what-s-new-in-gradle-5-0-for-mobile-developers-45en"&gt;Gradle 5.0&lt;/a&gt; the incremental annotation processing was optimized for performance.&lt;/p&gt;

&lt;p&gt;Anyway, the Gradle annotation processing API has one big limitation: to run an annotation processor incrementally, &lt;em&gt;all of the build annotation processors must be incremental&lt;/em&gt;. If only one of them does not adopt the new Gradle API, no one can run incrementally.&lt;/p&gt;

&lt;p&gt;So now it is annotation processor author's turn to adopt it and Gradle team is very supportive in this. Soon there was a list of major annotation processing libraries in &lt;a href="https://docs.gradle.org/current/userguide/java_plugin.html#state_of_support_in_popular_annotation_processors"&gt;Gradle docs&lt;/a&gt; describing their state on journey to incremental. &lt;/p&gt;

&lt;p&gt;Today, two years later, there is still quite a lot of work to be done for some libraries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kotlin troubles
&lt;/h2&gt;

&lt;p&gt;When Kotlin 1.0 has been released in 2016 it had an extra ordinary interoperability with Java. With one exception, annotation processing. Java annotation processing, baked to &lt;code&gt;javac&lt;/code&gt; compiler, does not work with Kotlin source code at all, so there was a need for completely new tool: &lt;code&gt;kapt&lt;/code&gt; (Kotlin Annotation Processing Tool).&lt;/p&gt;

&lt;p&gt;The first &lt;code&gt;kapt&lt;/code&gt; implementation was quite cumbersome to use as there was no way for Kotlin source code classes to refer to any code generated by the annotation processor. &lt;/p&gt;

&lt;p&gt;The second version of &lt;code&gt;kapt&lt;/code&gt; overcome this problem by generating stubs of Kotlin classes, but there were still issues with injecting values into fields etc.&lt;/p&gt;

&lt;p&gt;So there came the complete re-write known as &lt;code&gt;kapt3&lt;/code&gt; and everything was good. Until Gradle 4.7 appeared with incremental annotation processing, that works for Java but not for Kotlin and we had another challenge for &lt;code&gt;kapt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It took another year. In April 2019 Kotlin 1.3.30 has been released with &lt;code&gt;kapt&lt;/code&gt; supporting incremental annotation processors in an experimental mode. Later that year Kotlin 1.3.50 came out with stable implementation of incremental annotation processing support enabled by default.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Let's sum it up. If you want your annotation processors to run incrementally, you need to do three steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make sure you are using Gradle 5.0 or newer.&lt;/li&gt;
&lt;li&gt;Check that &lt;em&gt;all of your annotation processors&lt;/em&gt; are configured to run incrementally. Some do this by default, some need to be configured (&lt;a href="https://docs.gradle.org/current/userguide/java_plugin.html#state_of_support_in_popular_annotation_processors"&gt;overview in Gradle docs&lt;/a&gt; might help).&lt;/li&gt;
&lt;li&gt;If you have Kotlin code, make sure that you are using Kotlin 1.3.50 or newer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Happy incremental annotation processing!&lt;/p&gt;

</description>
      <category>gradle</category>
      <category>android</category>
      <category>kotlin</category>
      <category>build</category>
    </item>
    <item>
      <title>What's new in Android Gradle Plugin 3.4</title>
      <dc:creator>Pavel Sveda</dc:creator>
      <pubDate>Sat, 04 Apr 2020 20:24:39 +0000</pubDate>
      <link>https://dev.to/xsveda/what-s-new-in-android-gradle-plugin-3-4-3ki1</link>
      <guid>https://dev.to/xsveda/what-s-new-in-android-gradle-plugin-3-4-3ki1</guid>
      <description>&lt;p&gt;This post is part of &lt;em&gt;Gradle for mobile developers&lt;/em&gt; series that highlights Gradle Build System features useful for every developer on mobile project (mainly Android project). To extend this effort I'd like to cover also releases of Android Gradle Plugin (AGP). There are many blog posts presenting new features of Android Studio, but not much presenting the Android Gradle Plugin itself.&lt;/p&gt;

&lt;p&gt;I'll start with Android Gradle Plugin 3.4, released in April 2019, as it was the first version that builds on top of Gradle 5.x version only (which correlates with my previous Gradle 5.x series posts).&lt;/p&gt;

&lt;h1&gt;
  
  
  R8 enabled by default
&lt;/h1&gt;

&lt;p&gt;R8 is a new tool used in Android build pipeline introduced in Android Gradle Plugin 3.2 as feature preview and now being enabled by default for everyone. It is responsible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;shrinking&lt;/em&gt; = removing unused code and resources, code obfuscation, and optimizations (replaces &lt;em&gt;ProGuard&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;desugaring&lt;/em&gt; = backporting of newer Java version language features to Android Java version (replaces AGP internal desugar tool)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;dexing&lt;/em&gt; = converting Java bytecode to Dalvik bytecode (replaces &lt;em&gt;dx&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;R8 is able to do all these steps at once, and comparing to the previous build pipeline, R8 is faster while lowering the APK output size. It saves the time by parsing inputs just once, and creates smaller outputs (APKs or bundles) using broader optimizations. Also, the fact that the entire tool is developed by Google and open-sourced creates a promise of even more features in the future.&lt;/p&gt;

&lt;p&gt;If you want to know more about R8, there is no better source then &lt;a href="https://jakewharton.com/blog"&gt;the R8 blog series by Jake Wharton&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For some time, there will be an option to switch back to the old build pipeline, but I recommend migrate to R8 as soon as possible.&lt;br&gt;
To switch back, define these flags in &lt;code&gt;gradle.properties&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  android.enableR8.libraries = false  # Switch to the old pipeline for library modules
  android.enableR8 = false            # Switch to the old pipeline for all modules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Compatibility with ProGuard
&lt;/h3&gt;

&lt;p&gt;R8 holds the most of the configuration and feature compatibility with ProGuard by default. There are some configuration elements ignored, mainly for optimizations not supported by R8. The only problem I struggled with was with &lt;em&gt;Gson&lt;/em&gt; library. ProGuard has an implicit support for it that R8 does not have, so you need to add few extra rules if you use Gson in project, in my case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  -keepattributes *Annotation*
  -keep class * implements com.google.gson.TypeAdapterFactory
  -keep class * implements com.google.gson.JsonSerializer
  -keep class * implements com.google.gson.JsonDeserializer
  -keep class com.myapp.**Dto { *; } # this keeps all model classes using Gson in app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Full mode
&lt;/h3&gt;

&lt;p&gt;The compatibility with ProGuard is good for current projects migrating to R8, but if you are starting a new project and want to get more from R8, you can enable the &lt;em&gt;Full Mode&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  android.enableR8.fullMode = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This applies additional optimizations, that can further reduce app size. However, you might need a few extra keep rules to make it work. One such example is &lt;em&gt;Retrofit&lt;/em&gt; library that actually fixed it internally and publish new keep rules with the library. The only thing you need to do is update Retrofit to version 2.6.0 or newer.&lt;/p&gt;

&lt;h1&gt;
  
  
  New lint check dependency configurations (&lt;a href="https://developer.android.com/studio/releases/gradle-plugin#new_features_2"&gt;docs&lt;/a&gt;)
&lt;/h1&gt;

&lt;p&gt;Lint dependency configurations allow you to consume or publish custom Lint rules. This might be interesting for you in two cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your application consumes custom Lint rules defined locally for your project. In the project's &lt;code&gt;build.gradle.kts&lt;/code&gt; a dependency on module with custom Lint rules is defined by &lt;code&gt;lintChecks&lt;/code&gt; configuration (actually this was introduced already in Android Gradle Plugin 3.0).&lt;/li&gt;
&lt;li&gt;Your library publishes custom Lint rules to consumers. In previous versions this was defined by the same &lt;code&gt;lintChecks&lt;/code&gt; configuration, but in Android Gradle Plugin 3.4 there is a new &lt;code&gt;lintPublish&lt;/code&gt; configuration created directly for this purpose. It should allow library authors to use one set of custom Lint rules internally to enhance quality of library code, and publish another set of Lint rules for library consumers to enhance its use in consumer applications.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  dependencies {
    lintChecks project(':lint-private') // Lint rules to be executed on library code
    lintPublish project(':lint-public') // Lint rules to be executed on consumer application code
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Unique Package Names
&lt;/h1&gt;

&lt;p&gt;There is an interesting paragraph in the AGP 3.4 release notes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The correct usage of unique package names is currently not enforced but will become more strict on later versions of the plugin. On Android Gradle plugin version 3.4, you can opt-in to check whether your project declares acceptable package names by adding the line below to your &lt;code&gt;gradle.properties&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;android.uniquePackageNames=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actually, I didn't find any details for this requirement. But having one package name used only in one project module seems a good thing anyway, so why not enabling this check right now and having no migration issues in the future, right?&lt;/p&gt;

&lt;h1&gt;
  
  
  Build Speed Degradation
&lt;/h1&gt;

&lt;p&gt;This is not a feature, rather negative impact observed after migration of few projects to new Android Gradle Plugin version. The build started to be much slower and log was clogged by warnings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Daemon shut down due to memory pressure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason in my case was R8 use more memory than ProGuard and once Gradle Daemon hits the memory limit, Java Garbage Collector has been executed very often, thus the speed degradation.&lt;/p&gt;

&lt;p&gt;The resolution is simple: give Gradle build more Java Heap space. You can configure it in project's &lt;code&gt;gradle.properties&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  org.gradle.jvmargs=-Xmx2g
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is not a good practice to set the new memory limit by guess. Gradle build needs enough memory to run smoothly. But if you set the memory limit too high, it might affect how your computer and operation system runs and more memory may actually lead to slower build times.&lt;/p&gt;

&lt;p&gt;But there is a tool that helps you to find the proper value, &lt;a href="https://scans.gradle.com"&gt;Gradle Build Scan&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With default setting (&lt;code&gt;-Xmx512m&lt;/code&gt;) the build uses all the memory (and probably needs more). Build Scan output:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NlTCulKS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/34wjsypoqz057pt11whw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NlTCulKS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/34wjsypoqz057pt11whw.png" alt="Build Scan output for run with 512m of memory"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With adjusted setting (&lt;code&gt;-Xmx2g&lt;/code&gt;) the build has some memory reserve and runs smoother (and faster). Build Scan output:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hw-7vCN3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0lt3878fdupdzssrm56q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hw-7vCN3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0lt3878fdupdzssrm56q.png" alt="Build Scan output for run with 2g of memory"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On mid-size projects (roughly 200k LoC and 50+ Gradle modules) its fine to set memory limit to 3GB or 4GB.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Thank you for reading and stay tuned for next Android Gradle Plugin release reviews.&lt;/p&gt;

</description>
      <category>gradle</category>
      <category>android</category>
      <category>kotlin</category>
      <category>build</category>
    </item>
    <item>
      <title>What's new in Gradle 5.6 (for mobile developers)</title>
      <dc:creator>Pavel Sveda</dc:creator>
      <pubDate>Sun, 22 Mar 2020 11:10:38 +0000</pubDate>
      <link>https://dev.to/xsveda/what-s-new-in-gradle-5-6-for-mobile-developers-29c1</link>
      <guid>https://dev.to/xsveda/what-s-new-in-gradle-5-6-for-mobile-developers-29c1</guid>
      <description>&lt;p&gt;&lt;a href="https://docs.gradle.org/5.6/release-notes.html"&gt;Gradle 5.6&lt;/a&gt; has been released in August 2019 as the final release for Gradle 5.x and brings a lot of features as a preparation for Gradle 6.0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test fixtures
&lt;/h2&gt;

&lt;p&gt;When you are writing a library module, you structure the code in source sets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Production code is placed to &lt;code&gt;src/main/kotlin&lt;/code&gt; and shared with modules that depend on it.&lt;/li&gt;
&lt;li&gt;Test code is placed to &lt;code&gt;src/test/kotlin&lt;/code&gt; and is not shared anywhere. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The missing piece here is Test Fixtures code. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test Fixtures code is placed to &lt;code&gt;src/testFixtures/kotlin&lt;/code&gt; and shared with any &lt;code&gt;test&lt;/code&gt; source set (&lt;code&gt;src/test/kotlin&lt;/code&gt;) of modules that depend on it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What is it good for? You can share common pieces for writing tests, such as Test Assertions or fake test data to avoid test code duplication as your consuming modules don't need to create them on their own again and again.&lt;/p&gt;

&lt;p&gt;First, I was super excited about this! But when I tested it on real Android project, the feature appeared not compatible with Android Gradle Plugin at all (it works for plain Java projects only).&lt;/p&gt;

&lt;p&gt;Anyway, Android Tooling team has already start working on this (see &lt;a href="https://issuetracker.google.com/issues/139762443"&gt;Issue 139762443&lt;/a&gt; and &lt;a href="https://issuetracker.google.com/issues/139438142"&gt;Issue 139438142&lt;/a&gt;), so 🤞.&lt;/p&gt;

&lt;h2&gt;
  
  
  Central management of plugin versions with settings script (&lt;a href="https://docs.gradle.org/5.6/userguide/plugins.html#sec:plugin_version_management"&gt;docs&lt;/a&gt;)
&lt;/h2&gt;

&lt;p&gt;If you are not using &lt;code&gt;buildSrc&lt;/code&gt; included build to organize the build logic you might end up specifying version of Gradle plugins in &lt;code&gt;plugins {}&lt;/code&gt; block for every module of your project. This approach has few constrains as you are not able to read the version i.e. from &lt;code&gt;gradle.properties&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To address this Gradle 5.6 introduces a new way of specifying plugin version in root &lt;code&gt;settings.gradle.kts&lt;/code&gt; file (also with &lt;code&gt;gradle.properties&lt;/code&gt; support):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    val helloPluginVersion: String by settings // reads value from `gradle.properties`
    pluginManagement {
        plugins {
            id("org.gradle.sample.hello") version "${helloPluginVersion}"
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in the module's &lt;code&gt;build.gradle.kts&lt;/code&gt; file the plugin declaration don't need to specify the version anymore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    plugins {
        id("org.gradle.sample.hello")
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fail the build on deprecation warnings (&lt;a href="https://docs.gradle.org/5.6/release-notes.html#fail-the-build-on-deprecation-warnings"&gt;docs&lt;/a&gt;)
&lt;/h2&gt;

&lt;p&gt;If you want to be 100% build warning free, you can configure Gradle to fail the build for any Gradle deprecation warning. Just add this to &lt;code&gt;gradle.properties&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    org.gradle.warning.mode=fail       # other options are all/summary/none
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Correct handling of file name case on case-insensitive file systems (&lt;a href="https://docs.gradle.org/5.6/release-notes.html#changes-to-file-name-case-on-case-insensitive-file-systems-are-now-handled-correctly"&gt;docs&lt;/a&gt;)
&lt;/h2&gt;

&lt;p&gt;Fixes issues with &lt;code&gt;Copy&lt;/code&gt; and similar Gradle tasks on case-insensitive file systems like NTFS (Windows) or APFS (macOS).&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That's it for Gradle 5.x releases. Please stay tuned for the Gradle 6.0 blog post. 😉&lt;/p&gt;

</description>
      <category>gradle</category>
      <category>android</category>
      <category>kotlin</category>
      <category>build</category>
    </item>
    <item>
      <title>What's new in Gradle 5.2-5.5 (for mobile developers)</title>
      <dc:creator>Pavel Sveda</dc:creator>
      <pubDate>Sun, 22 Mar 2020 10:12:54 +0000</pubDate>
      <link>https://dev.to/xsveda/what-s-new-in-gradle-5-2-5-5-for-mobile-developers-5akc</link>
      <guid>https://dev.to/xsveda/what-s-new-in-gradle-5-2-5-5-for-mobile-developers-5akc</guid>
      <description>&lt;p&gt;On our road through history of Gradle versions and their value to mobile developers we already stop at &lt;a href="https://dev.to/xsveda/what-s-new-in-gradle-5-0-for-mobile-developers-45en"&gt;Gradle 5.0&lt;/a&gt; and &lt;a href="https://dev.to/xsveda/what-s-new-in-gradle-5-1-for-mobile-developers-5ca8"&gt;Gradle 5.1&lt;/a&gt;. &lt;br&gt;
In this post I'd like to summarize minor updates in Gradle 5.2 - Gradle 5.5 versions together as they do not add much to our story individually.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gradle 5.2 (&lt;a href="https://docs.gradle.org/5.2/release-notes.html"&gt;docs&lt;/a&gt;) - February 2019
&lt;/h2&gt;

&lt;p&gt;The only mentionable change is a package of &lt;a href="https://docs.gradle.org/5.2/release-notes.html#annotation-processor-improvements"&gt;Annotation processor improvements&lt;/a&gt; that makes your life together with them a little bit easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gradle 5.3 (&lt;a href="https://docs.gradle.org/5.3/release-notes.html"&gt;docs&lt;/a&gt;) - March 2019
&lt;/h2&gt;

&lt;p&gt;There are two features I'd like to point out, that won't affect your project builds directly, rather being important for the future enhancements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Type-safe accessors in precompiled script plugins (&lt;a href="https://docs.gradle.org/5.3/release-notes.html#type-safe-accessors-in-precompiled-script-plugins"&gt;docs&lt;/a&gt;)
&lt;/h3&gt;

&lt;p&gt;Behind this mouthful set of Gradle specific buzzwords is a technical change that simplifies the way how to structure the build logic.&lt;br&gt;
This topic is a candidate for a blog post on its own, but in short it is about moving all the Gradle build logic pieces out of your &lt;code&gt;build.gradle.kts&lt;/code&gt; files to &lt;code&gt;buildSrc&lt;/code&gt; directory which is a so called "included build" for &lt;em&gt;every&lt;/em&gt; Gradle project. &lt;br&gt;
Till then, Gradle User Guide has a standalone page for this topic called &lt;a href="https://docs.gradle.org/current/userguide/organizing_gradle_projects.html"&gt;"Organizing Gradle Projects"&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gradle Module Metadata 1.0 (&lt;a href="https://docs.gradle.org/5.3/release-notes.html#gradle-module-metadata-1.0"&gt;docs&lt;/a&gt;)
&lt;/h3&gt;

&lt;p&gt;Gradle Module Metadata (GMM) were created as a replacement for Maven &lt;code&gt;pom.xml&lt;/code&gt; files as those are simply not rich enough to solve many dependency management problems.&lt;br&gt;
This is not something that mobile developers will directly work with every day. The main reason I'm excited about this is it allows building Kotlin Multiplatform projects with Gradle. From the &lt;a href="https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html"&gt;docs&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The publications of a multiplatform library may include a special 'root' module that stands for the whole library and is automatically resolved to the appropriate platform-specific artifacts when added as a dependency, as described below.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Gradle will automatically consume published Gradle Metadata, but publications don't include any module metadata by default. To enable it , add &lt;code&gt;enableFeaturePreview("GRADLE_METADATA")&lt;/code&gt; to the root project's &lt;code&gt;settings.gradle.kts&lt;/code&gt; file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gradle 5.4 (&lt;a href="https://docs.gradle.org/5.4/release-notes.html"&gt;docs&lt;/a&gt;) - April 2019
&lt;/h2&gt;

&lt;p&gt;Android developers don't need to care about this release as both &lt;em&gt;Support running Gradle with JDK12&lt;/em&gt; (not much used among Android developers) and &lt;em&gt;Support for Swift 5&lt;/em&gt; (&lt;a href="https://github.com/gradle/native-samples"&gt;samples&lt;/a&gt;) do not really matter to them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gradle 5.5 (&lt;a href="https://docs.gradle.org/5.5/release-notes.html"&gt;docs&lt;/a&gt;) - June 2019
&lt;/h2&gt;

&lt;p&gt;If you work in a large organization that distributes custom Gradle binaries for its internal purposes (yeah, it happens), you can now define the organization-wide &lt;code&gt;gradle.properties&lt;/code&gt; that will configure Gradle environment for everyone who is using such distribution.&lt;br&gt;
This configured properties have the lowest precedence of any &lt;code&gt;gradle.properties&lt;/code&gt; and properties defined in other locations will override values defined here.&lt;/p&gt;

&lt;p&gt;I will cover the Gradle 5.6 version (last release for Gradle 5.x) in the next post.&lt;/p&gt;

</description>
      <category>gradle</category>
      <category>android</category>
      <category>kotlin</category>
      <category>build</category>
    </item>
    <item>
      <title>What's new in Gradle 5.1 (for mobile developers)</title>
      <dc:creator>Pavel Sveda</dc:creator>
      <pubDate>Sun, 22 Mar 2020 09:13:11 +0000</pubDate>
      <link>https://dev.to/xsveda/what-s-new-in-gradle-5-1-for-mobile-developers-5ca8</link>
      <guid>https://dev.to/xsveda/what-s-new-in-gradle-5-1-for-mobile-developers-5ca8</guid>
      <description>&lt;p&gt;&lt;a href="https://docs.gradle.org/5.1/release-notes.html"&gt;Gradle 5.1&lt;/a&gt; came in January 2019 as a first minor update of Gradle 5.0 with few feature updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repository to dependency matching (&lt;a href="https://docs.gradle.org/5.1/release-notes.html#repository-to-dependency-matching"&gt;docs&lt;/a&gt;)
&lt;/h2&gt;

&lt;p&gt;Official documentation states that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is now possible to match repositories to dependencies, so that Gradle doesn't search for a dependency in a repository if it's never going to be found there.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    repositories {
        maven(url = "https://nexus.mycompany.com") {
            content {
                includeGroupByRegex("""com.mycompany.*""")
            }
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, that's nice. You know that your company internal dependencies can't be in any other public repository, so you tell Gradle and it saves some time when searching for them. But not every project have private dependencies in company internal repository.&lt;br&gt;
However this feature has yet another use case. Maybe you read the article &lt;a href="https://blog.autsoft.hu/a-confusing-dependency/"&gt;"A Confusing Dependency"&lt;/a&gt; by Márton Braun about how easy is to populate fake library to &lt;code&gt;jcenter()&lt;/code&gt; repository. When you just do not trust some repository enough to use it in general but you still need it because the library you want is not available anywhere else, you can at least limit the use of such repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    repositories {
        jcenter {
            content {
                includeGroup("org.koin") // Koin is not available anywhere else
            }
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Gradle Kotlin DSL 1.1 (&lt;a href="https://github.com/gradle/kotlin-dsl-samples/releases/tag/v1.1.0"&gt;docs&lt;/a&gt;)
&lt;/h2&gt;

&lt;p&gt;Kotlin DSL 1.1 is a first update of Kotlin DSL feature originally introduced in Gradle 5.0 (you can read more about Kotlin DSL in my &lt;a href="https://dev.to/xsveda/what-s-new-in-gradle-5-0-for-mobile-developers-45en"&gt;previous post&lt;/a&gt;).&lt;br&gt;
The update is mainly focused on polishing the DSL syntax.&lt;br&gt;
We can now use lambdas in the Gradle APIs, we have type-safe accessors for &lt;code&gt;dependencies&lt;/code&gt;, and &lt;code&gt;kotlin-dsl&lt;/code&gt; plugin tasks are now all cacheable which positively affects build speed.&lt;/p&gt;
&lt;h2&gt;
  
  
  Configuration avoidance for Tasks (&lt;a href="https://docs.gradle.org/5.1/release-notes.html#configuration-avoidance-for-tasks"&gt;docs&lt;/a&gt;)
&lt;/h2&gt;

&lt;p&gt;From time to time you need to configure custom Gradle task as part of the build and unfortunately there is not a single way how to do this.&lt;br&gt;
Historically when one defined a new task it has been configured eagerly (&lt;code&gt;create&lt;/code&gt;) with all its dependencies in every build you run. And if you did not call such task during the Gradle run all the time spent on its configuration was wasted.&lt;br&gt;
As a part of Gradle's continuous effort to speed up the build speeds a "Configuration avoidance APIs" were introduced as Preview in Gradle 4.9 and became stable in Gradle 5.1.&lt;br&gt;
It allows us to configure a task in a lazy manner (&lt;code&gt;register&lt;/code&gt;). In fact, you won't configure a &lt;code&gt;Task&lt;/code&gt; this way but just a &lt;code&gt;TaskProvider&lt;/code&gt; that creates a &lt;code&gt;Task&lt;/code&gt; only once it is really needed during a Gradle run.&lt;br&gt;
It might sound complicated but the only thing you need to do is to replace&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   tasks.create("myTask", MyTask) {...}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   tasks.register("myTask", MyTask) {...}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! 🎉🎉🎉&lt;br&gt;
If you are interested in more details, I recommend you to read this &lt;a href="https://blog.gradle.org/preview-avoiding-task-configuration-time"&gt;blog post&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>gradle</category>
      <category>android</category>
      <category>kotlin</category>
      <category>build</category>
    </item>
    <item>
      <title>What's new in Gradle 5.0 (for mobile developers)</title>
      <dc:creator>Pavel Sveda</dc:creator>
      <pubDate>Sun, 22 Mar 2020 09:11:58 +0000</pubDate>
      <link>https://dev.to/xsveda/what-s-new-in-gradle-5-0-for-mobile-developers-45en</link>
      <guid>https://dev.to/xsveda/what-s-new-in-gradle-5-0-for-mobile-developers-45en</guid>
      <description>&lt;p&gt;In this series I'll go through the list of recent Gradle versions and pick the most useful features for the users of Gradle build system (a.k.a. developers), but ignoring updates that target plugin creators and large system admins. The features will be picked in context of a mobile (Android) app project, but most of  it is applicable also to any JVM related or Kotlin Multiplatform projects.&lt;/p&gt;

&lt;p&gt;For the first post in this series we will go back in time to the end of 2018 when &lt;a href="https://docs.gradle.org/5.0/release-notes.html"&gt;Gradle 5.0&lt;/a&gt; has been released. The reason is that Gradle 5.x versions are still very recent, but more important, for the first time in history, Gradle 5.0 comes with an alternative to Groovy for writing configuration scripts -&amp;gt; Kotlin 🎉🎉🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  Gradle Kotlin DSL (&lt;a href="https://docs.gradle.org/current/userguide/kotlin_dsl.html"&gt;docs&lt;/a&gt;)
&lt;/h2&gt;

&lt;p&gt;This is big! Actually, Gradle Kotlin DSL is not just about adding another programming language for writing configuration scripts. Introducing of this feature is actually a game changer for many teams I know to give Gradle a try, and these are the main reasons why:&lt;/p&gt;

&lt;h3&gt;
  
  
  IDE &amp;amp; tooling support
&lt;/h3&gt;

&lt;p&gt;Yes, with Gradle Kotlin DSL the IDE can actually assist you with writing the script, you can use refactoring or read the Gradle API code documentation!!! &lt;br&gt;
Well, to be fair, some of those features were introduced to the top-used IDEs also for Groovy DSL, but those were just few chosen features that were backed directly to the IDEs that not always work well.&lt;br&gt;
With Kotlin it's a different story. Gradle Kotlin scripts (&lt;code&gt;*.gradle.kts&lt;/code&gt; files) are processed on the fly when you write the code so the IDE works in very similar way as when you write your app's code and all the nice stuff we will love just works here.&lt;/p&gt;
&lt;h3&gt;
  
  
  Type safety
&lt;/h3&gt;

&lt;p&gt;No more blindly trying to write some Groovy code and running the Gradle over and over again still failing due to wrong type/method call error. Now you know what plugin class you are dealing with, you can overview its methods, and in case of an error a syntax highlighting will guide immediately.&lt;/p&gt;
&lt;h3&gt;
  
  
  Gradle API polishing
&lt;/h3&gt;

&lt;p&gt;Gradle was built on top of Groovy "magic" features that allows you to use the same syntax for calling properties and functions, shortcuts for working with collections or &lt;code&gt;methodMissing&lt;/code&gt; concept. &lt;br&gt;
But when a thoughts about introducing new language arise it was obvious that it won't be possible without a solid and kind of language "independent" API. Don't take me wrong, Gradle is a JVM tool and always will be (at least in near future), but the new Gradle Java API standardization is kind of "neutral" for these purposes, and helps the Gradle eco-system a lot.&lt;/p&gt;

&lt;p&gt;Gradle Kotlin DSL ain't all ☀️ and 🌈, but it just started with version &lt;code&gt;1.0&lt;/code&gt; and will receive updates in future Gradle versions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Build caching (&lt;a href="https://docs.gradle.org/current/userguide/build_cache.html"&gt;docs&lt;/a&gt;)
&lt;/h2&gt;

&lt;p&gt;Build Cache feature has been introduced already in &lt;a href="https://docs.gradle.org/4.0/release-notes.html"&gt;Gradle 4.0&lt;/a&gt;, but Gradle 5.0 enables it in many more scenarios so it can rapidly speed up your build without not much effort (at least for your local builds).&lt;/p&gt;
&lt;h2&gt;
  
  
  Incremental Java compilation (&lt;a href="https://docs.gradle.org/current/userguide/java_plugin.html#sec:incremental_compile"&gt;docs&lt;/a&gt;)
&lt;/h2&gt;

&lt;p&gt;Stable enough and it Just Works&lt;sup&gt;TM&lt;/sup&gt;!&lt;/p&gt;
&lt;h2&gt;
  
  
  Incremental annotation processing (&lt;a href="https://docs.gradle.org/current/userguide/java_plugin.html#sec:incremental_annotation_processing"&gt;docs&lt;/a&gt;)
&lt;/h2&gt;

&lt;p&gt;Introduces new &lt;code&gt;annotationProcessor&lt;/code&gt; configuration so Gradle can handle Java annotation processors correctly to avoid needless re-compilations. To make it work with Kotlin &lt;code&gt;kapt&lt;/code&gt; annotation processors you need to use &lt;a href="https://kotlinlang.org/docs/reference/kapt.html#incremental-annotation-processing-since-1330"&gt;Kotlin &lt;code&gt;1.3.30&lt;/code&gt; or newer&lt;/a&gt;. But don't forget that this feature must be first supported by &lt;a href="https://docs.gradle.org/5.0/userguide/java_plugin.html#making_an_annotation_processor_incremental"&gt;annotation processor plugin itself&lt;/a&gt;.&lt;br&gt;
Please read &lt;a href="https://dev.to/xsveda/what-s-new-in-android-gradle-plugin-3-5-157k"&gt;What's new in Android Gradle Plugin 3.5&lt;/a&gt; post for more information about the history and proper configuration of incremental annotation processing with Java and Kotlin.&lt;/p&gt;
&lt;h2&gt;
  
  
  BOM support (&lt;a href="https://docs.gradle.org/5.0/userguide/managing_transitive_dependencies.html#sec:bom_import"&gt;docs&lt;/a&gt;)
&lt;/h2&gt;

&lt;p&gt;Gradle 5.0 introduces a notion of a platform that is used for consuming Maven BOM files. This helps with introducing libraries like Firebase Android SDK where one need to be careful about selecting right components with compatible versions. With BOM support you can replace&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies {
  implementation("com.google.firebase:firebase-analytics:17.2.2")
  implementation("com.google.firebase:firebase-auth:19.2.0")
  implementation("com.google.firebase:firebase-firestore:21.3.1")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies {
  implementation(platform("com.google.firebase:firebase-bom:24.5.0"))
  implementation("com.google.firebase:firebase-analytics")
  implementation("com.google.firebase:firebase-auth")
  implementation("com.google.firebase:firebase-firestore")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Periodic Gradle cache cleanup (&lt;a href="https://docs.gradle.org/5.0/userguide/directory_layout.html#dir:gradle_user_home:cache_cleanup"&gt;docs&lt;/a&gt;)
&lt;/h2&gt;

&lt;p&gt;Gradle binaries and project dependency artifacts in Gradle cache are checked every day and removed if not used for last 30 days. Neat!&lt;/p&gt;

&lt;p&gt;And that's it! Stay tuned for the next posts por this series.&lt;/p&gt;

</description>
      <category>gradle</category>
      <category>android</category>
      <category>kotlin</category>
      <category>build</category>
    </item>
  </channel>
</rss>
