<?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>Forem: Nate Ebel</title>
    <description>The latest articles on Forem by Nate Ebel (@n8ebel).</description>
    <link>https://forem.com/n8ebel</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%2F37741%2F688ee0a3-90cf-48e7-aafe-c73467acca31.png</url>
      <title>Forem: Nate Ebel</title>
      <link>https://forem.com/n8ebel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/n8ebel"/>
    <language>en</language>
    <item>
      <title>Kotlin vs Java for Android Development FAQ</title>
      <dc:creator>Nate Ebel</dc:creator>
      <pubDate>Mon, 26 Apr 2021 12:00:00 +0000</pubDate>
      <link>https://forem.com/goobar_dev/kotlin-vs-java-for-android-development-faq-254i</link>
      <guid>https://forem.com/goobar_dev/kotlin-vs-java-for-android-development-faq-254i</guid>
      <description>&lt;p&gt;Kotlin vs Java? Which language is best for Android development in 2021?&lt;/p&gt;

&lt;p&gt;New Android developers want to know which language they should learn for building modern Android applications. Development teams want to be sure that Kotlin will not have a negative impact on their app’s performance, their ability to hire qualified engineers, or on their overall developer productivity.&lt;/p&gt;

&lt;p&gt;To help inform your decisions, we’ve curated a list of some of the most frequently asked questions regarding Kotlin vs Java for Android development.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions About Kotlin vs Java for Android Development
&lt;/h2&gt;



&lt;p&gt;&lt;strong&gt;Which is better for Android development – Java or Kotlin?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Kotlin is the &lt;a href="https://developer.android.com/kotlin/first#why"&gt;preferred language for Android development&lt;/a&gt; in 2021.  Both Java and Kotlin can be used to build performant, useful applications, but Google’s libraries, tooling, documentation, and learning resources continue to embrace a Kotlin-first approach; making it the better language for Android today.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does Google recommend Kotlin for Android development?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Yes.  &lt;a href="https://developer.android.com/kotlin/first"&gt;Google recommends developers start building Android applications with Kotlin&lt;/a&gt;, and has taken an increasingly Kotlin-first approach to modern Android development.  Many Android Jetpack libraries have been either written completely in Kotlin, or support Kotlin language features such as coroutines.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When did Google start supporting Kotlin for Android?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Google announced official Android support for Kotlin at &lt;a href="https://youtu.be/EtQ8Le8-zyo?t=660"&gt;Google I/O in 2017&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When did Android become Kotlin-first?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Google adopted their current Kotlin-first approach to Android at &lt;a href="https://youtu.be/LoLqSbV1ELU?t=530"&gt;Google I/O in 2019&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Java still used for Android development?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Yes.  Absolutely.  Java is still 100% supported by Google for Android development.  The majority of Android apps today have some mix of both Java and Kotlin code.  Developers can build the same functionality with Java as they can with Kotlin.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will Android stop supporting Java?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;It’s unlikely that Android will stop supporting Java any time soon.  The Android SDK is still mostly written in Java.  The majority of Android apps still include Java.  The Android OS is built upon a Java Virtual Machine.  To move away from Java completely would represent a monumental shift in the Android ecosystem.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Kotlin replacing Java?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;No.  Java will not be replaced completely by Kotlin.  Java will likely continue to lose some marketshare to Kotlin within the Android ecosystem, but Java will remain one of the most used programming languages in the world.   &lt;/p&gt;

&lt;p&gt;While Java for Android continues to be constrained to Java version 8, beyond Android, Java is evolving quickly and adopting many features from other modern programming languages; including Kotlin.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Kotlin enough for Android development?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Yes.  You can build Android applications using only Kotlin, and as documentation, tooling, and libraries become more Kotlin-focused, building apps exclusively with Kotlin will become even easier.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should I learn Java or Kotlin for Android?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;You should learn Kotlin first.  If you have to pick between learning Java or Kotlin to start developing Android apps, you will have an easier time using current tools and learning resources if you know Kotlin.  &lt;/p&gt;

&lt;p&gt;If you already know Java, and want to focus on learning Android, then you could defer learning Kotlin in favor of focusing on the Android SDK.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I learn Kotlin without Knowing Java?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Yes.  While knowing Java, or any programming language, will make it easier, Kotlin is a great first language thanks to things like static typing, type inference, and abundance of learning resources, and strong IDE support.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Kotlin easier than Java?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Many will find Kotlin easier to learn and write than Java.  A number of things factor into this experience including Kotlin’s concise syntax, type inference, explicit nullability, and extensive standard library.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I get a job as an Android developer without knowing Kotlin?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Yes, but Kotlin is becoming an increasingly desirable skill for hiring managers looking for qualified developers. A LinkedIn search for “kotlin android developer” jobs turns up &lt;a href="https://www.linkedin.com/jobs/search/?geoId=103644278&amp;amp;keywords=kotlin%20android%20developer&amp;amp;location=United%20States"&gt;~7,700 job postings&lt;/a&gt; while a search for “java android developer” returns &lt;a href="https://www.linkedin.com/jobs/search/?geoId=103644278&amp;amp;keywords=java%20android%20developer&amp;amp;location=United%20States"&gt;~7,800 results in the US&lt;/a&gt;. The relative number of postings is similaraly balanced in India with ~11,100 results &lt;a href="http://java%20android%20developer"&gt;for “java android developer”&lt;/a&gt; and ~11,000 &lt;a href="https://www.linkedin.com/jobs/search/?geoId=102713980&amp;amp;keywords=kotlin%20android%20developer&amp;amp;location=India"&gt;for “kotlin android developer.&lt;/a&gt;“  &lt;/p&gt;

&lt;p&gt;As codebases, teams, libraries, and Google continue to move more towards Kotlin, expect Kotlin to become an even more important skillset for Android developer jobs.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Kotlin faster than Java?&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;No; although the true answer depends on what performance metrics you are interested in.  At runtime, the performance of the languages is very similar.  At compile time however, &lt;a href="https://eng.uber.com/measuring-kotlin-build-performance/"&gt;Kotlin is measurably slower than Java&lt;/a&gt;.  The extent of the slowdown depends on a number of factors such as the usage of annotation processors, and the presence of mixed Java + Kotlin source sets&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Can You Learn More About Kotlin and Android Development?
&lt;/h2&gt;

&lt;p&gt;Check out our other posts on &lt;a href="https://goobar.dev/tag/kotlin/"&gt;Kotlin&lt;/a&gt; and &lt;a href="https://goobar.dev/tag/android/"&gt;Android&lt;/a&gt; development here on goobar.&lt;/p&gt;

&lt;p&gt;And you can find courses and tutorials on our &lt;a href="https://www.youtube.com/channel/UCVysWoMPvvHQMEJvRkslbAQ"&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://goobar.dev/kotlin-vs-java-for-android-development-faq/"&gt;Kotlin vs Java for Android Development&lt;/a&gt; appeared first on &lt;a href="https://goobar.dev"&gt;goobar&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>java</category>
    </item>
    <item>
      <title>Non-Coding Tips for Coding Interview Assignments</title>
      <dc:creator>Nate Ebel</dc:creator>
      <pubDate>Tue, 20 Apr 2021 01:04:51 +0000</pubDate>
      <link>https://forem.com/goobar_dev/non-coding-tips-for-coding-interview-assignments-31j1</link>
      <guid>https://forem.com/goobar_dev/non-coding-tips-for-coding-interview-assignments-31j1</guid>
      <description>&lt;p&gt;Unsurprisingly, when discussing take-home assignments for coding interviews, much of the focus is put on code.  Can you code?  Are you using “best practices?”  What tools are you using?.  There’s lots of code-related things that people think about, or even stress about.&lt;/p&gt;

&lt;p&gt;Unfortunately, non-coding tips for coding interview assignments don’t get talked about nearly as much. And, in my experience, there are a &lt;em&gt;lot&lt;/em&gt; of non-coding things we can do to put our best foot forward and impress a hiring committee with our take-home assignment.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Telling Your Story
&lt;/h2&gt;

&lt;p&gt;What are these non-coding tips? If we’re completing a programming assignment, what else should we pay attention to?&lt;/p&gt;

&lt;p&gt;Put yourself in the mindset of a reviewing engineer. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How will they experience your project?
&lt;/li&gt;
&lt;li&gt;How can you guide their experience?
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How can you tell your story?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What do you want a reviewer to know about you after they review your code?&lt;/li&gt;
&lt;li&gt;What interests, skillsets, workflows, or values do you want to highlight?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We want to help a reviewer get to know us – to understand what we can do. We want to think about giving reviewers reasons to be impressed by our projects and we want to do our best to limit head scratching moments.&lt;/p&gt;

&lt;p&gt;Take-home assignments provide a unique opportunity to tell these stories because they are done asynchronously. During a take-home assignment, engineers are not typically under the watchful gaze of the hiring committee. We have a chance to be more natural; to think more clearly; and to take greater ownership of the impression we make.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Make a good first impression
&lt;/h2&gt;

&lt;p&gt;Take-home assignments, as with many things, can really benefit from a positive first impression. If a reviewer starts exploring your assignment on a positive note, the rest of the review is likely to go better.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Project Metadata To Give Additional Context
&lt;/h3&gt;

&lt;p&gt;If your project is using GitHub, git, or some other form of version control, then you have a great opportunity to showcase project information through various forms of “metadata” available to you.&lt;/p&gt;

&lt;p&gt;If using git, your git history is a great way to highlight how you work.&lt;/p&gt;

&lt;p&gt;If your project lives in GitHub, add relevant attribution. Give it a useful description. Add relevant topcis such as “android” or “kotlin” to give a quick overview of what the project is about. You might leverage GitHub Issues, PRs, and Milestones to give reviewers a sense of how you like to work and manage your tasks.&lt;/p&gt;

&lt;p&gt;What can you add to your project to give helpful context to a reviewer? Don’t spend a lot of time here, but often a little bit of investment here can help give your project a more professional look.&lt;/p&gt;

&lt;h3&gt;
  
  
  Highlighting Information Using A Project README
&lt;/h3&gt;

&lt;p&gt;Having a helpful project README in the root directory of your assignment submission is a terrific idea. A README the perfect place to document assumptions, outline your tasks, or add screenshots or video of the project.&lt;/p&gt;

&lt;p&gt;Imagine yourself sitting down to present your project to a reviewer. Where would you start? What information would you want to highlight right away? Think of your README as this overview.&lt;/p&gt;

&lt;p&gt;Use the README to guide the efforts of a reviewer. Call out interesting functionality. Call out tools and libraries that were used.&lt;/p&gt;

&lt;p&gt;Use it to tell your story; whatever that may be.&lt;/p&gt;

&lt;h3&gt;
  
  
  Guiding Reviewers With Clear Project Organization
&lt;/h3&gt;

&lt;p&gt;The last item to a great first impression is clear project organization. In most cases, I suggest you organize your project by “feature”, or by “layer”. You want your reviewer to be able to navigate your project easily.&lt;/p&gt;

&lt;p&gt;You also want to demonstrate that your organization would scale to real-world, production projects. Putting all your files in a single directory might work for a small take-home assignment, but wouldn’t be a great choice for a large application.&lt;/p&gt;

&lt;p&gt;Not sure if your project will be easy to navigate? Try navigating the project without your IDE. You might explore the project in GitHub or from your file browser. If it’s easy to navigate without an IDE’s search and class-lookup functions, then you should be good to go.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  First Time User Experience
&lt;/h2&gt;

&lt;p&gt;At some point, a reviewer is most likely going to run your code. What will that first-time-user experience be? A focus on two main things can really have a large impact on how a reviewer feels about your project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ensuring A Functional Experience
&lt;/h3&gt;

&lt;p&gt;Make sure your app doesn’t crash when a reviewer installs it. You don’t want your app to crash at all, but it’s especially important that it doesn’t crash on startup. A crash on startup means a reviewer may not be able to evaluate the functionality – this does not usually lead to a great assignment review.&lt;/p&gt;

&lt;p&gt;If you have the time, test your app startup across a few different device configurations. Maybe 2-3 different OS versions, and a couple of different screen sizes. If your app starts up, and is functional, across these configurations there’s a good chance your assignment reviewers will also be able to successfully start using your app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Impressing With UI Polish
&lt;/h3&gt;

&lt;p&gt;Once your app is started, what is the first thing a reviewer sees? If your main screen leaves a positive first impression, it can go a long way towards creating a positive feeling towards the project as a whole.&lt;/p&gt;

&lt;p&gt;How can you leave a good impression? A little bit of design polish goes a long way. A few design items that are not time consuming, but really help the look/feel of your app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A unique, visually appealing, color palette. 

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://material.io/resources/color/#!/?view.left=0&amp;amp;view.right=0"&gt;The Material Design Color Tools is a great resource for this&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Consistent spacing

&lt;ul&gt;
&lt;li&gt;Using the &lt;a href="https://material.io/design/layout/spacing-methods.html#baseline-grid"&gt;Material Design 8dp grid&lt;/a&gt; is a great way to go&lt;/li&gt;
&lt;li&gt;Define a couple of dimension resources and use them throughout your layouts for a more professional look&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Touch feedback

&lt;ul&gt;
&lt;li&gt;Add a ripple effect when touching views is a nice UI addition&lt;/li&gt;
&lt;li&gt;This &lt;a href="https://guides.codepath.com/android/ripple-animation"&gt;can be accomplished with very little effort&lt;/a&gt; and again goes a long way towards a more professional look&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Don’t reinvent the wheel

&lt;ul&gt;
&lt;li&gt;If you’re not sure how to structure the UI/Navigation in your app, look to existing apps for inspiration&lt;/li&gt;
&lt;li&gt;If your “weather app” assignment behaves like an existing app, it’ll likely make it easier to use for a reviewer, and that can often lead to a better overview impression&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Adaptive design

&lt;ul&gt;
&lt;li&gt;Ideally, your app’s UI would adapt to different screen sizes/configurations&lt;/li&gt;
&lt;li&gt;If your app doesn’t work well on small screens, or in horizontal layouts, call that out in your README or elsewhere.

&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What does your code say about you?
&lt;/h2&gt;

&lt;p&gt;The way in which you write your code, whether it’s functional or not, can say a lot about how you operate as an engineer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Leveraging Consistency To Improve The Review Experience
&lt;/h3&gt;

&lt;p&gt;A big part of being a professional software developer is reviewing code. Code is easier to read and review if it uses consistent styling and conventions. This is true whether in a produciton codebase, or a take-home assignment.&lt;/p&gt;

&lt;p&gt;Before you submit you project, run a code formatter on the code to ensure you are using a consistent style.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building On A Solid Foundation
&lt;/h3&gt;

&lt;p&gt;It’s great to highlight fancy libraries, or to build flashy features into your project. However, if they come at the expense of the fundamentals, they might actually hurt you more than help.&lt;/p&gt;

&lt;p&gt;For example, if building an Android app, it’s considered best practice to define user-facing strings as String resources in a &lt;em&gt;strings.xml&lt;/em&gt; file. Hardcoding all of your strings might be a red flag to reviewers.&lt;/p&gt;

&lt;p&gt;If your project requires special permissions, and you don’t build a permissions workflow into the app, it could reflect poorly on your submission. Or if you place all of your code into a single, large class – it might reflect poorly on your submission.&lt;/p&gt;

&lt;p&gt;The moral here is that well organize, well structured code that doesn’t miss on the basics is likely going to be better off than a project that uses the “new shiny” library but is built on a shaky foundation.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation
&lt;/h2&gt;

&lt;p&gt;Software developers often joke about their lack of documentation, or argue about whether good code even needs documentation. However, in an interview situation, good documentation is without a doubt a helpful tool.&lt;/p&gt;

&lt;p&gt;Take home assignments are often about tradeoffs. You usually have a set number of tasks to complete with a limited amount of time in which to carry out the assignment. Tradeoffs must be made to balance completing the assignment with writing our ideal solutions.&lt;/p&gt;

&lt;p&gt;Use documentation to detail those tradeoffs and to simulate the discussions that would come up during a typical work situation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documenting Your Decision Making
&lt;/h3&gt;

&lt;p&gt;What assumptions did you make about the specified requirements? What questions did you have, and how did you answer them?&lt;/p&gt;

&lt;p&gt;Why did you choose &lt;em&gt;Library X&lt;/em&gt; over &lt;em&gt;Library Y&lt;/em&gt;? Why did you choose &lt;em&gt;Architecture A&lt;/em&gt; rather than &lt;em&gt;Architecture B&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;All of these types of decisions are opportunities do document and share your thinking.&lt;/p&gt;

&lt;p&gt;You can go further than that as well. You could include more narrative documentation about areas you chose to focus on, and why? Why did you add unit tests? Why did you add a CI workflow? How did you come up with your custom color palette? These are all interesting notes that you can document and share with reviewer to give a sense of how you work.&lt;/p&gt;

&lt;p&gt;And lastly, be sure to document anything that isn’t work – or isn’t working as specified.&lt;/p&gt;

&lt;p&gt;Was your weather app supposed to show precipitation, but the api you chose only offers that data if you pay? Document that limitation so its absence doesn’t seem like an oversight.&lt;/p&gt;

&lt;p&gt;Does your app crash when rotated? Call that out in the notes so it’s clear that you found and understand the issue. You might even get bonus points for including a suggested fix.&lt;/p&gt;

&lt;p&gt;With most reviewers, you’re not going to lose points for transparency. Being upfront about what is, and isn’t, working builds trust – and trust is a very important part of choosing to work with someone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choosing Documentation Formats
&lt;/h3&gt;

&lt;p&gt;Your documentation can come in a variety of forms. You might find that a mix of documentation formats is ideal for you, or you might focus on one above the rest. While I do highly suggest having a README, choose the documentation option(s) that work best for you.&lt;/p&gt;

&lt;p&gt;A few documentation examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A README in your project’s root directory&lt;/li&gt;
&lt;li&gt;Code comments&lt;/li&gt;
&lt;li&gt;GitHub Issues, Pull Requests, Milestones&lt;/li&gt;
&lt;li&gt;A wiki in your repository&lt;/li&gt;
&lt;li&gt;&lt;a href="https://adr.github.io/"&gt;Architectural Decision Records&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A recorded video of you walking through the project

&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Make It Your Own
&lt;/h2&gt;

&lt;p&gt;Take-home assignments typically have a concrete set of requirements; usually a set of tasks to complete and specific functionally that must be present. That doesn’t mean that those tasks are the &lt;em&gt;only&lt;/em&gt; things we can work on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Telling Your Story By Customizing Your Submission
&lt;/h3&gt;

&lt;p&gt;As mentioned earlier in this post, think about the story you want to tell to a reviewer. What do you enjoy working on? What is your “genius zone?” And how can you highlight those things in your submission?&lt;/p&gt;

&lt;p&gt;Do you enjoy working with CI infrastructure? You could setup a simple CI workflow for your project and maybe include a small writeup on your preferred CI architecture.&lt;/p&gt;

&lt;p&gt;Maybe you really enjoy bringing to life beautiful designs? You could add a unique animation or user interaction. A custom loading indicator or “empty state” screen are great opportunities for this.&lt;/p&gt;

&lt;p&gt;Do you really believe in Test Driven Development? Write some tests for the project and include a summary of your testing philosophy.&lt;/p&gt;

&lt;p&gt;These additions don’t have to be massive time investments, and honestly they probably shouldn’t be because we need to make sure the core functionality is there. But, an additional feature, test, or other custom element can be a really valuable way to highlight how you would be a uniquely valuable asset to any team.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Leveraging Non-Coding Tips For Your Next Coding Interview Assignment
&lt;/h2&gt;

&lt;p&gt;Next time you have a coding interview assignment, don’t forget about these non-coding tips. Remember to put your best foot forward by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Making a positive first impression&lt;/li&gt;
&lt;li&gt;Ensuring a stable and pleasing first-time-user experience&lt;/li&gt;
&lt;li&gt;Writing consistent, readable code&lt;/li&gt;
&lt;li&gt;Documenting your code and decision making process&lt;/li&gt;
&lt;li&gt;Making the project your own&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you can do these things, and complete the required assignment tasks, you will have gone a long ways towards helping yourself get that next job!&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where To Learn More?
&lt;/h2&gt;

&lt;p&gt;Watch on &lt;a href="https://youtu.be/LqlfiuczRzI"&gt;our YouTube channel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://goobar.dev/non-coding-tips-for-coding-interview-assignments/"&gt;Non-Coding Tips for Coding Interview Assignments&lt;/a&gt; appeared first on &lt;a href="https://goobar.dev"&gt;goobar&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>career</category>
      <category>interview</category>
    </item>
    <item>
      <title>Free Up System Resources For Faster Gradle Builds</title>
      <dc:creator>Nate Ebel</dc:creator>
      <pubDate>Tue, 09 Mar 2021 15:34:28 +0000</pubDate>
      <link>https://forem.com/n8ebel/free-up-system-resources-for-faster-gradle-builds-278g</link>
      <guid>https://forem.com/n8ebel/free-up-system-resources-for-faster-gradle-builds-278g</guid>
      <description>&lt;p&gt;Are your Android Gradle builds ever slower than you expect? Sometimes even painfully slow?&lt;/p&gt;

&lt;p&gt;I think most Android devs have felt this at one point or another, and many engineers spend countless hours optimizing Gradle builds to improve the productivity of mobile dev teams.&lt;/p&gt;

&lt;p&gt;Unfortunately, sometimes, even a well-optimized Gradle build can be slow.  Even &lt;em&gt;really&lt;/em&gt; slow at times.&lt;/p&gt;

&lt;p&gt;This was the case for our team recently.  &lt;/p&gt;

&lt;p&gt;We’ve invested a lot of time and effort into getting our Gradle builds under control; making them faster and more efficient across the team.  And yet, over the past couple of weeks, we had noticed a frustrating trend of extremely slow builds for one of our devs.&lt;/p&gt;

&lt;p&gt;According to our Gradle Enterprise data, some of their local builds were taking 5-15x longer than expected.  This was far beyond our typical range of expected build times.&lt;/p&gt;

&lt;p&gt;Obviously, something abnormal was happening here, but what?&lt;/p&gt;

&lt;p&gt;Thankfully, between Gradle Enterprise build scan insights, and good old-fashioned pair-debugging, we were able to get a good sense of what was causing these extremely slow builds and take steps to rectify the situation.&lt;/p&gt;

&lt;p&gt;I’m going to walk through some of our thinking and process in this post, but the moral of the story is this:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If your system is taxed BEFORE your Gradle build even starts, your build is likely going to be slow&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Understanding What’s Working And What Isn’t?
&lt;/h1&gt;

&lt;p&gt;How did we start investigating the cause of these slow downs?&lt;/p&gt;

&lt;p&gt;As with most build speed issues, we started by investigating some of our build optimizations&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Was local caching turned off for any of these builds?&lt;/li&gt;
&lt;li&gt;Was remote caching turned off for any of these builds?&lt;/li&gt;
&lt;li&gt;Were we suffering from negative cache savings when accessing the remote build cache?&lt;/li&gt;
&lt;li&gt;Are we experiencing a high number of cache misses?&lt;/li&gt;
&lt;li&gt;Were there extremely large change sets being built?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How we answered these questions is a post for another time.  The short story is that we used Gradle Enterprise to explore the buildscan details for specific builds.&lt;/p&gt;

&lt;p&gt;What matters here is that our build speed optimizations were generally working how we expected.  And when comparing the execution of the same Gradle task across different developers’ machines, we continued to see a very large discrepancy in the execution time.&lt;/p&gt;

&lt;p&gt;This hinted that there was something going on specifically with this machine, rather that with the project as a whole.&lt;/p&gt;

&lt;p&gt;To help further rule out anything specific to the code or the build configuration, we tried one final test.&lt;/p&gt;

&lt;p&gt;We ran &lt;code&gt;./gradlew help&lt;/code&gt; on two machines&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On my dev machine which was building as expected&lt;/li&gt;
&lt;li&gt;On the machine seeing the slowest of local build times&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What we found was surprising, but helped highlight the possible issue.&lt;/p&gt;

&lt;p&gt;Running the &lt;code&gt;help&lt;/code&gt; task on one machine took ~1-3 seconds while on the affected machine it took over 2 minutes.&lt;/p&gt;

&lt;p&gt;Clearly something was wrong here.  &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;help&lt;/code&gt; task helps us highlight only the configuration time of a Gradle project.  If configuration alone is so bogged down that it’s taking minutes to complete, then maybe something is off in the environment itself, rather than with our build at large.&lt;/p&gt;

&lt;h1&gt;
  
  
  Examining System Configuration
&lt;/h1&gt;

&lt;p&gt;If Gradle build optimizations were behaving as expected, only slower, then perhaps it was differences in the machines themselves.&lt;/p&gt;

&lt;p&gt;To start digging into the development machine itself, we started by taking a look at the system’s CPU and available memory.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;i5 processor&lt;/li&gt;
&lt;li&gt;16GB memory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These specs immediately helped us understand that we couldn’t directly compare the build times from the affected machine and some of the other laptops on our team.  We have a mix of devices.  Some very similar to this i5/16GB configuration, while others are more similar to an i7/32GB configuration.&lt;/p&gt;

&lt;p&gt;A lower spec’d machine would account for some increase in build times, but not to the extent we were seeing with as much as a 15x increase, and certainly wouldn’t explain why the &lt;code&gt;help&lt;/code&gt; task took over 2min to finish.  &lt;/p&gt;

&lt;p&gt;So, we then went deeper; to look more closely at how the available resources were actually being used.&lt;/p&gt;

&lt;h1&gt;
  
  
  Examining System Resource Pressure
&lt;/h1&gt;

&lt;p&gt;Running an Android Gradle build can be a taxing process; asking a lot from both system memory and from available CPUs.&lt;/p&gt;

&lt;p&gt;If there are a lack of available system resources, perhaps the builds are being negatively impacted.&lt;/p&gt;

&lt;p&gt;To check the status of the system, we opened up the MacOS Activity Monitor.  We wanted to check two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Idle CPU %&lt;/li&gt;
&lt;li&gt;Memory Used&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The results of this stuck out like a sore thumb.&lt;/p&gt;

&lt;p&gt;Without Android Studio or a Gradle build running we saw the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;15% idle CPU (Meaning 85% usage)&lt;/li&gt;
&lt;li&gt;25% available memory (12GB used out of 16GB total)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As soon as we opened Android Studio on the affected machine, we saw further large spikes in CPU and memory to the point where the machine started to lock up across the board; bringing everything to a halt.&lt;/p&gt;

&lt;p&gt;We had found our culprit.&lt;/p&gt;

&lt;p&gt;The combination of Android Studio, Android Virtual Devices, video calls, and endless browser tabs was severely taxing this laptop’s system resources.  Add in an Android Gradle build and suddenly CPU and Memory were maxed out, causing things to come to a screeching halt. &lt;/p&gt;

&lt;h1&gt;
  
  
  Freeing Up System Resources
&lt;/h1&gt;

&lt;p&gt;Thankfully, this hypothesis was pretty easy test and remedy.  We used Activity Monitor to examine what was taking up CPU/Memory and tried to close the most taxing processes.&lt;/p&gt;

&lt;p&gt;CPU&lt;/p&gt;

&lt;p&gt;On the CPU front, a few things stuck out to us&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pretty consistently high usage from the browser; likely coming from the video call we were on&lt;/li&gt;
&lt;li&gt;several unknown processes that looked to be taking up a &lt;em&gt;lot&lt;/em&gt; of CPU.  At least 2 of these were known issues on MacOS&lt;/li&gt;
&lt;li&gt;an Android emulator running in the background that wasn’t taking up a &lt;em&gt;lot&lt;/em&gt; but still requiring some consistent CPU usage&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Memory&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;It was a bit easier to understand where the system memory was being allocated.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the web browser was taking up a large chunk of memory; likely due to a high number of tabs open and an active video call&lt;/li&gt;
&lt;li&gt;an Android emulator running in the background taking up ~3GB of memory&lt;/li&gt;
&lt;li&gt;Slack, and additional apps running in the background&lt;/li&gt;
&lt;li&gt;when opened, Android Studio consumed ~4GB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After closing out of numerous tabs and programs, changing web browsers, closing the Android emulator, and closing Android Studio, we re-ran the &lt;code&gt;help&lt;/code&gt; task from the command line.&lt;/p&gt;

&lt;p&gt;This time, the task completed in a few seconds as we would expect.&lt;/p&gt;

&lt;p&gt;For a more comprehensive test, we ran our default build task again, and were again happy to see that build times were much closer to our expected baseline performance.&lt;/p&gt;

&lt;h1&gt;
  
  
  Recommendations For Keeping Your Build Fast
&lt;/h1&gt;

&lt;p&gt;The moral of this story is that our Android builds are going to be painfully slow if our systems do not have enough cpu and memory resources available.&lt;/p&gt;

&lt;p&gt;So, if you’re experiencing unusually slow builds, you might try some of the following before cursing Gradle and the Android build system.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;change to a less resource web browser&lt;/li&gt;
&lt;li&gt;avoid building your app while on a video call&lt;/li&gt;
&lt;li&gt;use a physical device for testing to avoid the use of an emulator&lt;/li&gt;
&lt;li&gt;build your app without Android Studio being open&lt;/li&gt;
&lt;li&gt;build your app without any other taxing programs being open&lt;/li&gt;
&lt;li&gt;adjust Gradle’s JVM memory settings to something that isn’t likely to consume all your available memory&lt;/li&gt;
&lt;li&gt;keep your machine well cooled to avoid thermal throttling of your CPU&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And last, but certainly not least, try to get a more powerful development machine if you can.&lt;/p&gt;

&lt;p&gt;If you’re in a position of leadership/influence in your team, and you see a coworker dealing with slow builds simply because they have an underpowered machine, I encourage you to put together a developer efficiency business argument for getting them a faster machine.  &lt;/p&gt;

&lt;p&gt;A couple of thousands of dollars for a new laptop is likely going to be cheaper and faster than trying to shave another couple of minutes off your already optimized Gradle build.&lt;/p&gt;

&lt;h1&gt;
  
  
  Wrapping Up
&lt;/h1&gt;

&lt;p&gt;Hopefully this will help those out there that are maybe scratching their heads as to why their well-optimized builds are still building so slowly; or intermittently slowly.&lt;/p&gt;

&lt;p&gt;With so many more video calls, more documents being passed around, and a lack of access to physical testing devices, it’s maybe not surprising if we are over-taxing our laptops and slowing down our builds.&lt;/p&gt;




&lt;p&gt;The post &lt;a href="https://goobar.io/free-up-system-resources-for-faster-gradle-builds/"&gt;Free Up System Resources For Faster Gradle Builds&lt;/a&gt; appeared first on &lt;a href="https://goobar.io"&gt;goobar&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>android</category>
      <category>gradle</category>
    </item>
    <item>
      <title>Benchmarking Gradle Builds Using Gradle-Profiler</title>
      <dc:creator>Nate Ebel</dc:creator>
      <pubDate>Thu, 12 Nov 2020 17:38:59 +0000</pubDate>
      <link>https://forem.com/goobar_dev/benchmarking-gradle-builds-using-gradle-profiler-2pf8</link>
      <guid>https://forem.com/goobar_dev/benchmarking-gradle-builds-using-gradle-profiler-2pf8</guid>
      <description>&lt;p&gt;In this post, we’re going to take an introductory look at benchmarking Gradle build performance using the gradle-profiler tool.  &lt;/p&gt;

&lt;p&gt;By the end, you should have a basic understanding of how to use gradle-profiler to gain better insights into the performance of your Gradle build and how you might use those insights to improve Gradle build performance for your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Gradle-Profiler Tool?
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/gradle/gradle-profiler"&gt;gradle-profiler&lt;/a&gt; project describes itself in the following way:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A tool to automate the gathering of profiling and benchmarking information for Gradle builds.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What does that mean to you and your project?&lt;/p&gt;

&lt;p&gt;Imagine you want to get a sense of how fast your Gradle build is.&lt;/p&gt;

&lt;p&gt;You might run your target Gradle task, wait for the build to complete, and take that build time as your result.&lt;/p&gt;

&lt;p&gt;Now, because build times are often variable, you may want to run your Gradle task multiple times and average the execution times.  So, you kick off your build, wait for it to finish, write down the total execution time, and repeat the process.  &lt;/p&gt;

&lt;p&gt;This process of manually benchmarking your Gradle build will likely take a while.  Depending on how long your build takes to complete, and how many interactions you want to run, you could find yourself repeatedly coming back to your computer to check whether it’s time to start the next build or not.  Even if you stay busy with other things, this is still a drawn out, tedious process that relies on you, as the developer, manually recording build statistics for each iteration.&lt;/p&gt;

&lt;p&gt;It’s this process that gradle-profiler aims to automate for you.&lt;/p&gt;

&lt;p&gt;Rather than you having to manually kick off each build and recording the resulting build statistics, gradle-profiler allows devs to start a single command which will repeatedly run a specified Gradle task and record all the build stats in an easy to examine output format.&lt;/p&gt;

&lt;p&gt;This takes Gradle build benchmarking from a tedious, manual task to something that can be highly automated with little need for human interaction or monitoring.&lt;/p&gt;

&lt;p&gt;I’ve been using gradle-profiler recently in an effort to keep my primary project’s build times low, and to examine the build impact of proposed changes.  In this post, we’re going to walk through how you can start using gradle-profiler to gather benchmark data for your Gradle build, and how you may start using that data to understand the impact of changes on your project. &lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Gradle-Profiler
&lt;/h2&gt;

&lt;p&gt;Before you can start benchmarking Gradle build performance, you’ll need to install gradle-profiler to your development machine.&lt;/p&gt;

&lt;p&gt;You can do this in one of several ways&lt;/p&gt;

&lt;h3&gt;
  
  
  Install From Source
&lt;/h3&gt;

&lt;p&gt;You could clone the git repository to your local machine, and &lt;a href="https://github.com/gradle/gradle-profiler#build-from-source"&gt;build the project from source&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ git clone git@github.com:gradle/gradle-profiler.git
→ cd gradle-profiler
→ ./gradlew installDist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You would likely then want to add &lt;em&gt;&lt;code&gt;gradle-profiler/build/install/gradle-profiler/bin&lt;/code&gt;&lt;/em&gt; to your path or create some kind of alias that enables you to invoke the tool by executing the &lt;em&gt;gradle-profiler&lt;/em&gt; command.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install With Homebrew
&lt;/h3&gt;

&lt;p&gt;If you are using &lt;a href="https://brew.sh/"&gt;Homebrew&lt;/a&gt; on your machine, installation is quite simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ brew install gradle-profiler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Other Installation Options
&lt;/h3&gt;

&lt;p&gt;If building from source, or installing using Homebrew, aren’t good options for you, you could try either of the following installation methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/gradle/gradle-profiler#sdkman"&gt;Installing using SDKMAN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gradle/gradle-profiler#download-binaries"&gt;Downloading binaries directly from GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Examples On GitHub&lt;/h3&gt;

&lt;p&gt;You can find example commands and example benchmark scenarios in my sample repo on GitHub.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/n8ebel/Gradle-Profiler-Sandbox" rel="noopener noreferrer"&gt;&lt;span&gt;&lt;span&gt;Find The Code&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmarking Your Gradle Build
&lt;/h2&gt;

&lt;p&gt;Now that gradle-profiler is installed, and the &lt;em&gt;gradle-profiler&lt;/em&gt; command is available to us, let’s start benchmarking Gradle build performance for your project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running the Benchmarking Tool
&lt;/h3&gt;

&lt;p&gt;To generate benchmarking results for our project, we need two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The path to the project directory containing the Gradle project&lt;/li&gt;
&lt;li&gt;A Gradle task to run&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With these, we can start benchmarking our build like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ cd &amp;lt;project directory&amp;gt;→ gradle-profiler --benchmark --project-dir . assemble
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s break down this command into its individual parts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;&lt;code&gt;gradle-profiler&lt;/code&gt;&lt;/em&gt; – invokes the gradle-profiler tool&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;code&gt;--benchmark&lt;/code&gt;&lt;/em&gt; – indicates that we want to benchmark our build&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;code&gt;--project-dir .&lt;/code&gt;&lt;/em&gt; – indicates that the Gradle project is located within the current working directory&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;code&gt;assemble&lt;/code&gt;&lt;/em&gt; – this is the Gradle task to benchmark &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When this command is run, the benchmarking tool will begin.  You should see output in your console indicating that &lt;em&gt;warm-up&lt;/em&gt; and &lt;em&gt;measured&lt;/em&gt; builds are running.&lt;/p&gt;

&lt;p&gt;When all the builds are completed, two benchmarking artifacts should be created for you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;&lt;code&gt;benchmark.csv&lt;/code&gt;&lt;/em&gt; – provides benchmarking data in a simple .csv format&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;&lt;code&gt;benchmark.html&lt;/code&gt;&lt;/em&gt; – provides an interactive webpage report based on the .csv data&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The output paths should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Results written to /Users/n8ebel/Projects/GradleProfilerSandbox/profile-out
/Users/n8ebel/Projects/GradleProfilerSandbox/profile-out/benchmark.csv
/Users/n8ebel/Projects/GradleProfilerSandbox/profile-out/benchmark.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Understanding Benchmarking Results
&lt;/h3&gt;

&lt;p&gt;Once your outputs are generated, you can use them to explore the benchmarking results.&lt;/p&gt;

&lt;h4&gt;
  
  
  Interpreting .csv results
&lt;/h4&gt;

&lt;p&gt;Here’s a sample &lt;em&gt;&lt;code&gt;benchmark.csv&lt;/code&gt;&lt;/em&gt; output generated by benchmarking the &lt;em&gt;assemble&lt;/em&gt; task for a new Android Studio project.&lt;/p&gt;

&lt;p&gt;| &lt;strong&gt;scenario&lt;/strong&gt; | &lt;strong&gt;default&lt;/strong&gt; |&lt;br&gt;
| &lt;strong&gt;version&lt;/strong&gt; | Gradle 6.7 |&lt;br&gt;
| &lt;strong&gt;tasks&lt;/strong&gt; | assemble |&lt;br&gt;
| &lt;strong&gt;value&lt;/strong&gt; | execution |&lt;br&gt;
| &lt;strong&gt;warm-up build #1&lt;/strong&gt; | 45574 |&lt;br&gt;
| &lt;strong&gt;warm-up build #2&lt;/strong&gt; | 2149 |&lt;br&gt;
| &lt;strong&gt;warm-up build #3&lt;/strong&gt; | 1778 |&lt;br&gt;
| &lt;strong&gt;warm-up build #4&lt;/strong&gt; | 1772 |&lt;br&gt;
| &lt;strong&gt;warm-up build #5&lt;/strong&gt; | 1436 |&lt;br&gt;
| &lt;strong&gt;warm-up build #6&lt;/strong&gt; | 1474 |&lt;br&gt;
| &lt;strong&gt;measured build #1&lt;/strong&gt; | 1247 |&lt;br&gt;
| &lt;strong&gt;measured build #2&lt;/strong&gt; | 1370 |&lt;br&gt;
| &lt;strong&gt;measured build #3&lt;/strong&gt; | 1267 |&lt;br&gt;
| &lt;strong&gt;measured build #4&lt;/strong&gt; | 1217 |&lt;br&gt;
| &lt;strong&gt;measured build #5&lt;/strong&gt; | 1305 |&lt;br&gt;
| &lt;strong&gt;measured build #6&lt;/strong&gt; | 1103 |&lt;br&gt;
| &lt;strong&gt;measured build #7&lt;/strong&gt; | 973 |&lt;br&gt;
| &lt;strong&gt;measured build #8&lt;/strong&gt; | 1007 |&lt;br&gt;
| &lt;strong&gt;measured build #9&lt;/strong&gt; | 999 |&lt;br&gt;
| &lt;strong&gt;measured build #10&lt;/strong&gt; | 1151 |&lt;/p&gt;
CSV benchmark results for &lt;em&gt;assemble&lt;/em&gt; task



&lt;p&gt;This report is very streamlined and highlights only a few things.  The most interesting data points are likely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which version of Gradle was used&lt;/li&gt;
&lt;li&gt;Which Gradle tasks were run&lt;/li&gt;
&lt;li&gt;The task execution time, in milliseconds, for the &lt;em&gt;warm-up&lt;/em&gt; and &lt;em&gt;measured&lt;/em&gt; builds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notice that the first &lt;em&gt;warm-up&lt;/em&gt; build took significantly longer than every other build?  Is this a problem?  Is something wrong with your project’s configuration?&lt;/p&gt;

&lt;p&gt;By default, &lt;em&gt;gradle-profiler&lt;/em&gt; uses a warm Gradle daemon when measuring build times.  If you’re not familiar, the &lt;a href="https://docs.gradle.org/current/userguide/gradle_daemon.html"&gt;Gradle daemon&lt;/a&gt; runs in the background to avoid repeatedly paying JVM startup costs.  It can drastically improve the performance of your Gradle builds.&lt;/p&gt;

&lt;p&gt;So, for this first &lt;em&gt;warm-up&lt;/em&gt; build, task execution time is much longer as the daemon is started.  After that, you can see that subsequent builds are much faster.&lt;/p&gt;

&lt;p&gt;If we ignore the &lt;em&gt;warm-up&lt;/em&gt; builds, and look only at the set of &lt;em&gt;measured&lt;/em&gt; builds, we see that the build times are consistently fast as one might expect for a new project.  &lt;/p&gt;
&lt;h4&gt;
  
  
  Interpreting HTML results
&lt;/h4&gt;

&lt;p&gt;In addition to being an interactive webpage, the &lt;em&gt;&lt;code&gt;benchmarking.html&lt;/code&gt;&lt;/em&gt; results provide more data than the .csv file.  By viewing the results this way, you’ll have access to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mean, Median, StdDev, and other statistics from the &lt;em&gt;measured&lt;/em&gt; build results&lt;/li&gt;
&lt;li&gt;Gradle argument details&lt;/li&gt;
&lt;li&gt;JVM argument details&lt;/li&gt;
&lt;li&gt;And more…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q-IqKTTA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/goobar.io/wp-content/uploads/2020/11/Screen-Shot-2020-11-12-at-7.28.28-AM-1329778080-1605209269815.png%3Fresize%3D800%252C562%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q-IqKTTA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/goobar.io/wp-content/uploads/2020/11/Screen-Shot-2020-11-12-at-7.28.28-AM-1329778080-1605209269815.png%3Fresize%3D800%252C562%26ssl%3D1" alt="gradle-profiler HTML benchmarking results for a single assemble task"&gt;&lt;/a&gt;HTML benchmark results for &lt;em&gt;assemble&lt;/em&gt; task&lt;/p&gt;

&lt;p&gt;The HTML results provide a graph of each &lt;em&gt;warm-up&lt;/em&gt; and &lt;em&gt;measured&lt;/em&gt; build to help you visually understand performance over time.&lt;/p&gt;

&lt;p&gt;If you aren’t interested in automating the analysis of your benchmarking results, then viewing the HTML results is often the most convenient way to quickly understand how long your build takes, and to quickly see if there are any outlier executions to examine.&lt;/p&gt;

&lt;p&gt;This HTML view becomes even more useful when benchmarking multiple scenarios at the same time as we’ll see later on.&lt;/p&gt;
&lt;h2&gt;
  
  
  Detecting Gradle Performance Issues
&lt;/h2&gt;

&lt;p&gt;Now that we have some understanding of the output generated by gradle-profiler benchmarking, let’s explore how we might begin to use that benchmark data to compare the performance of our Gradle builds.&lt;/p&gt;

&lt;p&gt;The simplest approach is generally as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Collect benchmarking data for your current/default Gradle configuration&lt;/li&gt;
&lt;li&gt;Change your Gradle configuration&lt;/li&gt;
&lt;li&gt;Collect benchmarking data for updated configuration&lt;/li&gt;
&lt;li&gt;Compare the results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We could use this approach to compare the impact of caching on a build.  We might compare the performance of clean builds versus incremental builds. &lt;/p&gt;

&lt;p&gt;Any tweak to our build settings or project structure could be examined through this type of comparison.&lt;/p&gt;
&lt;h3&gt;
  
  
  Comparing &lt;em&gt;clean&lt;/em&gt; and &lt;em&gt;up-to-date&lt;/em&gt; build performance
&lt;/h3&gt;

&lt;p&gt;Let’s walk through a quick example of this kind of analysis using &lt;em&gt;gradle-profiler.&lt;/em&gt;  We’re going to compare the impact of an &lt;em&gt;up-to-date&lt;/em&gt; build over a &lt;em&gt;clean&lt;/em&gt; build.&lt;/p&gt;

&lt;p&gt;First we’ll benchmark &lt;em&gt;up-to-date&lt;/em&gt; builds of our &lt;em&gt;assemble&lt;/em&gt; task and collect the results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ gradle-profiler --benchmark --project-dir . assemble
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’re referring this as the &lt;em&gt;up-to-date&lt;/em&gt; scenario because after the first execution of the &lt;em&gt;assmble&lt;/em&gt; task, each task should be up-to-date and subsequent builds should be extremely fast as there is nothing to rebuild.&lt;/p&gt;

&lt;p&gt;Next, we’ll benchmark our &lt;em&gt;clean&lt;/em&gt; build.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ gradle-profiler --benchmark --project-dir . clean assemble
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;em&gt;clean&lt;/em&gt; build scenario, we are discarded previous outputs before executing our &lt;em&gt;assemble&lt;/em&gt; task, so we should expect the &lt;em&gt;clean&lt;/em&gt; build to take longer than the &lt;em&gt;up-to-date&lt;/em&gt; build.&lt;/p&gt;

&lt;p&gt;Once we’ve generated both sets of output, we can compare the benchmarked performance. I’ve taken the .csv results from each of those benchmarking executions and combined them into the following table for comparison.&lt;/p&gt;

&lt;p&gt;| &lt;strong&gt;scenario&lt;/strong&gt; | &lt;strong&gt;default&lt;/strong&gt; | &lt;strong&gt;scenario&lt;/strong&gt; | &lt;strong&gt;default&lt;/strong&gt; |&lt;br&gt;
| &lt;strong&gt;version&lt;/strong&gt; | Gradle 6.7 | version | Gradle 6.7 |&lt;br&gt;
| &lt;strong&gt;tasks&lt;/strong&gt; | assemble | tasks | clean assemble |&lt;br&gt;
| &lt;strong&gt;value&lt;/strong&gt; | execution | value | execution |&lt;br&gt;
| &lt;strong&gt;warm-up build #1&lt;/strong&gt; | 14330 | warm-up build #1 | 26492 |&lt;br&gt;
| &lt;strong&gt;warm-up build #2&lt;/strong&gt; | 1887 | warm-up build #2 | 10345 |&lt;br&gt;
| &lt;strong&gt;warm-up build #3&lt;/strong&gt; | 1546 | warm-up build #3 | 9853 |&lt;br&gt;
| &lt;strong&gt;warm-up build #4&lt;/strong&gt; | 1440 | warm-up build #4 | 8757 |&lt;br&gt;
| &lt;strong&gt;warm-up build #5&lt;/strong&gt; | 1383 | warm-up build #5 | 8705 |&lt;br&gt;
| &lt;strong&gt;warm-up build #6&lt;/strong&gt; | 1301 | warm-up build #6 | 7377 |&lt;br&gt;
| &lt;strong&gt;measured build #1&lt;/strong&gt; | 1187 | measured build #1 | 7268 |&lt;br&gt;
| &lt;strong&gt;measured build #2&lt;/strong&gt; | 1230 | measured build #2 | 7378 |&lt;br&gt;
| &lt;strong&gt;measured build #3&lt;/strong&gt; | 1118 | measured build #3 | 7750 |&lt;br&gt;
| &lt;strong&gt;measured build #4&lt;/strong&gt; | 1104 | measured build #4 | 6707 |&lt;br&gt;
| &lt;strong&gt;measured build #5&lt;/strong&gt; | 1105 | measured build #5 | 6635 |&lt;br&gt;
| &lt;strong&gt;measured build #6&lt;/strong&gt; | 1082 | measured build #6 | 7542 |&lt;br&gt;
| &lt;strong&gt;measured build #7&lt;/strong&gt; | 1044 | measured build #7 | 7066 |&lt;br&gt;
| &lt;strong&gt;measured build #8&lt;/strong&gt; | 990 | measured build #8 | 6398 |&lt;br&gt;
| &lt;strong&gt;measured build #9&lt;/strong&gt; | 993 | measured build #9 | 6341 |&lt;br&gt;
| &lt;strong&gt;measured build #10&lt;/strong&gt; | 1037 | measured build #10 | 7416 |&lt;/p&gt;

&lt;p&gt;With this, we can see that our &lt;em&gt;up-to-date&lt;/em&gt; build takes ~1 second while our &lt;em&gt;clean&lt;/em&gt; build is taking ~7 seconds. This seems in line with expectations about the relative performance of these two build types.&lt;/p&gt;
&lt;h3&gt;
  
  
  Comparing caching impact
&lt;/h3&gt;

&lt;p&gt;We’ve seen the performance of an &lt;em&gt;up-to-date&lt;/em&gt; build.  We’ve seen the impact of doing a &lt;em&gt;clean&lt;/em&gt; build. &lt;/p&gt;

&lt;p&gt;Let’s expand on our example by now benchmarking the impact of enabling &lt;a href="https://docs.gradle.org/current/userguide/build_cache.html#sec:build_cache_enable"&gt;Gradle’s local build cache&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, we’ll once again benchmark a &lt;em&gt;clean&lt;/em&gt; build without enabling the build cache.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ gradle-profiler --benchmark --project-dir . clean assemble
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we’ll enable Gradle’s local build cache by adding the following to our &lt;em&gt;&lt;code&gt;gradle.properties&lt;/code&gt;&lt;/em&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.caching_=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can re-run our &lt;em&gt;clean&lt;/em&gt; build benchmark scenario; this time with the cache enabled.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ gradle-profiler --benchmark --project-dir . clean assemble
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once again, we can compare results to get a sense of how enabling the local Gradle build cache can benefit build performance.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;No Caching&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Caching&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;scenario&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;default&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;scenario&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;default&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;version&lt;/td&gt;
&lt;td&gt;Gradle 6.7&lt;/td&gt;
&lt;td&gt;version&lt;/td&gt;
&lt;td&gt;Gradle 6.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tasks&lt;/td&gt;
&lt;td&gt;clean assemble&lt;/td&gt;
&lt;td&gt;tasks&lt;/td&gt;
&lt;td&gt;clean assemble&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;value&lt;/td&gt;
&lt;td&gt;execution&lt;/td&gt;
&lt;td&gt;value&lt;/td&gt;
&lt;td&gt;execution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;warm-up build #1&lt;/td&gt;
&lt;td&gt;26492&lt;/td&gt;
&lt;td&gt;warm-up build #1&lt;/td&gt;
&lt;td&gt;24568&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;warm-up build #2&lt;/td&gt;
&lt;td&gt;10345&lt;/td&gt;
&lt;td&gt;warm-up build #2&lt;/td&gt;
&lt;td&gt;6838&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;warm-up build #3&lt;/td&gt;
&lt;td&gt;9853&lt;/td&gt;
&lt;td&gt;warm-up build #3&lt;/td&gt;
&lt;td&gt;4901&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;warm-up build #4&lt;/td&gt;
&lt;td&gt;8757&lt;/td&gt;
&lt;td&gt;warm-up build #4&lt;/td&gt;
&lt;td&gt;5145&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;warm-up build #5&lt;/td&gt;
&lt;td&gt;8705&lt;/td&gt;
&lt;td&gt;warm-up build #5&lt;/td&gt;
&lt;td&gt;4382&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;warm-up build #6&lt;/td&gt;
&lt;td&gt;7377&lt;/td&gt;
&lt;td&gt;warm-up build #6&lt;/td&gt;
&lt;td&gt;5309&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;measured build #1&lt;/td&gt;
&lt;td&gt;7268&lt;/td&gt;
&lt;td&gt;measured build #1&lt;/td&gt;
&lt;td&gt;4825&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;measured build #2&lt;/td&gt;
&lt;td&gt;7378&lt;/td&gt;
&lt;td&gt;measured build #2&lt;/td&gt;
&lt;td&gt;4674&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;measured build #3&lt;/td&gt;
&lt;td&gt;7750&lt;/td&gt;
&lt;td&gt;measured build #3&lt;/td&gt;
&lt;td&gt;4428&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;measured build #4&lt;/td&gt;
&lt;td&gt;6707&lt;/td&gt;
&lt;td&gt;measured build #4&lt;/td&gt;
&lt;td&gt;4577&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;measured build #5&lt;/td&gt;
&lt;td&gt;6635&lt;/td&gt;
&lt;td&gt;measured build #5&lt;/td&gt;
&lt;td&gt;4053&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;measured build #6&lt;/td&gt;
&lt;td&gt;7542&lt;/td&gt;
&lt;td&gt;measured build #6&lt;/td&gt;
&lt;td&gt;4236&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;measured build #7&lt;/td&gt;
&lt;td&gt;7066&lt;/td&gt;
&lt;td&gt;measured build #7&lt;/td&gt;
&lt;td&gt;4388&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;measured build #8&lt;/td&gt;
&lt;td&gt;6398&lt;/td&gt;
&lt;td&gt;measured build #8&lt;/td&gt;
&lt;td&gt;4131&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;measured build #9&lt;/td&gt;
&lt;td&gt;6341&lt;/td&gt;
&lt;td&gt;measured build #9&lt;/td&gt;
&lt;td&gt;5818&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;measured build #10&lt;/td&gt;
&lt;td&gt;7416&lt;/td&gt;
&lt;td&gt;measured build #10&lt;/td&gt;
&lt;td&gt;4016&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
Merged CSV results comparing the build speed impact of enabling the Gradle build cache



&lt;p&gt;From these results, we see that enabling local caching seems to improve the performance of &lt;em&gt;clean&lt;/em&gt; builds from ~7 seconds to ~4.5 seconds.&lt;/p&gt;

&lt;p&gt;Now, these build times are artificially fast as it’s a simple project.&lt;/p&gt;

&lt;p&gt;However, this approach is applicable to your real-world projects, and these general results are what one might expect from a well-configured project; &lt;code&gt;up-to-date&lt;/code&gt; &amp;lt; &lt;code&gt;clean with caching&lt;/code&gt; &amp;lt; &lt;code&gt;clean w/out caching&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Benchmarking Behavior
&lt;/h2&gt;

&lt;p&gt;When running these benchmarking tasks, you may find yourself wanting greater control over how benchmarking is carried out.  A few of the common configuration properties you may find yourself needing to change include&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;changing the project directory&lt;/li&gt;
&lt;li&gt;modifying the output directory&lt;/li&gt;
&lt;li&gt;updating the number of build iterations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’re going to quickly examine how you can update these properties when executing your benchmarking task.&lt;/p&gt;

&lt;h3&gt;
  
  
  Changing Project Directory
&lt;/h3&gt;

&lt;p&gt;Throughout these examples, we’ve been operating as if we are running &lt;em&gt;gradle-profiler&lt;/em&gt; from within the project directory.  &lt;/p&gt;

&lt;p&gt;Here, we see that after the &lt;em&gt;&lt;code&gt;--project-dir&lt;/code&gt;&lt;/em&gt; flag, we pass &lt;code&gt;.&lt;/code&gt; to signify the current directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ gradle-profiler --benchmark --project-dir . assemble
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want to run &lt;em&gt;gradle-profiler&lt;/em&gt; from any other directory, we are free to do that.  We just need to update the path to the project directory.&lt;/p&gt;

&lt;p&gt;In this updated example, we change directories into our user directory, and pass &lt;code&gt;Projects/GradleProfilerSandbox&lt;/code&gt; as the path to our project directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ cd
→ gradle-profiler --benchmark --project-dir Projects/GradleProfilerSandbox/ clean assemble
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Changing Output Directory
&lt;/h3&gt;

&lt;p&gt;When &lt;em&gt;gradle-profiler&lt;/em&gt; is run, by default, it will store output artifacts in the current directory.  If you would prefer to specify a different output directory, you can do so using &lt;em&gt;&lt;code&gt;--output-dir&lt;/code&gt;&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;gradle-profiler --benchmark --project-dir Projects/GradleProfilerSandbox/ --output-dir Projects/benchmarking/ clean assemble
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This may come in handy if you want to automate the running of benchmarking tasks and would like to keep all your outputs collected within a specific working directory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Controlling Build Warm-Ups and Iterations
&lt;/h3&gt;

&lt;p&gt;Another pair of useful configuration options are &lt;em&gt;&lt;code&gt;--warmups&lt;/code&gt;&lt;/em&gt; and &lt;em&gt;&lt;code&gt;--iterations&lt;/code&gt;&lt;/em&gt;.  These two flags allow you to control how many &lt;em&gt;warm-up&lt;/em&gt; builds and &lt;em&gt;measured&lt;/em&gt; builds to run.&lt;/p&gt;

&lt;p&gt;This might be useful to you if you want to receive your results more quickly, or if you want more data points, and hopefully greater confidence, if your benchmarking results.&lt;/p&gt;

&lt;p&gt;If we wanted to have 10 &lt;em&gt;warm-up&lt;/em&gt; builds and &lt;em&gt;15&lt;/em&gt; measured builds, we can start our benchmarking task like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ gradle-profiler --benchmark --project-dir . --warmups 10 --iterations 15 assemble
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Benchmarking Complex Gradle Builds
&lt;/h2&gt;

&lt;p&gt;We’ve really only scratched the surface of what gradle-profiler is capable of.  Real world build scenarios are varied, and often quite complex.  Ideally, we’d be able to capture these complexities, and benchmark Gradle build performance for these real-world conditions.&lt;/p&gt;

&lt;p&gt;Let’s take a look at how we can define benchmark scenarios that give greater control and flexibility into what is benchmarked.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining a Benchmark Scenario
&lt;/h3&gt;

&lt;p&gt;As our command line inputs become more complex, it may become difficult to manage. &lt;/p&gt;

&lt;p&gt;Look at the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gradle-profiler --benchmark --project-dir Projects/GradleProfilerSandbox/ --output-dir Projects/benchmarking/ --warmups10 --iterations 15 clean assemble
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command is still executing a fairly simple benchmarking task, but has already become quite long and unwieldily to execute from the command line every time.&lt;/p&gt;

&lt;p&gt;This is especially true if we want to start benchmarking multiple build types, or want to simulate complex incremental build changes.&lt;/p&gt;

&lt;p&gt;To help define complex build scenarios, the &lt;em&gt;gradle-profiler&lt;/em&gt; tool provides a mechanism for encapsulating all of the configuration for a build scenario into a &lt;em&gt;&lt;code&gt;.scenarios&lt;/code&gt;&lt;/em&gt; file.  This helps us organize our scenarios in a single place and makes it easier to benchmarking multiple scenarios.&lt;/p&gt;

&lt;p&gt;To define a simple &lt;em&gt;&lt;code&gt;.scenarios&lt;/code&gt;&lt;/em&gt; file, we’ll do the following.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, we’ll create a new file named &lt;em&gt;&lt;code&gt;benchmarking.scenarios&lt;/code&gt;&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Next, we’ll define a scenario for our &lt;em&gt;up-to-date&lt;/em&gt; &lt;em&gt;assemble&lt;/em&gt; task.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;assemble_no_op {
  tasks = ["assemble"]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this small configuration block, we’ve defined a scenario named &lt;code&gt;assemble_no_op&lt;/code&gt; that will run the &lt;code&gt;assemble&lt;/code&gt; task when executed. We’ve used the “no op” suffix on the scenario name because this will test our &lt;em&gt;up-to-date&lt;/em&gt; build in which tasks shouldn’t have to be re-run each time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benchmarking With a Scenarios File
&lt;/h3&gt;

&lt;p&gt;With our scenario file defined, we can benchmark this scenario by using the &lt;em&gt;&lt;code&gt;--scenario-file&lt;/code&gt;&lt;/em&gt; flag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gradle-profiler --benchmark --project-dir . --scenario-file benchmarking.scenarios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From this, we get an HTML output similar to this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mtNISvRz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/goobar.io/wp-content/uploads/2020/11/assemble_no_op.png%3Fresize%3D800%252C336%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mtNISvRz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/goobar.io/wp-content/uploads/2020/11/assemble_no_op.png%3Fresize%3D800%252C336%26ssl%3D1" alt="HTML benchmark results"&gt;&lt;/a&gt;HTML output from running the assemble_no_op benchmark scenario&lt;/p&gt;

&lt;p&gt;We can see that the &lt;em&gt;assemble_no_op&lt;/em&gt; name used to define our scenario is automatically used as the scenario name in the output.&lt;/p&gt;

&lt;p&gt;In the next sections, we’ll see how to changes this to something more human-readable and why this can be important.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuring Build Scenarios
&lt;/h3&gt;

&lt;p&gt;Within our &lt;em&gt;&lt;code&gt;.scenarios&lt;/code&gt;&lt;/em&gt; file, there are quite a few configuration options we can use to control our benchmarked scenarios.&lt;/p&gt;

&lt;p&gt;We can provide a human-readable title for our scenario:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;assemble_no_op {
  title = "Up-To-Date Assemble"
  tasks = ["assemble"]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can provide multiple Gradle tasks to run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;assemble_clean {
  title = "Clean Assemble"
  tasks = ["clean", "assemble"]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could pass in different Gradle build flags such as for parallel execution or for the build cache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;assemble_clean {
  title = "Clean Assemble"
  tasks = ["clean", "assemble"]
  gradle-args = ["--parallel"]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also explicitly define the number of &lt;em&gt;warm-ups&lt;/em&gt; and &lt;em&gt;iterations&lt;/em&gt; so they don’t have to be passed from the command line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;assemble_clean {
  title = "Clean Assemble"
  tasks = ["clean", "assemble"]
  gradle-args = ["--parallel"]
  warm-ups = 3
  iterations = 5
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not an exhaustive list of scenario configurations.  You can find more examples in the &lt;em&gt;gradle-profiler&lt;/em&gt; &lt;a href="https://github.com/gradle/gradle-profiler#advanced-profiling-scenarios"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benchmarking Multiple Build Scenarios
&lt;/h3&gt;

&lt;p&gt;One of the primary benefits of using a &lt;code&gt;.scenarios&lt;/code&gt; file is that we can define multiple scenarios within a single file, and benchmark multiple scenarios at the same time.&lt;/p&gt;

&lt;p&gt;For example, we could compare our &lt;em&gt;up-to-date, clean, clean w/caching&lt;/em&gt; builds from a single benchmarking execution, and receive a single set of output reports comparing all of them.&lt;/p&gt;

&lt;p&gt;To do this, we first define each of our unique build scenarios within our &lt;code&gt;benchmarking.scenarios&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;assemble_clean {
  title = "Clean Assemble"
  tasks = ["clean", "assemble"]
}

assemble_clean_caching {
  title = "Clean Assemble w/ Caching"
  tasks = ["clean", "assemble"]
  gradle-args = ["--build-cache"]
}

assemble_no_op {
  title = "Up-To-Date Assemble"
  tasks = ["assemble"]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we continue to invoke &lt;em&gt;gradle-profiler&lt;/em&gt; in the same way; by specifying the single &lt;em&gt;&lt;code&gt;.scenarios&lt;/code&gt;&lt;/em&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;gradle-profiler --benchmark --project-dir . --scenario-file benchmarking.scenarios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From this, we will receive a merge report that compares the performance of each scenario.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GFV0z9OE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/goobar.io/wp-content/uploads/2020/11/multiple_scenarios_no_baseline.png%3Fresize%3D800%252C395%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GFV0z9OE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/goobar.io/wp-content/uploads/2020/11/multiple_scenarios_no_baseline.png%3Fresize%3D800%252C395%26ssl%3D1" alt="HTML gradle-profiler output for multiple build scenarios"&gt;&lt;/a&gt;HTML output for multiple build scenarios&lt;/p&gt;

&lt;p&gt;Scenarios will be run in alphabetical order based on the name used in the scenario definition; not the human-readable title.  &lt;/p&gt;

&lt;p&gt;When viewing a report with multiple scenarios, you can select a scenario as the &lt;em&gt;baseline&lt;/em&gt;.  This will update the report to display a +/-% on each build metric where the +/-% is the statistical difference between the current scenario and the baseline scenario.&lt;/p&gt;

&lt;p&gt;What does that look like in practice?&lt;/p&gt;

&lt;p&gt;In this example, we’ve selected the &lt;em&gt;clean build w/out caching&lt;/em&gt; scenario as our baseline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--htQBZVmE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/goobar.io/wp-content/uploads/2020/11/multiple_scenarios_with_baseline.png%3Fresize%3D800%252C427%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--htQBZVmE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/goobar.io/wp-content/uploads/2020/11/multiple_scenarios_with_baseline.png%3Fresize%3D800%252C427%26ssl%3D1" alt="HTML gradle-profiler output for multiple scenarios with a selected baseline"&gt;&lt;/a&gt;HTML output for multiple build scenarios with a selected baseline&lt;/p&gt;

&lt;p&gt;With the baseline set, we see that the mean build time was reduced ~4% for the &lt;em&gt;clean build with caching&lt;/em&gt; scenario and ~80% for the &lt;em&gt;up-to-date&lt;/em&gt; build scenario.&lt;/p&gt;

&lt;p&gt;By setting a baseline, you let the tool do all the statistical analysis for you leaving you free to interpret and share the results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmarking Incremental Gradle Builds
&lt;/h2&gt;

&lt;p&gt;The last concept we’re going to touch on is that of benchmarking incremental builds.  These are builds in which we need to re-execute a subset of tasks because of file changes.  These files could change due to source file changes, resource updates, etc.&lt;/p&gt;

&lt;p&gt;Incremental scenarios can be very important for real-world benchmarking of Gradle build performance, because in our day-to-day work, we’re often performing incremental builds as we make a small code change, and redeploy for testing.&lt;/p&gt;

&lt;p&gt;When using &lt;em&gt;gradle-profiler&lt;/em&gt; we have &lt;a href="https://github.com/gradle/gradle-profiler#profiling-incremental-builds"&gt;quite a few options available&lt;/a&gt; to us for defining and benchmarking incremental build scenarios.&lt;/p&gt;

&lt;p&gt;If building with Kotlin or Java, we might be interested in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;apply-abi-change-to&lt;/li&gt;
&lt;li&gt;apply-non-abi-change-to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If building an Android application, we might use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;apply-android-resource-change-to&lt;/li&gt;
&lt;li&gt;apply-android-resource-value-change-to&lt;/li&gt;
&lt;li&gt;apply-android-manifest-change-to&lt;/li&gt;
&lt;li&gt;apply-android-layout-change-to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these options, and others, we can simulate different types of changes to our projects to benchmark real world scenarios.&lt;/p&gt;

&lt;p&gt;Here, we’ve defined a new incremental scenario in our &lt;em&gt;benchmarking.scenarios&lt;/em&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;incremental_build {
  title = "Incremental Assemble w/ Caching"
  tasks = ["assemble"]

  apply-abi-change-to = "app/src/main/java/com/goobar/gradleprofilersandbox/MainActivity.kt"
  apply-android-resource-change-to = "app/src/main/res/values/strings.xml"
  apply-android-resource-value-change-to = "app/src/main/res/values/strings.xml"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This scenario will measure the impact of changing one Kotlin file, and of adding and modifying string resource values.&lt;/p&gt;

&lt;p&gt;The resulting benchmark results look something like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WX2dqMDe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/goobar.io/wp-content/uploads/2020/11/incremental.png%3Fresize%3D800%252C474%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WX2dqMDe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/goobar.io/wp-content/uploads/2020/11/incremental.png%3Fresize%3D800%252C474%26ssl%3D1" alt="HTML benchmark results from gradler-profiler displaying build times for 4 different build scenarios. The chart shows that an up-to-date build is the fastest of the 4 build types."&gt;&lt;/a&gt;HTML benchmark results including incremental build scenario&lt;/p&gt;

&lt;p&gt;As expected, the incremental build was measured to be faster than a &lt;em&gt;clean&lt;/em&gt; build, but slower than an &lt;em&gt;up-to-date&lt;/em&gt; build.&lt;/p&gt;

&lt;p&gt;This is a very simple example.  For your production project, you might define multiple different incremental build scenarios. &lt;/p&gt;

&lt;p&gt;If you’re working in a multi-module project, you might want to measure the incremental build impact of changing a single module versus multiple modules.  You might want to measure the impact of changing a public api versus changing implementation details of a module.  There are many things you may want to measure in order to improve the real world performance of your build.  &lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;At this point, hopefully you have a better understanding of benchmarking Gradle build performance using gradle-profiler, and how to start using gradle-profiler to improve the performance of your Gradle builds.&lt;/p&gt;

&lt;p&gt;There’s still more that can be done with gradle-profiler to make it more effective for detecting build regressions and to make it easier to use for everyone on your team. &lt;/p&gt;

&lt;p&gt;I’ll be exploring those ideas in upcoming posts.&lt;/p&gt;

&lt;p&gt;If you’d like to start learning more today, be sure to check out gradle-profiler &lt;a href="https://github.com/gradle/gradle-profiler"&gt;on GitHub&lt;/a&gt; and &lt;a href="https://dev.to/autonomousapps/benchmarking-builds-with-gradle-profiler-oa8"&gt;Tony Robalik’s post&lt;/a&gt; on Benchmarking builds with Gradle-Profiler.&lt;/p&gt;

&lt;p&gt;You can find more &lt;a href="https://goobar.io/tag/gradle/"&gt;Gradle-related posts here&lt;/a&gt; on my blog.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://goobar.io/benchmarking-gradle-builds-using-gradle-profiler/"&gt;Benchmarking Gradle Builds Using Gradle-Profiler&lt;/a&gt; appeared first on &lt;a href="https://goobar.io"&gt;goobar&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>gradle</category>
      <category>android</category>
    </item>
    <item>
      <title>Understanding, Profiling, and Optimizing Gradle In Android Builds</title>
      <dc:creator>Nate Ebel</dc:creator>
      <pubDate>Mon, 26 Oct 2020 16:05:46 +0000</pubDate>
      <link>https://forem.com/goobar_dev/understanding-profiling-and-optimizing-gradle-in-android-builds-58e2</link>
      <guid>https://forem.com/goobar_dev/understanding-profiling-and-optimizing-gradle-in-android-builds-58e2</guid>
      <description>&lt;p&gt;If you’ve spent any time as an Android developer you’ve probably experienced some level of frustration with Gradle in Android builds.&lt;/p&gt;

&lt;p&gt;I’m no exception to this rule. I’ve often enjoyed a laugh at Gradle’s expense, or laughed and nodded along as coworkers shared their own harrowing stories of lengthy or broken builds.&lt;/p&gt;

&lt;p&gt;However, I also think much of this frustration and complaint is unwarranted, or at the very least, misplaced. The Android build toolchain has a number of unique components and I often find others, and myself, blaming Gradle for something that might not actually be Gradle’s fault at all.&lt;/p&gt;

&lt;p&gt;So this week, I want to pull back the curtain, and share a bit about Gradle and how it relates to our Android builds.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does Gradle Relate To Your Android Project?
&lt;/h2&gt;

&lt;p&gt;Let’s start at beginning.&lt;/p&gt;

&lt;p&gt;What is Gradle?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gradle.org/"&gt;Gradle is a build tool&lt;/a&gt; capable of building software projects across a variety of different languages and domains.&lt;/p&gt;

&lt;p&gt;Gradle projects are configured using a Groovy-based DSL (Domain Specific Language). Groovy, itself, is a &lt;a href="http://groovy-lang.org/"&gt;multi-purpose programming language&lt;/a&gt; for the Java Virtual Machine (JVM).&lt;/p&gt;

&lt;p&gt;How then do these both work together to build our Android apps?&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are The Individual Components Of An Android Build?
&lt;/h2&gt;

&lt;p&gt;To build our Android apps using Gradle, we rely on another important component; the Android Gradle Plugin.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Introduction"&gt;Android Gradle Plugin&lt;/a&gt; builds upon the generic concept of &lt;a href="https://docs.gradle.org/current/userguide/plugins.html"&gt;Gradle plugins&lt;/a&gt; to support the Android build requirements. Custom Gradle tasks, and build configuration options are provided by the Android Gradle Plugin to control how an Android application is built.&lt;/p&gt;

&lt;p&gt;Android Gradle Plugin (AGP) is not directly tied to Android Studio, though they do often have a close connection. As &lt;a href="https://developer.android.com/studio/releases/gradle-plugin"&gt;new features are added to the plugin&lt;/a&gt;, Android Studio is generally updated to take advantage of those features to provide a better developer experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Is Your Android Gradle Project Structured?
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://docs.gradle.org/current/userguide/organizing_gradle_projects.html"&gt;Gradle project is comprised&lt;/a&gt; of one, or many, modules. A module may consist of any combination of source code, resources, assets, and build configuration.&lt;/p&gt;

&lt;p&gt;Your Android project configuration is comprised of several different files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a top-level &lt;em&gt;settings.gradle&lt;/em&gt; file to indicates which individual Gradle modules should be loaded&lt;/li&gt;
&lt;li&gt;a top-level &lt;em&gt;build.gradle&lt;/em&gt; file that can be used to declare project-level dependencies, plugins, and other configuration&lt;/li&gt;
&lt;li&gt;one, or many, module-level &lt;em&gt;build.gradle&lt;/em&gt; files that define how each individual module and built and how they relate to one another&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you create a new project in Android Studio, you generally have a single &lt;code&gt;:app&lt;/code&gt; module created.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do these build components work to build your app?
&lt;/h3&gt;

&lt;p&gt;How do all of these pieces work together to actually build your Android app?&lt;/p&gt;

&lt;p&gt;Your project, and each module, use the Groovy language and Gradle DSL to control how they should be built.&lt;/p&gt;

&lt;p&gt;Any of these projects that need to know about the Android framework will use the Android Gradle Plugin to configure Android-specific build options such as minSdk, buildTypes, lintOptions, etc.&lt;/p&gt;

&lt;p&gt;This is easily recognized by applying the plugin to a &lt;code&gt;build.gradle&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;plugins {
  id 'com.android.application'
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and by modifying the Android configuration block&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;android {
  compileSdkVersion 30
  buildToolsVersion "30.0.1"
  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All of these &lt;code&gt;build.gradle&lt;/code&gt; files will work together to define which tasks should be generated and run. Each Gradle task is responsible for one small piece of the project compilation and packaging process.&lt;/p&gt;

&lt;p&gt;To see a list of all Gradle tasks available for your Project, you have two options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run &lt;em&gt;./gradlew tasks&lt;/em&gt; from the command line&lt;/li&gt;
&lt;li&gt;Open the Gradle tool window within Android Studio or IntelliJ&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once all tasks are defined and configured, the general Gradle build tool will process the build files, generate any needed tasks, and ultimately execute each task.&lt;/p&gt;

&lt;p&gt;Most Gradle plugins use &lt;a href="https://docs.gradle.org/current/userguide/custom_tasks.html"&gt;&lt;em&gt;enhanced tasks&lt;/em&gt;&lt;/a&gt; which means they contain all the behavior needed to perform their desired action. Enhanced tasks also are responsible for declaring needed inputs and outputs.&lt;/p&gt;

&lt;p&gt;You can think of a &lt;em&gt;Gradle task&lt;/em&gt; as a function that takes in a set of inputs, and generates a specific output. The work executed could be processing a file, merging resources, uploading an .apk to Firebase, or any number of other actions.&lt;/p&gt;

&lt;p&gt;Once these tasks finish executing, the Gradle build is complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are The Pain Points Of Gradle In Android Builds?
&lt;/h2&gt;

&lt;p&gt;I hear, and have experienced, several common complaints about different parts of this build process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining build logic
&lt;/h3&gt;

&lt;p&gt;Many people feel it’s too difficult to define, or customize, build logic. Gradle often gets blamed for this, when in reality, it’s like Groovy that developers are unfamiliar with.&lt;/p&gt;

&lt;p&gt;Because Groovy can be both dynamically, and statically, typed, it can feel very foreign if you’re not expecting dynamic typing. How do I define a variable to determine whether we’re building on CI or not? How to I loop over a collection of build variants? Lack of robust auto-completion can leave developers feeling lost when trying to define custom build logic.&lt;/p&gt;

&lt;p&gt;To help with this, you may benefit from learning more about Groovy as a language. The language &lt;a href="http://groovy-lang.org/syntax.html"&gt;syntax guide&lt;/a&gt; may be a good starting point for you.&lt;/p&gt;

&lt;p&gt;Additionally, improvements to Gradle and Android Studio have made it possible to define your Gradle build logic using statically typed Kotlin, rather than Groovy. If you miss static typing and Kotlin language features when defining your build logic, read more about how to start &lt;a href="https://docs.gradle.org/current/userguide/kotlin_dsl.html"&gt;using the Gradle Kotlin DSL&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exploring the Android Gradle Plugin
&lt;/h3&gt;

&lt;p&gt;Another big Gradle-related frustration for Android devs is that they don’t know what configuration options are available. What flags are available to control how a project is built? How do you work with Android-specific facets of the build during the Gradle build process.&lt;/p&gt;

&lt;p&gt;To help answer these questions, it be be useful to read through &lt;a href="https://google.github.io/android-gradle-dsl/current/"&gt;api reference docs&lt;/a&gt; for the Android Gradle Plugin. This gives detailed documentation on what configuration blocks, and types can be used to control your build.&lt;/p&gt;

&lt;p&gt;For example, if you were looking for more information on how to control Android Lint tasks, you &lt;a href="https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.LintOptions.html"&gt;could reference&lt;/a&gt; the &lt;code&gt;lintOptions { }&lt;/code&gt; configuration block.&lt;/p&gt;

&lt;p&gt;Other configuration blocks include&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.AdbOptions.html"&gt;adbOptions {}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.BuildType.html"&gt;buildTypes {}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.DataBindingOptions.html"&gt;dataBinding {}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.SigningConfig.html"&gt;signingConfigs {}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://google.github.io/android-gradle-dsl/current/index.html"&gt;and more…&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Working with annotation processors
&lt;/h3&gt;

&lt;p&gt;One of the most common, and serious, build issues Android developers may face is that of slow builds.&lt;/p&gt;

&lt;p&gt;There are lots of reasons your build may be slow; and we’ll look at some tools for detecting and fixing these issues. One of the most common culprits of a slow build are annotation processors. Tools like Dagger or Android DataBinding rely on annotation processors to generate code at compile time. This saves code and the cost of slower builds. This issue is particularly bad when using annotation processors in Kotlin projects.&lt;/p&gt;

&lt;p&gt;To help with this, take a look at the &lt;a href="https://kotlinlang.org/docs/reference/kapt.html"&gt;Annotation Processing with Kotlin guide&lt;/a&gt;. In it, you’ll find several tips for ensuring your build is better optimized for annotation processing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Profiling Gradle In Android Builds
&lt;/h2&gt;

&lt;p&gt;As you start to further understand your Gradle build, you’ll likely want to profile it to really dig in and see which parts of your build are taking the most time.&lt;/p&gt;

&lt;p&gt;The go-to tool for this are &lt;a href="https://docs.gradle.org/nightly/userguide/performance.html#profiling_with_build_scans"&gt;Gradle build scans.&lt;/a&gt; A build scan provides deep insights into your gradle build including, which tasks were executed, which tasks were pulled from local and remote caches, and which tasks are taking the most time.&lt;/p&gt;

&lt;p&gt;To generate a build scan for any Gradle build, you can add the &lt;em&gt;–scan&lt;/em&gt; build flag after the invocation.&lt;/p&gt;

&lt;p&gt;Once the task finishes, you’re receive a link to a report like the following.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_Pq4essN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://media-exp1.licdn.com/dms/image/C5612AQEF64WRdpm4ng/article-inline_image-shrink_1500_2232/0%3Fe%3D1609372800%26v%3Dbeta%26t%3DJltdVcmZG_LDmZ_Oq40RdYTplpw6P6TRFKMDsJbjOo4" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_Pq4essN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://media-exp1.licdn.com/dms/image/C5612AQEF64WRdpm4ng/article-inline_image-shrink_1500_2232/0%3Fe%3D1609372800%26v%3Dbeta%26t%3DJltdVcmZG_LDmZ_Oq40RdYTplpw6P6TRFKMDsJbjOo4" alt="Gradle Build Scan"&gt;&lt;/a&gt;A sample build scan&lt;/p&gt;

&lt;p&gt;Open the report into a web browser, and you’ll be able to explore every facet of your build, and can use this information to start optimizing your build.&lt;/p&gt;

&lt;p&gt;If your team is using Gradle Enterprise, you’re likely already familiar with using Gradle build scans. To get the most out of these scans, it’s helpful to make them easily discoverable for everyone on your team. I recently shared about how we &lt;a href="https://goobar.io/2020/10/13/surfacing-gradle-build-scans-within-github-actions/"&gt;surfaced Gradle build scans&lt;/a&gt; within our GitHub Actions workflows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://scans.gradle.com/"&gt;For more on Gradle build scans, you can follow this guide.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmarking Gradle In Android Builds
&lt;/h2&gt;

&lt;p&gt;As you start profiling your build, you may identify avenues of possible improvement. When making changes to your build. it can be useful to benchmark current, and updated, build performance to know whether your changes are actually impacting your build.&lt;/p&gt;

&lt;p&gt;To do this, you can turn to the &lt;em&gt;gradle-profiler&lt;/em&gt; tool.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/gradle/gradle-profiler#advanced-profiling-scenarios"&gt;Gradle-profiler&lt;/a&gt; helps you automate the repeated testing, and data collection, needed to really understand build performance.&lt;/p&gt;

&lt;p&gt;Imagine running 10 Gradle builds in a row, collecting the build times, and performing statistical analysis on those build times. That’s effectively what &lt;em&gt;gradle-profiler&lt;/em&gt; provides.&lt;/p&gt;

&lt;p&gt;With &lt;em&gt;gradle-profiler&lt;/em&gt; you can benchmark a single simple task, a complex build scenario, or even a suite of build scenarios.&lt;/p&gt;

&lt;p&gt;These benchmarks can also be run against different branches of your app. This can allow you to compare the benchmark performance of any given branch to that of your default branch; ideally detecting build regressions before they’re ever checked in.&lt;/p&gt;

&lt;p&gt;For a great overview of using &lt;em&gt;gradle-profiler&lt;/em&gt; check &lt;a href="https://dev.to/autonomousapps/benchmarking-builds-with-gradle-profiler-oa8"&gt;this post from Tony Robalik&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimizing Your Gradle Build
&lt;/h2&gt;

&lt;p&gt;Finally, once you’ve profiled your build, and once you know how to benchmark the impact of any build changes, you’re going to want to start optimizing performance to have the fastest, most efficient build possible. This can save your team both time and money.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enabling performance settings
&lt;/h3&gt;

&lt;p&gt;There are &lt;a href="https://docs.gradle.org/nightly/userguide/performance.html"&gt;several build properties&lt;/a&gt; that can be set to help provide quick build performance wins:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;org.gradle.parallel=true&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;org.gradle.vfs.watch=true&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;org.gradle.caching=true&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By setting the &lt;em&gt;parallel&lt;/em&gt; flag, you enable your project to &lt;a href="https://docs.gradle.org/nightly/userguide/performance.html#parallel_execution"&gt;build multiple tasks at the same time&lt;/a&gt;, as long as they are in different modules. If you have a multi-module setup, this can be a great performance win.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;vfs.watch&lt;/em&gt; flag enables the &lt;a href="https://blog.gradle.org/introducing-file-system-watching"&gt;new filesystem watching&lt;/a&gt; feature of Gradle which monitors information about which files are changing to improve incremental build times.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gradle build cache
&lt;/h3&gt;

&lt;p&gt;The &lt;em&gt;caching&lt;/em&gt; flag is one of the biggest performance changes you can make. Gradle has two different build cache types: &lt;em&gt;local&lt;/em&gt; and &lt;em&gt;remote&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Setting the &lt;em&gt;caching&lt;/em&gt; flag will enable the local build cache.&lt;/p&gt;

&lt;p&gt;With caching enabled, the outputs of Gradle tasks are saved to the cache and reused for future builds. This can dramatically speed up clean and incremental builds.&lt;/p&gt;

&lt;p&gt;Similarly, you can enable a remove build cache that moves this concept to a remote server. You might configure your CI server to push task outputs to the remote cache which can then be reused by everyone on your team, and by future CI builds.&lt;/p&gt;

&lt;p&gt;Browse the &lt;a href="https://docs.gradle.org/current/userguide/build_cache.html"&gt;Gradle Build Cache guide&lt;/a&gt; for more information on enabling caching for you project. Additionally, there’s a &lt;a href="https://youtu.be/YrY-skMl06w"&gt;great webinar from Gradle&lt;/a&gt; on how to get the most out of the Gradle build cache. I highly recommend watching that to learn more on profiling and optimizing your Gradle build.&lt;/p&gt;

&lt;h3&gt;
  
  
  JVM memory settings
&lt;/h3&gt;

&lt;p&gt;You may also want to update your JVM memory settings to &lt;a href="https://docs.gradle.org/current/userguide/build_environment.html#sec:configuring_jvm_memory"&gt;provide Gradle/JVM more memory&lt;/a&gt; when building your app.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;org.gradle.jvmargs=Xmx2g&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Build performance plugins
&lt;/h3&gt;

&lt;p&gt;There are also two really useful plugins I can recommend for helping you fix and monitor Gradle build issues.&lt;/p&gt;

&lt;p&gt;First, the &lt;a href="https://runningcode.github.io/gradle-doctor/"&gt;Gradle-Doctor plugin&lt;/a&gt; helps you diagnose common issues such as mismatched JDK versions and negative remote build cache savings. If building an Android app, &lt;em&gt;gradle-doctor&lt;/em&gt; can also help you understand how much time is spent by Dagger annotation processing.&lt;/p&gt;

&lt;p&gt;Second is the &lt;a href="https://github.com/gradle/android-cache-fix-gradle-plugin"&gt;Android Cache Fix Gradle Plugin&lt;/a&gt;. This is a must-try plugin for Android projects.&lt;/p&gt;

&lt;p&gt;It provides workarounds for Gradle build issues present in the Android Gradle Plugin. Most noticeably, it helps fix cache misses due to these issues with AGP. In a well configured Gradle build, fixing cache misses can have a massive positive impact on your build times.&lt;/p&gt;

&lt;p&gt;Integrate this plugin, re-run your benchmark scenarios, and you’ll hopefully see nice positive improvements to your build times.&lt;/p&gt;

&lt;p&gt;Android builds are complex, with multiple languages, tools, and plugins to consider. As we spend so much of our time waiting for code to compile, or CI builds to run, it’s in the best interest of ourselves, our teams, and our organizations if our builds are fast and efficient.&lt;/p&gt;

&lt;p&gt;I think the best way to start improving the efficiency of our builds is to better understand our build tools and the overall build process.&lt;/p&gt;

&lt;p&gt;Hopefully, this has helped you better understand some of these individual build components, and helped point you to resources to help you further your understanding of the Android build process.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://goobar.io/2020/10/26/understanding-profiling-and-optimizing-gradle-in-android-builds/"&gt;Understanding, Profiling, and Optimizing Gradle In Android Builds&lt;/a&gt; appeared first on &lt;a href="https://goobar.io"&gt;goobar&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>gradle</category>
      <category>android</category>
    </item>
    <item>
      <title>Remote Work in 2020 is Not Normal – Will We Evaluate It Fairly?</title>
      <dc:creator>Nate Ebel</dc:creator>
      <pubDate>Mon, 19 Oct 2020 12:30:00 +0000</pubDate>
      <link>https://forem.com/goobar_dev/remote-work-in-2020-is-not-normal-will-we-evaluate-it-fairly-4fli</link>
      <guid>https://forem.com/goobar_dev/remote-work-in-2020-is-not-normal-will-we-evaluate-it-fairly-4fli</guid>
      <description>&lt;p&gt;How are you feeling about working from home right now?&lt;/p&gt;

&lt;p&gt;As I look around the internet, it appears to me that results are mixed.  Many are loving the new remote work lifestyle.  Many others are stressed, working more hours, and feeling pressure to maintain productivity while working from home.&lt;/p&gt;

&lt;p&gt;I don’t believe either of these groups are right or wrong.  Everyone’s situation is unique.&lt;/p&gt;

&lt;p&gt;One thing I do believe strongly though;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Working from home right now, during a global pandemic, is NOT the same thing as “remote work”.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I feel that this is getting lost in too many discussions lately.&lt;/p&gt;

&lt;h2&gt;
  
  
  This is not a normal year
&lt;/h2&gt;

&lt;p&gt;With large companies like &lt;a href="https://www.cnn.com/2020/07/28/success/google-permanent-remote-work/index.html"&gt;Google&lt;/a&gt;, &lt;a href="https://www.nytimes.com/2020/05/21/technology/facebook-remote-work-coronavirus.html"&gt;Facebook&lt;/a&gt;, and &lt;a href="https://www.webpronews.com/microsoft-making-remote-work-a-permanent-option/"&gt;Microsoft&lt;/a&gt; continuing to adopt more permanent remote-work policies, it looks as if remote work is poised to stick around for a while.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X2f6oisq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i0.wp.com/goobar.io/wp-content/uploads/2020/10/What-Does-Remote-Work-Normally-Look-Like_-1.png%3Fresize%3D800%252C534%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X2f6oisq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i0.wp.com/goobar.io/wp-content/uploads/2020/10/What-Does-Remote-Work-Normally-Look-Like_-1.png%3Fresize%3D800%252C534%26ssl%3D1" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I don’t think remote work is right from everyone.  It’s not, and it doesn’t need to be.  &lt;/p&gt;

&lt;p&gt;But I also don’t think the current realities of working from home are an accurate, or fair, representation of what a remote work culture can be.&lt;/p&gt;

&lt;p&gt;According to &lt;a href="https://lp.buffer.com/state-of-remote-work-2020"&gt;Buffer’s State of Remote Survey&lt;/a&gt;, remote employees largely want to stay remote. However, if 2020 is your first foray into remote work, I wonder if that is still the case.&lt;/p&gt;

&lt;p&gt;We’re extra stressed right now.&lt;/p&gt;

&lt;p&gt;There are more distractions throughout the day; kids learning from home; extra deliveries; partners also working from home; etc &lt;/p&gt;

&lt;p&gt;We can’t really get out of the house to work. &lt;/p&gt;

&lt;p&gt;We can’t meet up with others to work, chat, brainstorm, collaborate. &lt;/p&gt;




&lt;p&gt;On top of all of that, it seems many companies haven’t actually shifted to a remote-first mindset.&lt;/p&gt;

&lt;p&gt;All-day meetings are even more draining right now.  Employees are feeling pushed to work nights and weekends.  Defaulting to real-time communication adds to the pressure of being always at a keyboard; even when that’s at odds with the realities of being at home.&lt;/p&gt;

&lt;p&gt;In short, translating the on-site work experience to the home is challenging, and in many ways, just doesn’t really work. This leaves employees feeling overwhelmed, less creative, more isolated, and longing for a return to work-normalcy.&lt;/p&gt;

&lt;p&gt;All in all, there are currently many things which are very atypical of enjoyable, and successful, remote work.&lt;/p&gt;

&lt;p&gt;I worry that during this big initial push into remote work, let’s call it v1, that the evaluation by organizations/managers/individuals will fail to take into account everything else going on right now.  I fear that this will keep many from getting to remote work v2 in which there are hopefully fewer abnormal circumstances and more of the traditional benefits of a remote work culture.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does remote work usually look like?
&lt;/h2&gt;

&lt;p&gt;Are you getting your first taste or remote work here in 2020, and it’s not what you thought it would be? &lt;/p&gt;

&lt;p&gt;I can relate.&lt;/p&gt;

&lt;p&gt;I’ve been remote for 4+ years now, and this year has still been unusual.  It has not been the same remote work situation that I’m accustomed to, or that I enjoy so much.&lt;/p&gt;

&lt;p&gt;How does remote work usually look?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R9k4-HOg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i0.wp.com/goobar.io/wp-content/uploads/2020/10/What-Does-Remote-Work-Normally-Look-Like_.png%3Fresize%3D342%252C512%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R9k4-HOg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i0.wp.com/goobar.io/wp-content/uploads/2020/10/What-Does-Remote-Work-Normally-Look-Like_.png%3Fresize%3D342%252C512%26ssl%3D1" alt="Is this normal for remote work?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For me, remote work has generally been filled with far more connection, flexibility, and variety than it has here in 2020.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I miss getting out of my home to work from a coffee shop, or library, or a co-working space.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I miss being able to change locations when the home is too loud; or too distracting.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I miss meeting with local co-workers or friends to chat, work, brainstorm, plan, organize, etc…&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The lack of 1 on 1 chats, meetups, and conferences has me feeling disconnected, isolated, and uninspired.&lt;/p&gt;

&lt;p&gt;In the past, I’ve been able to travel and meet my remote team in person.  This builds trust, improves communication, and leads to a better working relationship.  In 2020, I haven’t even been able to meet remote teammates living in the same city; let alone the ones from all over the world.&lt;/p&gt;

&lt;p&gt;Speaking of travel, it’s difficult right now to get away and recharge in the same way we used to.  Even just going outside for a relaxing walk is not as simple or relaxing as it used to be.  This has accumulated over the year; myself and others are starting to feel the fatigue of our current situations.&lt;/p&gt;

&lt;p&gt;None of these things matches my previous experiences with remote work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s the future of remote work?
&lt;/h2&gt;

&lt;p&gt;I don’t expect all companies to shift to remote-first work; not all can or should.  And I know that my experience with remote work may be very different than yours.&lt;/p&gt;

&lt;p&gt;If you don’t want to work remotely, there’s absolutely nothing wrong with that.&lt;/p&gt;

&lt;p&gt;But if you thought you might like remote work, and aren’t enjoying it here in 2020, I hope some of this resonates with you and maybe gives you hope that your remote work dreams are still possible under different circumstances.&lt;/p&gt;

&lt;p&gt;I do worry that the efficacy of remote work will be unfairly judged during this period, and I’m also encouraged by the number of people that find themselves adapting to remote, acknowledging the realities of 2020, and still finding themselves wanting to make a more permanent shift in remote work.&lt;/p&gt;

&lt;p&gt;I hope the increase in remote work stays around. Not because we’re forced into, but because more teams find themselves adapting to it favorably, and in a way that emphasizes outcomes, trust, and the human being. As discussed in &lt;a href="https://www.cnbc.com/2020/10/05/working-from-home-means-more-trust-from-leaders-says-tech-exec.html"&gt;this recent CNBC article&lt;/a&gt;, these changes in leadership are needed to make the effective shift into remote work.  It &lt;a href="https://www.forbes.com/sites/jackkelly/2020/05/24/the-work-from-home-revolution-is-quickly-gaining-momentum/#6bb102af1848"&gt;seems like this may be the case&lt;/a&gt;, but only time will tell.&lt;/p&gt;

&lt;p&gt;In my experience, effective remote work has enabled me to work around life, rather than living around work.  That’s what I wish for all of us, and I see increased remote work opportunity as a powerful tool in realizing that for more people; not because everyone should be remote, but because I hope those that wish to be remote can find healthy, thriving remote teams in the future.&lt;/p&gt;




&lt;p&gt;The post &lt;a href="https://goobar.io/2020/10/19/remote-work-in-2020-is-not-normal-will-we-evaluate-it-fairly/"&gt;Remote Work in 2020 is Not Normal – Will We Evaluate It Fairly?&lt;/a&gt; appeared first on &lt;a href="https://goobar.io"&gt;goobar&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>remotework</category>
    </item>
    <item>
      <title>Surfacing Gradle Build Scans Within GitHub Actions Workflows</title>
      <dc:creator>Nate Ebel</dc:creator>
      <pubDate>Tue, 13 Oct 2020 12:37:00 +0000</pubDate>
      <link>https://forem.com/n8ebel/surfacing-gradle-build-scans-within-github-actions-workflows-2dn8</link>
      <guid>https://forem.com/n8ebel/surfacing-gradle-build-scans-within-github-actions-workflows-2dn8</guid>
      <description>&lt;p&gt;This post demonstrates several approaches for surfacing Gradle build scans within &lt;a href="https://github.com/features/actions"&gt;GitHub Actions&lt;/a&gt; workflows; thereby making them more discoverable and hopefully more useful to a team.&lt;/p&gt;

&lt;p&gt;Recently, our Android team at &lt;a href="https://www.premise.com/"&gt;Premise Data&lt;/a&gt; has worked with the &lt;a href="https://gradle.com/"&gt;Gradle Enterprise&lt;/a&gt;team to optimize our Gradle builds.  Gradle build scans have been a key tool in this work.  Build scans have helped optimize our build, and have helped detect regressions and other build trends for both CI, and local developers’, builds.&lt;/p&gt;

&lt;p&gt;Because of the value we’ve seen in regularly reviewing these build scans, I wanted a way to make these scans easier to find, and to use, for everyone on our team.&lt;/p&gt;

&lt;p&gt;Table Of Contents&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Working With Gradle Build Scans?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What are Gradle build scans?&lt;/li&gt;
&lt;li&gt;What does a build scan look like?&lt;/li&gt;
&lt;li&gt;How to generate a Gradle build scan?&lt;/li&gt;
&lt;li&gt;How to enable build scans for your Android project?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Surfacing Gradle Build Scan URLs as Pull Request Comments&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding a Single Job’s Gradle Build Scan URL as a Pull Request Comment&lt;/li&gt;
&lt;li&gt;Adding Build Scan URL Comments for Multiple Jobs&lt;/li&gt;
&lt;li&gt;Consolidating Multiple Job’s Build Scan URLs Into a Single Pull Request Comment&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Storing Gradle Build Scan URLs In GitHub Actions Workflow Artifacts&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing Gradle Build Scan URLs to a File&lt;/li&gt;
&lt;li&gt;Storing Build Scan Files as Workflow Artifacts&lt;/li&gt;
&lt;li&gt;Storing Multiple Build Scan Files as a Single Workflow Artifact&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Learn More&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wrapping Up&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Thanks to &lt;a href="https://twitter.com/AutonomousApps"&gt;Tony Robalik&lt;/a&gt; for pointing me in the direction of adding build scan urls as PR comments.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Working With Gradle Build Scans?
&lt;/h2&gt;

&lt;p&gt;Before we dive in, let’s quickly review Gradle build scans; what are they, and &lt;a href="https://guides.gradle.org/creating-build-scans/"&gt;how to enable them&lt;/a&gt; for your project?&lt;/p&gt;

&lt;h3&gt;Find the Code&lt;/h3&gt;

&lt;p&gt;If you want to check out these full examples, you can find them on GitHub.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/n8ebel/GitHubActionsAutomationSandbox/compare/ne/buildscan-recipes" rel="noopener noreferrer"&gt;&lt;span&gt;&lt;span&gt;Open In Github&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What are Gradle build scans?
&lt;/h3&gt;

&lt;p&gt;Gradle &lt;a href="https://gradle.com/build-scans/"&gt;build scans provide a detailed overview&lt;/a&gt; of your Gradle build.  These details include a myriad of information including &lt;em&gt;tasks executed, build cache performance, test results, environment details,&lt;/em&gt; and much more.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does a build scan look like?
&lt;/h3&gt;

&lt;p&gt;Build scans are presented as interactive webpages hosted at either &lt;code&gt;scans.gradle.com&lt;/code&gt; or within your own Gradle Enterprise instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dcNw2oqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh4.googleusercontent.com/d_dD9svW9pN1Zig5vXLb1FS-5xSE6TcXVN0nQdTPYnkXzVXlVZfI4QeCD0qQHy3IAMv-rWSfOUIDpMhxyjc_tZCMILrzavuQu3SC4KvlI7uh6DzeNMXotj02uksuw8_OtpaTgJZa" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dcNw2oqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh4.googleusercontent.com/d_dD9svW9pN1Zig5vXLb1FS-5xSE6TcXVN0nQdTPYnkXzVXlVZfI4QeCD0qQHy3IAMv-rWSfOUIDpMhxyjc_tZCMILrzavuQu3SC4KvlI7uh6DzeNMXotj02uksuw8_OtpaTgJZa" alt=""&gt;&lt;/a&gt;Sample build scan&lt;/p&gt;

&lt;p&gt;When scans are generated for a build, a link to the build scan will be included at the end of the console build output.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to generate a Gradle build scan?
&lt;/h3&gt;

&lt;p&gt;Generating a Gradle build scan for a single Gradle task execution is simple.  We only need to add the &lt;code&gt;–scan&lt;/code&gt; option to our task invocation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./gradlew assembleDebug --scan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the end of this execution, we see the following in our console window:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Publishing build scan...[https://gradle.com/s/](https://gradle.com/s/)&amp;lt;scan id here&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s this url that I wanted to surface to our team.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to enable build scans for your Android project?
&lt;/h3&gt;

&lt;p&gt;If your team is leveraging Gradle Enterprise, or you just want to generate build scans for all builds, you can integrate the Gradle Enterprise plugin into your project.&lt;/p&gt;

&lt;p&gt;First, you’ll want to add the Gradle Enterprise plugin to your &lt;code&gt;settings.gradle&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;plugins { id "com.gradle.enterprise" version "3.4.1" }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, you can configure build scan behavior in your &lt;code&gt;settings.gradle&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;gradleEnterprise { buildScan { termsOfServiceUrl = "https://gradle.com/terms-of-service" termsOfServiceAgree = "yes" publishAlways() } }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this setup in place, a build scan will be generated for each build of your project. We took the time to review this setup because we’ll make use of this later on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Surfacing Gradle Build Scan URLs as Pull Request Comments
&lt;/h2&gt;

&lt;p&gt;Now that we’re familiar with Gradle build scans, let’s return to the idea of surfacing these build scans in our GitHub Actions workflows.&lt;/p&gt;

&lt;p&gt;We’ve now seen that urls for these build scans are logged at the end of our Gradle task execution. &lt;/p&gt;

&lt;p&gt;If running on a continuous integration (CI) server, this often means having to scroll, and parse, through hundreds or even thousands of lines of build output to find this url.  And that’s only useful if developers even know the url exists in the first place.&lt;/p&gt;

&lt;p&gt;One way to help with this problem is to add these urls as comments on an open PR. In this section, we’re going to examine several variations of this idea. In each variant, we’re going to make use of the following GitHub Actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/eskatos/gradle-command-action"&gt;gradle-command-action&lt;/a&gt; – for executing Gradle tasks&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mshick/add-pr-comment"&gt;add-pr-comment&lt;/a&gt; – for commenting on an open pull request&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These actions will do most of the heavy lifting for us.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding a Single Job’s Gradle Build Scan URL as a Pull Request Comment
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/n8ebel/GitHubActionsAutomationSandbox/blob/ne/buildscan-recipes/.github/workflows/single-job-buildscan-pr-comment.yml"&gt;Code Sample Here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s first imagine we have a GitHub Actions workflow running a single &lt;a href="https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#jobs"&gt;job&lt;/a&gt;. That job is configured to assemble our app.&lt;/p&gt;

&lt;p&gt;We can use the &lt;em&gt;&lt;a href="https://github.com/eskatos/gradle-command-action"&gt;gradle-command-action&lt;/a&gt;&lt;/em&gt; action to run our desired Gradle task.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- id: gradle uses: eskatos/gradle-command-action@v1 with: arguments: assembleDebug
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This action will automatically parse our build output, find the build scan url, and add it as an output that can be accessed from other steps in the job.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;steps.gradle.outputs.build-scan-url
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the structure of this output. &lt;code&gt;steps.gradle&lt;/code&gt; is referencing the job build step with id &lt;code&gt;gradle&lt;/code&gt;. Then, &lt;code&gt;outputs.build-scan-url&lt;/code&gt; is referencing a specific output for that build step.&lt;/p&gt;

&lt;p&gt;Now that we have access to the build scan url, we can use the &lt;em&gt;&lt;a href="https://github.com/mshick/add-pr-comment"&gt;add-pr-comment&lt;/a&gt;&lt;/em&gt; action in add the url as a pull request comment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Add Build Scan URLs to Pull Request uses: mshick/add-pr-comment@v1 with: repo-token: ${{ secrets.GITHUB\_TOKEN }} message: Buildscan url ${{ steps.gradle.outputs.build-scan-url }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could go one step further, and customize the PR comment a bit more.&lt;/p&gt;

&lt;p&gt;In this example, we’ll add the workflow run id for this specific build scan so we can more closely tie the url to the workflow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Add Build Scan URLs to Pull Request uses: mshick/add-pr-comment@v1 with: repo-token: ${{ secrets.GITHUB\_TOKEN }} message: | \*\*Buildscan url for run [${{ github.run\_id }}](https://github.com/n8ebel/GitHubActionsAutomationSandbox/actions/runs/${{ github.run\_id }})\*\* ${{ steps.gradle.outputs.build-scan-url }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this workflow is run, we’ll now get PR comments for each successful run of our workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tt-egxi6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.09.16-AM.png%3Fresize%3D800%252C107%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img width="800" height="107" src="https://res.cloudinary.com/practicaldev/image/fetch/s--tt-egxi6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.09.16-AM.png%3Fresize%3D800%252C107%26ssl%3D1" alt=""&gt;&lt;/a&gt;Example pull request comment including a Gradle build scan url&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding Build Scan URL Comments for Multiple Jobs
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/n8ebel/GitHubActionsAutomationSandbox/blob/ne/buildscan-recipes/.github/workflows/multiple-job-multiple-buildscan-pr-comments.yml"&gt;Code Sample Here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In many cases, our workflows will have more than one job. If we’re running Gradle tasks for each job, this will result in multiple build scans.&lt;/p&gt;

&lt;p&gt;So how can we surface each build scan for the workflow?&lt;/p&gt;

&lt;p&gt;The easiest approach, is to extend our previous example and add PR comments for each job.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs: test\_job: name: Test runs-on: ubuntu-latest steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 with: arguments: test - name: Add Build Scan URL to Pull Request uses: mshick/add-pr-comment@v1 with: repo-token: ${{ secrets.GITHUB\_TOKEN }} message: | \*\*Test job buildscan url for run [${{ github.run\_id }}](https://github.com/n8ebel/GitHubActionsAutomationSandbox/actions/runs/${{ github.run\_id }})\*\* ${{ steps.gradle.outputs.build-scan-url }} assemble: name: Assemble Debug runs-on: ubuntu-latest steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 with: arguments: assembleDebug - name: Add Build Scan URL to Pull Request uses: mshick/add-pr-comment@v1 with: repo-token: ${{ secrets.GITHUB\_TOKEN }} message: | \*\*Assemble job buildscan url for run [${{ github.run\_id }}](https://github.com/n8ebel/GitHubActionsAutomationSandbox/actions/runs/${{ github.run\_id }})\*\* ${{ steps.gradle.outputs.build-scan-url }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we’ve added a comment for each of the jobs run. In this case, we’ve customized the comment text to indicate which job the build scan is associated with; Test or Assemble.&lt;/p&gt;

&lt;p&gt;The resulting PR looks something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--koGzqQyu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Untitled-design.png%3Fresize%3D600%252C200%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img width="600" height="200" src="https://res.cloudinary.com/practicaldev/image/fetch/s--koGzqQyu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Untitled-design.png%3Fresize%3D600%252C200%26ssl%3D1" alt=""&gt;&lt;/a&gt;Multiple build scan PR comments; one for each job in the workflow&lt;/p&gt;

&lt;p&gt;This approach succeeds in surfacing the build scan urls. However, it also results in a lot of PR noise as each workflow run may result in multiple PR comments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consolidating Multiple Job’s Build Scan URLs Into a Single Pull Request Comment
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/n8ebel/GitHubActionsAutomationSandbox/blob/ne/buildscan-recipes/.github/workflows/multiple-job-single-buildscan-pr-comment.yml"&gt;Code Sample Here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To improve upon the previous example, we’ll consolidate all the build scan urls for a workflow into a single PR comment. That way, we’ll have a 1:1 mapping between a workflow run and build scan PR comments.&lt;/p&gt;

&lt;p&gt;The general idea of this approach is this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Expose each build scan url as a job output&lt;/li&gt;
&lt;li&gt;Delay adding PR comments until all relevant jobs have completed&lt;/li&gt;
&lt;li&gt;Add a new job that waits for relevant jobs, and adds a single PR comment including all the build scan urls
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs: test: name: Test runs-on: ubuntu-latest outputs: buildScanUrl: ${{ steps.gradle.outputs.build-scan-url }} steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 with: arguments: test assemble: name: Assemble Debug runs-on: ubuntu-latest outputs: buildScanUrl: ${{ steps.gradle.outputs.build-scan-url }} steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 with: arguments: assembleDebug notification\_job: needs: [test, assemble] name: Add Build Scan URLs runs-on: ubuntu-latest steps: - uses: mshick/add-pr-comment@v1 with: repo-token: ${{ secrets.GITHUB\_TOKEN }} message: | \*\*Build scans for run: [${{ github.run\_id }}](https://github.com/premisedata/mobile-android/actions/runs/${{ github.run\_id }})\*\* \* Test Build Scan ${{ needs.test.outputs.buildScanUrl }} \* Assemble Build Scan ${{ needs.assemble.outputs.buildScanUrl }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With all build scan urls consolidated into a single comment, our PR output might look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2NSCT2Rh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.56.39-AM.png%3Fresize%3D800%252C142%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img width="800" height="142" src="https://res.cloudinary.com/practicaldev/image/fetch/s--2NSCT2Rh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-7.56.39-AM.png%3Fresize%3D800%252C142%26ssl%3D1" alt="A single pull request comment that contains multiple Gradle build scan urls"&gt;&lt;/a&gt;A single build scan PR comment for all jobs in the workflow&lt;/p&gt;

&lt;p&gt;Now, we will see a single comment for each workflow run.&lt;/p&gt;

&lt;p&gt;If any job fails for a workflow run, we can find the associated build scan url for that job, and start investigating the issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Storing Gradle Build Scan URLs In GitHub Actions Workflow Artifacts
&lt;/h2&gt;

&lt;p&gt;Surfacing build scan urls as PR comments might be a useful improvement to your pull request workflows.&lt;/p&gt;

&lt;p&gt;However, not all workflows have an associated pull request. You may have a nightly build. Or a scheduled release build. Or any number of other automated workflows that don’t have an associated pull request.&lt;/p&gt;

&lt;p&gt;If something goes wrong for those builds, we still want to quickly find the associated build scan and start diagnosing the problem.&lt;/p&gt;

&lt;p&gt;How then can we improve discoverability of build scans for non-pull-request workflows?&lt;/p&gt;

&lt;p&gt;One solution is to write the build scan urls to a file stored as a build artifact.&lt;/p&gt;

&lt;p&gt;Within our GitHub Actions workflows, &lt;a href="https://docs.github.com/en/free-pro-team@latest/actions/guides/storing-workflow-data-as-artifacts"&gt;we can store any number of different build artifacts&lt;/a&gt;. These could be things like testing or linting reports, or maybe your .apk file.&lt;/p&gt;

&lt;p&gt;Storing artifacts is quite straightforward using the &lt;em&gt;&lt;a href="https://github.com/actions/upload-artifact"&gt;upload-artifact&lt;/a&gt;&lt;/em&gt; action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- uses: actions/upload-artifact@v2 with: name: some-artifact path: path/to/artifact/some\_artifact.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sample will store the file &lt;em&gt;some_artifact.txt&lt;/em&gt; in a workflow artifact named &lt;em&gt;some-artifact&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We will use this approach to save a set of files that contain build scan urls for workflows that don’t include a PR.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing Gradle Build Scan URLs to a File
&lt;/h3&gt;

&lt;p&gt;To write our build scan URL to a file, we can make use of the &lt;em&gt;buildScanPublished {}&lt;/em&gt; callback of the Gradle Enterprise plugin.&lt;/p&gt;

&lt;p&gt;We see in this example that we’ve added the &lt;em&gt;buildScanPublished&lt;/em&gt; block, which is called with the current &lt;em&gt;PublishedBuildScan&lt;/em&gt; object, once the scan is published.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gradleEnterprise { buildScan { termsOfServiceUrl = "https://gradle.com/terms-of-service" termsOfServiceAgree = "yes" publishAlways() buildScanPublished { PublishedBuildScan scan -&amp;gt; file("buildscan.log") &amp;lt;&amp;lt; "${new Date()} - ${scan.buildScanUri}\n" } } }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we have the scan, we can use it however we want.&lt;/p&gt;

&lt;p&gt;In this case, we’re creating a new file named &lt;em&gt;buildscan.log&lt;/em&gt; and writing the build scan uri to the file, along with the current timestamp.&lt;/p&gt;

&lt;p&gt;Locally, as multiple build scans are generated, this file will continue to populate that list.&lt;/p&gt;

&lt;p&gt;On CI, where builds are run in a clean environment, this file will include only the most recent build scan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Storing Build Scan Files as Workflow Artifacts
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/n8ebel/GitHubActionsAutomationSandbox/blob/ne/buildscan-recipes/.github/workflows/buildscan-as-file-artifact.yml"&gt;Code Sample Here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that our builds will generate these build scan files, we need to store them as a workflow artifact so we can go back and view them for any arbitrary workflow.&lt;/p&gt;

&lt;p&gt;For each job, we’ll add a build step that stores the &lt;em&gt;buildscan.log&lt;/em&gt; file as a build artifact.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs: test\_job: name: Test runs-on: ubuntu-latest steps: ... - name: Save Build Scan Log uses: actions/upload-artifact@v2 with: name: buildscan-test path: 'buildscan.log' assemble\_job: name: Assemble runs-on: ubuntu-latest steps: ... - name: Save Build Scan Log uses: actions/upload-artifact@v2 with: name: buildscan-assemble path: 'buildscan.log'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To avoid overwriting the artifact, each job writes the &lt;em&gt;buildscan.log&lt;/em&gt; file to a different artifact.&lt;/p&gt;

&lt;p&gt;The result is something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7jphMZmb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.30.07-AM.png%3Fresize%3D800%252C213%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img width="800" height="213" src="https://res.cloudinary.com/practicaldev/image/fetch/s--7jphMZmb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.30.07-AM.png%3Fresize%3D800%252C213%26ssl%3D1" alt="Multiple GitHub Actions workflow artifacts that each contain a Gradle build scan url"&gt;&lt;/a&gt;Multiple workflow artifacts storing build scan files&lt;/p&gt;

&lt;p&gt;This allows us to find the build scan urls for a non-PR workflow without browsing the build logs.&lt;/p&gt;

&lt;p&gt;Unfortuneately, this approach requires us to download multiple artifacts to view all of the workflow’s build scan urls.&lt;/p&gt;

&lt;p&gt;So for one final improvement, we’ll look at how to consolidate all the &lt;em&gt;buildscan.log&lt;/em&gt; files into a single file artifact.&lt;/p&gt;

&lt;h3&gt;
  
  
  Storing Multiple Build Scan Files as a Single Workflow Artifact
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/n8ebel/GitHubActionsAutomationSandbox/blob/ne/buildscan-recipes/.github/workflows/multiple-buildscans-as-single-file-artifact.yml"&gt;Code Sample Here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To store our build scan files in a single artifact, we need to be able to customize the file name of the &lt;em&gt;buildscan.log&lt;/em&gt; files.&lt;/p&gt;

&lt;p&gt;There’s probably many different ways to go about this, and I’ll cover just one here.&lt;/p&gt;

&lt;p&gt;We’ll add an environment variable to the Gradle task build step. This variable will be used as a filename prefix for our &lt;em&gt;buildscan.log&lt;/em&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;jobs: test\_job: name: Test runs-on: ubuntu-latest steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 env: BUILDSCAN\_FILE\_PREFIX: test with: arguments: test ... assemble\_job: name: Assemble runs-on: ubuntu-latest steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 env: BUILDSCAN\_FILE\_PREFIX: assemble-debug with: arguments: assembleDebug ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can update our &lt;em&gt;buildScanPublished{}&lt;/em&gt; configuration to use the prefix when naming the &lt;em&gt;buildscan.log&lt;/em&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;buildScanPublished { PublishedBuildScan scan -&amp;gt; def scanNamePrefix = System.getenv("BUILDSCAN\_FILE\_PREFIX") ? "${System.getenv("BUILDSCAN\_FILE\_PREFIX")}-" : "" def filename = scanNamePrefix + "buildscan.log" file(filename) &amp;lt;&amp;lt; "${new Date()} - ${scan.buildScanUri}\n" }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, each job’s &lt;em&gt;buildscan.log&lt;/em&gt; file should have a unique name corresponding to the environment variable adding to the Gradle execution build step.&lt;/p&gt;

&lt;p&gt;So our last step, is to update the workflow so that each job uploads the unique &lt;em&gt;buildscan.log&lt;/em&gt; files to the same artifact.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs: test\_job: name: Test runs-on: ubuntu-latest steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 env: BUILDSCAN\_FILE\_PREFIX: test with: arguments: test - name: Save Build Scan Log if: ${{ always() }} uses: actions/upload-artifact@v2 with: name: buildscans path: 'test-buildscan.log' assemble\_job: name: Assemble runs-on: ubuntu-latest steps: ... - id: gradle uses: eskatos/gradle-command-action@v1 env: BUILDSCAN\_FILE\_PREFIX: assemble-debug with: arguments: assembleDebug - name: Save Build Scan Log if: ${{ always() }} uses: actions/upload-artifact@v2 with: name: buildscans path: 'assemble-debug-buildscan.log'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when our workflow is completed, we’ll have a single artifact called &lt;em&gt;buildscans&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7HYz9t62--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.10-AM.png%3Fresize%3D800%252C189%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img width="800" height="189" src="https://res.cloudinary.com/practicaldev/image/fetch/s--7HYz9t62--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.10-AM.png%3Fresize%3D800%252C189%26ssl%3D1" alt="A single GitHub Actions workflow artifact that contains multiple build scan urls"&gt;&lt;/a&gt;A single workflow artifact for all build scan files&lt;/p&gt;

&lt;p&gt;Once downloaded, we have access to each &lt;em&gt;buildscan.log&lt;/em&gt; file for the workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hdrTDgEi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i0.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.45-AM.png%3Fresize%3D727%252C117%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img width="727" height="117" src="https://res.cloudinary.com/practicaldev/image/fetch/s--hdrTDgEi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i0.wp.com/goobar.io/wp-content/uploads/2020/10/Screen-Shot-2020-10-10-at-8.47.45-AM.png%3Fresize%3D727%252C117%26ssl%3D1" alt="Build scan files stored within a GitHub Actions workflow artifact"&gt;&lt;/a&gt;The single workflow artifact will contain all the buildscan.log files once unzipped&lt;/p&gt;

&lt;p&gt;Now, for any workflow that’s run, we can download the &lt;em&gt;buildscans&lt;/em&gt; artifact and immediately find the build scan urls for that workflow.&lt;/p&gt;

&lt;h2&gt;Learn More&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://goobar.io/tag/github-actions/" rel="noopener noreferrer"&gt;More GitHub Actions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check Out The Docs &lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;In this post, we’ve explored several different ways of making Gradle build scan urls easier to find within our GitHub Actions workflows.&lt;/p&gt;

&lt;p&gt;The effectiveness of these approaches likely depends upon your team. If your team is using Gradle Enterprise and everyone is comfortable using that tool to find build scans, then surfacing them in workflows may not be that helpful.&lt;/p&gt;

&lt;p&gt;However, if not everyone on your team is familiar with Gradle Enterprise, or you’re not using Gradle Enterprise, then surfacing the build scan urls in a more visible location may in fact help your team quite a bit.&lt;/p&gt;




&lt;p&gt;The post &lt;a href="https://goobar.io/2020/10/13/surfacing-gradle-build-scans-within-github-actions/"&gt;Surfacing Gradle Build Scans Within GitHub Actions Workflows&lt;/a&gt; appeared first on &lt;a href="https://goobar.io"&gt;goobar&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ci</category>
      <category>githubactions</category>
      <category>gradle</category>
    </item>
    <item>
      <title>GitHub CLI – GitHub From The Command Line</title>
      <dc:creator>Nate Ebel</dc:creator>
      <pubDate>Fri, 01 May 2020 16:30:01 +0000</pubDate>
      <link>https://forem.com/goobar_dev/github-cli-github-from-the-command-line-2cl8</link>
      <guid>https://forem.com/goobar_dev/github-cli-github-from-the-command-line-2cl8</guid>
      <description>&lt;p&gt;GitHub &lt;a href="https://github.blog/2020-02-12-supercharge-your-command-line-experience-github-cli-is-now-in-beta/"&gt;recently announced&lt;/a&gt; GitHub CLI; a &lt;a href="https://github.com/cli/cli"&gt;first-party command line tool&lt;/a&gt; for interfacing with GitHub from the command line.&lt;/p&gt;

&lt;p&gt;With GitHub CLI, developers can check the status of GitHub issues and pull requests, search for a specific issue or PR, create/fork a repo, or create new issues and pull requests right from the command line.&lt;/p&gt;

&lt;p&gt;In this post, we’ll walk through some common daily developer workflows. As we do, we’ll focus in on how we might manage our issues and pull requests using GitHub CLI.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/tm9gdHd9qmE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  What Is GitHub CLI?
&lt;/h1&gt;

&lt;p&gt;So we’re all on the same page, we’ll start with a short overview of GitHub CLI. If you’re already familiar with it, jump ahead to the next section.&lt;/p&gt;

&lt;p&gt;GitHub CLI is best described as “GitHub from the command line.”&lt;/p&gt;

&lt;p&gt;Currently, GitHub CLI is at &lt;a href="https://github.com/cli/cli/releases/tag/v0.6.3"&gt;version v0.6.3&lt;/a&gt; and consists of a focused set of functionality around three GitHub artifacts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Issues&lt;/li&gt;
&lt;li&gt;Pull Requests&lt;/li&gt;
&lt;li&gt;Repositories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With GitHub CLI, developers can perform the following commands in relation to this different artifacts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;create&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;list&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;status&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;view&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;checkout&lt;/em&gt; (pull requests only)&lt;/li&gt;
&lt;li&gt;clone (repo only)&lt;/li&gt;
&lt;li&gt;fork (repo only)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As mentioned previously, in this post, we’re only going to focus on commands related to issues and pull requests.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to Install GitHub CLI?
&lt;/h1&gt;

&lt;p&gt;To install GitHub CLI on your development machine, check out the &lt;a href="https://github.com/cli/cli#installation-and-upgrading"&gt;installation guide&lt;/a&gt; found on GitHub. You can also follow along with the &lt;a href="https://www.youtube.com/watch?v=tm9gdHd9qmE"&gt;tutorial on my YouTube channel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;GitHub CLI is available across MacOS, Windows, and various Linux distros, so you shouldn’t have a problem getting the tool up and running on your machine.&lt;/p&gt;

&lt;h1&gt;
  
  
  Using GitHub CLI To Manage GitHub Issues
&lt;/h1&gt;

&lt;p&gt;If working with GitHub Issues is a regular part of your development flows then GitHub CLI likely has several helpful commands for you. Let’s walk through what a typical work day might look like and highlight some examples of using GitHub CLI to work with issues on GitHub.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/nuCQiP41jU0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  List Issues With GitHub CLI
&lt;/h2&gt;

&lt;p&gt;Let’s imagine we are just sitting down at our computer for the day, and we want to list out the open GitHub Issues for our project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh issue list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want to list out ALL of the issues we could use the “state” flag&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh issue list --state "all"gh issue list -s "all"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, maybe we’ve realized that is too many issues to sort through, so we decide we only want to list out your currently assigned issues.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh issue list --assignee "n8ebel"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, you can use the short form&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh issue list -a "n8ebel"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Check Issue Status With GitHub CLI
&lt;/h2&gt;

&lt;p&gt;Next, we want to check in on the status of a couple of the issues we created yesterday.  Maybe we don’t remember their exact numbers, but since we created them, we can use the status command to list them at the terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh issue status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will give us a list of issues that are assigned to us, mentioning us, or that were opened by us.&lt;/p&gt;

&lt;p&gt;After checking in on these issues, we still can’t find the issue we’re looking for, so we might want to check whether it was closed or not.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh issue list --state "closed"gh issue list -s "closed"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s great!  Our issue has been closed, so now we’re ready to find our next task.  We could start looking for new tasks by listing out issuses filtered by different labels.&lt;/p&gt;

&lt;p&gt;To list out all of our open bugs, we could filter by the “bug” label defined in our GitHub repo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh issue list --label "bug"gh issue list -l "bug"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re unsure of what labels are available for the open issues, you could first check by listing all the open issues again&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh issue list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can see there is also an enhancement label we can search for&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh issue list -l "enhancement"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  View Issues With GitHub CLI
&lt;/h2&gt;

&lt;p&gt;Once we’ve found an issue we want to fix, we might want to assign that issue to ourselves.  Currently, we can’t do that directly from the command line, but we can quickly open the issue from the command line using the “view” command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh issue view "15"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will open the issue in a web browser where you can then assign it to yourself.&lt;/p&gt;

&lt;p&gt;After assigning any issues to yourself, you can double check your assignments from the command line by listing out open bugs assigned to you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh issue list -a "n8bel" -l "bug"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create Issues With GitHub CLI
&lt;/h2&gt;

&lt;p&gt;Now, we just have one last command to explore.&lt;/p&gt;

&lt;p&gt;As we’re working on our assigned issues, imagine we find an additional bug we need to report.&lt;/p&gt;

&lt;p&gt;We can use the &lt;strong&gt;&lt;em&gt;gh&lt;/em&gt;&lt;/strong&gt; issue create command to create a new GitHub Issue directly from the command line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh issue create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using this command as is will kick off an interactive terminal workflow to select any available GitHub Issue template, and then fill in the title and issue description.  You’ll finally then have the option to submit the issue, open it the browser, or cancel.&lt;/p&gt;

&lt;p&gt;If you’d like to simplify things a bit, you can specify the issue with the command using additional flags&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; gh issue create -t "Sample Issue Title" -b "Sample issue description"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you still prefer to create your issue from the web, you could use the following command to open up a browser window and jump right into the issue creation workflow in your repo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh issue create --web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Helpful GitHub CLI Aliases
&lt;/h2&gt;

&lt;p&gt;So with these various command and flag variation, we have quite a few options for creating, listing, and viewing our GitHub Issues.&lt;/p&gt;

&lt;p&gt;We can make these commands even easier to work with by creating some command line aliases for them.&lt;/p&gt;

&lt;p&gt;For example, when listing out all bugs, instead of using this full command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh issue list --label "bug"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could create an alias like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alias listbugs='gh issue list --label "bug"'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That way, when we want to list all bugs we can simply type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;listbugs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another example would be to use the following alias to list all bugs assigned to you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alias listmybugs='gh issue list -a "&amp;lt;your username&amp;gt;" -l "bug"'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this alias in place, we can search for all bugs assigned to you like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;listmybugs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Managing Pull Requests With GitHub CLI
&lt;/h1&gt;

&lt;p&gt;Now, let’s explore the use of GitHub CLI for managing pull requests. Again, let’s walk through an imaginary workday and see where this tool make help us.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Ku9_0Mftiic"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  List Pull Requests
&lt;/h2&gt;

&lt;p&gt;Once again, we sit down at our computer for the day, and we want to list the open pull requests for our project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want to list out ALL of the pull requests, both open and closed, we could use the “state” flag&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr list --state "all"gh pr list -s "all"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, maybe we’ve realized that is too many PRs to sort through, so we decide we only want to list out your currently assigned issues.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr list --assignee "n8ebel"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, you can use the short form&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr list -a "n8ebel"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Check Pull Request Status
&lt;/h2&gt;

&lt;p&gt;Next, we want to check in on the status of a couple of the PRs we created yesterday.  Maybe we don’t remember their exact numbers, but since we created them, we can use the status command to list them at the terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will give us a list of PRs that are assigned to us, mentioning us, or that were opened by us.&lt;/p&gt;

&lt;p&gt;After checking in on these PRs, we still can’t find the pull request we’re looking for, so we might want to check whether it was closed or not.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr list --state "closed"gh pr list -s "closed"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s great!  Our PR has been closed, so now we’re ready to find our next task.  We could start looking for new tasks by listing out pull requests filtered by different labels.&lt;/p&gt;

&lt;p&gt;To list out all of our open bug fix PRs, we could filter by the “bug” label defined in our GitHub repo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr list --label "bug"gh pr list -l "bug"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re unsure of what labels are available for the open issues, you could first check by listing all the open PRs again&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can see there is also an enhancement label we can search for&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr list -l "enhancement"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  View Pull Request
&lt;/h2&gt;

&lt;p&gt;Once we’ve found a PR we want to review, we might want to assign that PR to ourself.  Currently, we can’t do that directly from the command line, but we can quickly open the PR from the command line using the &lt;strong&gt;&lt;em&gt;view&lt;/em&gt;&lt;/strong&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr view "14"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will open the pull request in a web browser where you can then assign it to yourself, review it, etc.&lt;/p&gt;

&lt;p&gt;You can double check your assigned pull requests from the command line by listing out PRs assigned to you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr list -a "n8bel" -l "bug"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create Pull Request
&lt;/h2&gt;

&lt;p&gt;As we’re working on our assigned issue, at some point, we’re going to want to create a new pull request based on our local changes.&lt;/p&gt;

&lt;p&gt;We can use the gh pr create command to create a new pull request directly from the command line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using this command as is will kick off an interactive terminal workflow to fill in the title and issue description.  You’ll finally then have the option to submit the PR, open it the browser, or cancel.&lt;/p&gt;

&lt;p&gt;If you’d like to simpify things a bit, you can specificy the PR info with the command using additional flags&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr create -t "Sample Issue Title" -b "Sample issue description"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you still prefer to create your PR from the web, you could use the following command to open up a browser window and jump right into the PR creation workflow in your repo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr create --web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At some point, we’re going to want to test a PR locally.  This generaly requires looking up the PR, checking the branch it’s on, then checking it out locally.&lt;/p&gt;

&lt;p&gt;Using GitHub CLI we can streamline this process using the pr checkout command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr checkout "14"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will checkout the branch associated with PR 14 so you’re ready to start testing.So with these various command and flag variation, we have quite a few options for creating, listing, and viewing our GitHub pull requests.&lt;/p&gt;

&lt;p&gt;We can make these commands even easier to work with by creating some command line aliases for them.&lt;/p&gt;

&lt;p&gt;For example, when listing out all PRs, instead of using this full command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr list --label "bug"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could create an alias like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alias listprs='gh pr list --label "bug"'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That way, when we want to list all bug related PRs we can simply type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;listprs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another example would be to use the following alias to list all PRs assigned to you&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alias listmyprs='gh pr list -a "&amp;lt;your username&amp;gt;"'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this alias in place, we can search for all PRs assigned to you like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;listmyprs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  More GitHub Resources
&lt;/h1&gt;

&lt;p&gt;Check out the follow articles for more ways to leverage GitHub in your development workflows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://Manually%20Trigger%20A%20GitHub%20Actions%20Workflow"&gt;Manually Trigger A GitHub Actions Workflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://goobar.io/2019/12/07/manually-trigger-android-build-tasks-using-github-actions/"&gt;Manually Trigger Android Build Tasks Using GitHub Actions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://goobar.io/2019/12/07/manually-triggering-github-actions-workflows-using-postman/"&gt;Trigger A GitHub Actions Workflow Using Postman&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;a href="https://mailchi.mp/d4dda8b66929/goobario"&gt;Subscribe for more software development posts, videos, and resources&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://goobar.io/2020/04/01/github-cli-github-from-the-command-line/"&gt;GitHub CLI – GitHub From The Command Line&lt;/a&gt; appeared first on &lt;a href="https://goobar.io"&gt;goobar.io&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>github</category>
      <category>programming</category>
      <category>versioncontrol</category>
      <category>tips</category>
    </item>
    <item>
      <title>Android Developer Career Paths</title>
      <dc:creator>Nate Ebel</dc:creator>
      <pubDate>Tue, 14 Jan 2020 01:32:16 +0000</pubDate>
      <link>https://forem.com/goobar_dev/android-developer-career-paths-7bd</link>
      <guid>https://forem.com/goobar_dev/android-developer-career-paths-7bd</guid>
      <description>&lt;p&gt;What Android developer career paths are available and viable in 2020?&lt;/p&gt;

&lt;p&gt;The beginning of a new year offers a fresh start for us all.  A chance to consider where we’ve been, and where we’re going. For me, this typically includes time to examine my career and to think about where I’d like that career to go.&lt;/p&gt;




&lt;p&gt;I’m pretty sure I’m not alone in this either.  Developers are constantly asking questions like “Should I learn framework X or framework Y?” and “Should I be a specialist or a generalist?”.  These questions largely stem from a desire to smartly invest in our careers to set us up for long term success.&lt;/p&gt;

&lt;p&gt;In this week’s issue, I wanted to explore this idea within the context of Android development.  I want to throw out and examine a few general questions like “What languages should I learn?” and “How can I get my name out there?” and then unpack some specific questions to shed light on the different ways in which you might consider building a career as an Android developer, and really just as a &lt;em&gt;developer&lt;/em&gt; in general.&lt;/p&gt;

&lt;p&gt;You ready? Let’s dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Android Development Career Path Questions?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is Android development still a viable career option?
&lt;/h3&gt;

&lt;p&gt;Of all the questions I see about Android development career paths, this is the most common; and I believe the answer is Yes.  Do a quick search for “Android” jobs on LinkedIn, and you’re presented with &lt;a href="https://www.linkedin.com/jobs/search/?geoId=92000000&amp;amp;keywords=android&amp;amp;location=Worldwide"&gt;over 268,000 results&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While Android has been around for over a decade, and the operating system does seem to have reached some level of maturity, the job market doesn’t appear to be slowing down.  There are still many many companies out there looking for skill Android developers.&lt;/p&gt;

&lt;p&gt;So, if you want to build apps that run on Android devices, I think you’ll be able to find a job for at least a few more years.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Native Android development still a viable career path?
&lt;/h3&gt;

&lt;p&gt;This is probably a close second in terms of popular Android career path questions, and is honestly a lot more interesting to me.  Companies are clearly still looking to build apps and tools that work for Android, but are they moving away from native Android development in favor of cross-platform solutions like Flutter or React Native?&lt;/p&gt;

&lt;p&gt;Again, looking at job postings is, I think, a reasonable metric to gauge the market interest in these different skillsets.&lt;/p&gt;

&lt;p&gt;Let’s compare the job posting results for a few different searches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“flutter” – &lt;a href="https://www.linkedin.com/jobs/search/?geoId=92000000&amp;amp;keywords=flutter&amp;amp;location=Worldwide"&gt;2,583 results&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;“react native” – &lt;a href="https://www.linkedin.com/jobs/search/?geoId=92000000&amp;amp;keywords=react%20native&amp;amp;location=Worldwide"&gt;13,927 results&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;“android java” – &lt;a href="https://www.linkedin.com/jobs/search/?geoId=92000000&amp;amp;keywords=android%20java&amp;amp;location=Worldwide"&gt;33,487 results&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;“android kotlin” – &lt;a href="https://www.linkedin.com/jobs/search/?geoId=92000000&amp;amp;keywords=android%20kotlin&amp;amp;location=Worldwide"&gt;9,542 results&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;“android c++” – &lt;a href="https://www.linkedin.com/jobs/search/?geoId=92000000&amp;amp;keywords=android%20c%2B%2B&amp;amp;location=Worldwide"&gt;10,159 results&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By these results, we can see that building Android apps natively with Java, Kotlin, or C++ seems to still be what most employers are looking for.  So I think it’s safe to say that native Android development, and probably native iOS development are both perfectly viable career paths for the coming years.&lt;/p&gt;

&lt;p&gt;Conversely, there’s also clearly demand for cross-platform developers as well, and we’ll explore that more as we continue on.&lt;/p&gt;

&lt;h3&gt;
  
  
  What languages should you learn?
&lt;/h3&gt;

&lt;p&gt;What programming languages should you learn to build a career in Android development?  If going the native Android development route, then you have three options: Java, Kotlin, and C++.  &lt;/p&gt;

&lt;p&gt;If doing typical Android app development, you’ll likely be considering between Java and Kotlin, and with Google’s “Kotlin First” approach to modern Android, I think Kotlin is a good investment of your time and learning effort.  &lt;/p&gt;

&lt;p&gt;If you’re going to be doing lower level SDK work or building high-performance games, you may need to work with C++&lt;/p&gt;

&lt;p&gt;If you’re more interested in building for multiple platforms at the same time using frameworks like Flutter or React Native, your options are a bit more clear.  When building with Flutter, you’ll use Dart, and when building with React Native you’ll most likely use Javascript.&lt;/p&gt;

&lt;p&gt;Now, are these the only languages you need to know?  Maybe to get started, yes. However, having familiarity with multiple languages can improve the way you think about code and how you write code.  As you become familiar with new language features and paradigms, you’ll see how you can apply those to other languages and challenges as well.  &lt;/p&gt;

&lt;p&gt;Being comfortable with at least one scripting language is a great idea as well as it’ll enable you to automate development workflows when the need arises.  Options such as Python, or Unix Shell Scripts could be a great choice here.&lt;/p&gt;

&lt;h3&gt;
  
  
  How can you get your first job?
&lt;/h3&gt;

&lt;p&gt;Breaking into an industry with your first job can be a daunting task.  The process is often filled with stress, uncertainty, and lots of waiting to hear back from recruiters.  A few things I found helpful when searching for my first job include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting realistic expectations about where I’m going to work.  Not everyone can, or should, work at the big companies like Google, Amazon, Facebook, etc.  There are many many wonderful places to work out there, and exploring more options improves your chances of finding that first job.&lt;/li&gt;
&lt;li&gt;Demonstrating job competencies.  A big factor in me landing my first Android development job was the fact that I had published an app to the app store and could explain to interviewers how I had built it, what the app publishing process was like, and what the major challenges were in writing production software.  Having some form of sample project, portfolio, or published work is a great way for recruiters and interviewers to see what you can do. This will hopefully then improve your chances of getting job interviews, and of doing better in those interviews.&lt;/li&gt;
&lt;li&gt;Reach out to people you know in the industry, and ask if they have entry-level or internship opportunities available.  Direct referrals can often get your resume placed at the top of the list which is a huge advantage in getting called for an interview.&lt;/li&gt;
&lt;li&gt;Stay positive.  Like I mentioned before, finding a job is stressful and challenging.  It can make our imposter syndrome flare up in a major way, and make us question whether or not we have the required skills to do the job we want.  Remember that not receiving a job offer does not mean you can’t do the job. There are many factors involved, and sometimes all we can do is stay positive and move on to the next opportunity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How can you get your name out there?
&lt;/h3&gt;

&lt;p&gt;Once you’ve found your first job, you might start looking for ways to add to your career beyond your job.  For this, there are a number of ways you might look to become more involved in the developer community including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open source contributions&lt;/li&gt;
&lt;li&gt;Event organizing&lt;/li&gt;
&lt;li&gt;Speaking&lt;/li&gt;
&lt;li&gt;Blogging&lt;/li&gt;
&lt;li&gt;Video Tutorials&lt;/li&gt;
&lt;li&gt;Mentorship&lt;/li&gt;
&lt;li&gt;Social Media&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any of these are great ways to add your experience and ideas to the public discussions around topics your interested in.  The internet makes it easier than ever to connect with people all over the world and to carve out your own niche of interests, ideas, projects, and ways of giving back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Career Options for Developers
&lt;/h2&gt;

&lt;p&gt;Now that we’ve discussed some of these higher-level questions, I want to get more specific and focus in on some more concrete comparisons of different career paths available to us as software developers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Developer vs Educator
&lt;/h3&gt;

&lt;p&gt;Do you want to get paid to write code, or would you prefer to get paid to teach others how to write code? &lt;/p&gt;

&lt;p&gt;I included this here because it’s becoming more and more viable to make money online by teaching others how to write code and to become software developers.  Whether it’s at established edTech companies like Pluralsight and Udacity or with your own courses, it’s possible to make a living by teaching others.&lt;/p&gt;

&lt;p&gt;Your career path as a developer doesn’t &lt;em&gt;have&lt;/em&gt; to include getting a job to build someone else’s app.  If you have a passion for teaching, mentorship, and helping others, then you might consider either a full-time, or at least a part-time, job in some form of developer education.&lt;/p&gt;

&lt;h3&gt;
  
  
  Freelance vs Company
&lt;/h3&gt;

&lt;p&gt;Do you have to go work for someone else to make money as a developer?  The simple answer is, No. If you’re someone that would prefer to work alone, or to work on a variety or projects, or to have greater flexibility in when/how you work, then freelancing might be the way to go.&lt;/p&gt;

&lt;p&gt;As a freelancer, you’re likely to find greater flexibility in your work.  This may also manifest as uncertainty. You may not always know where your next project and paycheck are coming from.  You may get bogged down in the more administrative side of running your own freelancing business.  &lt;/p&gt;

&lt;p&gt;You may also find that the freedom provided by freelancing is a great fit. You may really enjoy the business aspect of freelancing, and in particular, you might find freelancing enables you greater freedom to pursue other interests such as content creation or travel.&lt;/p&gt;

&lt;h3&gt;
  
  
  FAANG vs Startup
&lt;/h3&gt;

&lt;p&gt;If you prefer to work at a company, what type of company do you want to work for?  Do you want to be in the fast-paced, VC-backed startup world? Do you want to work at the major tech giants like Google, Microsoft, and Amazon?  Do you want to work for a less exciting, but very stable company?&lt;/p&gt;

&lt;p&gt;Not all companies are created equally.  Similarly, different business groups, organizations, and teams may operate very differently even within the same company.&lt;/p&gt;

&lt;p&gt;When deciding what type of company to work for there are many questions you can ask yourself and use to filter out the options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do you want to work at a well known company?&lt;/li&gt;
&lt;li&gt;Do you prefer to work on a small team or a large team?&lt;/li&gt;
&lt;li&gt;Would you rather get paid more, or work from home?&lt;/li&gt;
&lt;li&gt;Do you prefer to know everyone you work with, or would you rather work in a large organization?&lt;/li&gt;
&lt;li&gt;What’s more important, fun perks like snacks and ping pong, or reasonable working hours?&lt;/li&gt;
&lt;li&gt;How much project ownership will you have?&lt;/li&gt;
&lt;li&gt;Would you prefer to go deep or wide on a project?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m sure you can think of many questions of your own.  What do you value in your work? What tradeoffs are you willing to make.  What have you liked about past companies, and what have you disliked? Taking time to consider these things will help guide your future decisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  IC vs Manager
&lt;/h3&gt;

&lt;p&gt;When you think about your career, do you see yourself writing code forever?  Do you see yourself managing others? Do you want a mix of both? These are great questions to consider as many companies have different career paths to help fit what you’re looking for.  The most common split is between an Individual Contributor (IC) role and a Manager role.&lt;/p&gt;

&lt;p&gt;The exact requirements and responsibilities of each path will differ based on company, but in general, the IC path is going to be more focused on your writing code, while the management path will be more focused on making other developers more successful.&lt;/p&gt;

&lt;p&gt;Both have their pros and cons, and both are completely viable.&lt;/p&gt;

&lt;p&gt;Whoa!  In this short article we’ve already touched on a lot of questions, comparisons, and potential career paths.&lt;/p&gt;

&lt;p&gt;If you’re feeling a little overwhelmed that’s perfectly okay.  I think we all become a little overwhelmed, lost, or even discouraged at times when considering our careers.  There’s a lot to navigate in this game of life. The great thing is, we have time and resources available to us to learn new skills, pivot in a new direction, and build a career that we love.  The trick is to be intentional about it. That doesn’t mean you have to plan out your whole career, that would be impossible given the rate of technological change, but you should regularly take time to think about what’s important to you, what you enjoy doing, and to survey the landscape of the industry around you and look for those areas where your passions, values, and financial needs align.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;What in the world of Android development are you interested in right now? Join in the conversation in the comments below.&lt;/em&gt;&lt;/strong&gt;  &lt;/p&gt;




&lt;p&gt;The post &lt;a href="https://goobar.io/2020/01/13/android-developer-career-paths/"&gt;Android Developer Career Paths&lt;/a&gt; appeared first on &lt;a href="https://goobar.io"&gt;goobar.io&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>android</category>
    </item>
    <item>
      <title>Android Development Podcasts — 7 Options to Choose From</title>
      <dc:creator>Nate Ebel</dc:creator>
      <pubDate>Tue, 09 Jul 2019 01:48:45 +0000</pubDate>
      <link>https://forem.com/goobar_dev/android-development-podcasts-7-options-to-choose-from-43k0</link>
      <guid>https://forem.com/goobar_dev/android-development-podcasts-7-options-to-choose-from-43k0</guid>
      <description>&lt;h3&gt;
  
  
  Android development podcasts to help you stay up to date
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rUalMrQU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A7xVoCC5dZnObU91Xso5HMg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rUalMrQU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A7xVoCC5dZnObU91Xso5HMg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://goobar.io/2019/07/08/android-development-podcasts-7-options-to-choose/"&gt;&lt;em&gt;https://goobar.io&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on July 9, 2019.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I’ve had a number of questions lately about which podcasts I’ve been listening to, and where to find them, so I thought I’d share a small list of relevant Android development podcasts for you to check out.&lt;/p&gt;

&lt;p&gt;tl;dr — 7 Android Development Podcasts&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://fragmentedpodcast.com/"&gt;Fragmented&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://androidbackstage.blogspot.com/"&gt;Android Developers Backstage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://talkingkotlin.com/"&gt;Talking Kotlin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/artem-zinnatullin/TheContext-Podcast"&gt;The Context&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://droidkast.live/"&gt;droidkast.LIVE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soundcloud.com/andro-idiots"&gt;Andro idiots&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://androidleakspodcast.com/"&gt;Android Leaks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C6mzs3Qz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wqx29ymusqu80j73onse.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C6mzs3Qz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wqx29ymusqu80j73onse.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Fragmented
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://fragmentedpodcast.com/"&gt;Fragmented Podcast&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This has been my go-to Android development podcast for a long time. &lt;a href="https://twitter.com/donnfelker"&gt;Donn Felker&lt;/a&gt; and &lt;a href="https://twitter.com/kaushikgopal"&gt;Kaushik Gopal&lt;/a&gt; do a terrific job of putting out consistently great episodes on all manner of Android-related topics. They generally sit down with other Android developers to discuss tools, libraries, patterns, etc.; all relevant to the world of Android development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Android Developers Backstage
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://androidbackstage.blogspot.com/"&gt;Android Developers Backstage Podcast&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This podcast comes straight out of the Googlers’ mouths as it’s hosted by &lt;a href="https://twitter.com/chethaase"&gt;Chet Haase&lt;/a&gt; and &lt;a href="https://twitter.com/tornorbye"&gt;Tor Norbye&lt;/a&gt; from the Android teams at Google.&lt;/p&gt;

&lt;p&gt;I enjoy this podcast because it generally offers deep dives into Android topics usually including guests that actually work on the tools/libraries. Because of this, I think it offers a level of insight that’s difficult to replicate elsewhere.&lt;/p&gt;

&lt;h3&gt;
  
  
  Talking Kotlin
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://talkingkotlin.com/"&gt;Talking Kotlin Podcast&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Talking Kotlin with &lt;a href="https://twitter.com/hhariri"&gt;Hadi Hariri&lt;/a&gt; is a wonderful resource if you’re wanting to learn more about Kotlin specifically. It covers everything from the world of Kotlin include Kotlin on Android, Kotlin Multiplatform, KotlinConf, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Context
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/artem-zinnatullin/TheContext-Podcast"&gt;The Context Podcast&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Context is another community-driven Android development podcast hosted by the trio of &lt;a href="https://twitter.com/artem_zin"&gt;Artem Zinnatullin&lt;/a&gt;, &lt;a href="https://twitter.com/sockeqwe"&gt;Hannes Dorfmann&lt;/a&gt;, and &lt;a href="https://twitter.com/arturdryomov"&gt;Artur Dryomov&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is another great option if you are wanting to hear what other developers are working on and thinking about in the world of Android.&lt;/p&gt;




&lt;h3&gt;
  
  
  Bonus Android Development Podcasts
&lt;/h3&gt;

&lt;p&gt;I also want to include a few other podcasts that might be worth checking out.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://androidleakspodcast.com/"&gt;Android Leaks Podcast&lt;/a&gt; — a French Android development podcast that I recently came across. I don’t speak French, so I don’t really know a whole lot about it but it’s out there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://soundcloud.com/andro-idiots"&gt;Andro idiots Podcast&lt;/a&gt; — This is a new one which someone pointed out to me recently. It’s pretty new, but has a nice backlog of episodes going and covers a variety of Android topics.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://droidkast.live/"&gt;droidkast.LIVE&lt;/a&gt; — &lt;a href="https://twitter.com/lime_cl"&gt;Antonio Levia&lt;/a&gt; has a small backlog of episodes consisting of interviews with other Android developers which culminate in a smaller learning presentation at the end.&lt;/p&gt;




&lt;h3&gt;
  
  
  Where to Listen?
&lt;/h3&gt;

&lt;p&gt;For those using Android devices, I highly recommend Pocket Casts as a podcast app. I’ve been using it for years to listen to Android development podcasts (really all of my podcasts) and have been extremely happy with it.&lt;/p&gt;

&lt;p&gt;As an alternative, I’ve used Google Play Music for podcasts in the past which does a pretty good job as well.&lt;/p&gt;

&lt;p&gt;I haven’t been overly impressed so far with the Google Podcasts app, but it’s out there as well and might be getting more attention from Google right now than Google Play Music’s podcast support.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/9pO5W2-86ds"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Other Useful Resources
&lt;/h3&gt;

&lt;p&gt;I love to meet/talk/discuss and help where I can. If you want to chat or ask a question you can follow me on &lt;a href="http://twitter.com/n8ebel"&gt;Twitter,&lt;/a&gt; &lt;a href="https://www.youtube.com/channel/UCVysWoMPvvHQMEJvRkslbAQ"&gt;YouTube&lt;/a&gt;, &lt;a href="https://www.instagram.com/n8ebel/"&gt;Instagram&lt;/a&gt; and &lt;a href="https://www.facebook.com/goobar.io/"&gt;Facebook&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/c/goobario"&gt;&lt;strong&gt;Check Out My YouTube Channel&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
    </item>
    <item>
      <title>Kotlin vs Flutter? Are you comparing them fairly?</title>
      <dc:creator>Nate Ebel</dc:creator>
      <pubDate>Fri, 14 Jun 2019 02:59:48 +0000</pubDate>
      <link>https://forem.com/n8ebel/kotlin-vs-flutter-are-you-comparing-them-fairly-4oj5</link>
      <guid>https://forem.com/n8ebel/kotlin-vs-flutter-are-you-comparing-them-fairly-4oj5</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://goobar.io/2019/06/13/kotlin-vs-flutter-are-you-comparing-them-fairly/"&gt;&lt;em&gt;https://goobar.io&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on June 14, 2019.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Lately, I’ve seen, and been asked, variations of the following question: “Kotlin vs Flutter?”&lt;/p&gt;

&lt;p&gt;It’s happened enough times that I thought I’d try and capture some of my thoughts regarding this question.&lt;/p&gt;

&lt;p&gt;So here it goes…&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/0v7d7vrOV9Q"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Kotlin vs Flutter: Which should you learn?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://handstandsam.com/2019/03/10/it-depends-is-the-answer-to-your-android-question/"&gt;It depends&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Comparing Kotlin toFlutter is comparing apples to oranges”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But before going too much further into the “It Depends” rabbit hole, I think it’s worth examining whether or not we’re even asking the right question.&lt;/p&gt;

&lt;p&gt;Comparing Kotlin vs Flutter is comparing apples to oranges in many respects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://flutter.dev/"&gt;&lt;strong&gt;&lt;em&gt;Flutter is an entire cross platform UI toolkit.&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because the differences between Kotlin vs Flutter are so large, the scope of the original question is quite larger; making it difficult to answer without exploring a variety of other questions first.&lt;/p&gt;

&lt;p&gt;Choosing between Kotlin and Flutter is going to come down to a number of more specific questions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why do you want to learn either Kotlin or Flutter?
&lt;/h2&gt;

&lt;p&gt;One of the first questions to ask yourself might be “why do you want to learn Kotlin or Flutter to begin with?”&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do you want to learn mobile development?&lt;/li&gt;
&lt;li&gt;Do you want to get a job as a mobile developer?&lt;/li&gt;
&lt;li&gt;Are you wanting to develop your own product as a solo dev or small team?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Do you want to learn mobile development?
&lt;/h3&gt;

&lt;p&gt;If your primary goal is to simply dabble in mobile development, or to build a small hobby project, then the choice between Kotlin and Flutter likely doesn’t matter too much.&lt;/p&gt;

&lt;p&gt;However, it’s important to remember that you’re not just picking between Flutter and Kotlin. You’re picking between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flutter/Dart&lt;/li&gt;
&lt;li&gt;iOS/Swift/Objective-C&lt;/li&gt;
&lt;li&gt;Android/Kotlin/Java&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Flutter is an entire toolkit for developing applications. This includes the usage of Dart as a programming language, a new set of UI components, a unique set of programming patterns and best practices, and its own debugging tools and workflows.&lt;/p&gt;

&lt;p&gt;To compare Flutter fairly to other platform toolkits, you need to take into account the entire ecosystem that you’re investing into.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kotlin vs Flutter to get a job as a mobile developer?
&lt;/h3&gt;

&lt;p&gt;If your primary goal is to get a job as a mobile developer, then it’s likely a good idea to take into account the demand for the different skill sets.&lt;/p&gt;

&lt;p&gt;A quick LinkedIn search for jobs related to Kotlin and Flutter turn up the following results (in the USA)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flutter: 315 results&lt;/li&gt;
&lt;li&gt;Kotlin: 3,342 results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Flutter is still a new technology, and it represents a much larger change to the mobile development process than does the introduction of Kotlin to an Android project. Because of these things, there are fewer jobs available that mention Flutter.&lt;/p&gt;

&lt;p&gt;This difference in job availability could mean 2 things&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It could be harder to find a Flutter job in your area&lt;/li&gt;
&lt;li&gt;It could be easier to get your foot in the door somewhere if you know Flutter well&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are somewhat contradictory, and what’s most applicable to you likely depends on your current life situation, how quickly you need to find a job, and how willing you are to relocate for that job.&lt;/p&gt;

&lt;p&gt;On the other hand, there is still a lot of demand for native Android developers, and many of those jobs are looking for people that know, or are willing to learn, Kotlin. This greater number of jobs means more options for you to choose from, but also possibly greater competition for those jobs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kotlin vs Flutter to develop your own product as a solo dev or small team?
&lt;/h3&gt;

&lt;p&gt;If you are deciding between Kotlin and Flutter because you want to build your own app that will turn into a business, then it’s a good idea to step back and consider the full picture.&lt;/p&gt;

&lt;p&gt;If you want to build a product, then you very likely are going to want to build for iOS and Android.&lt;/p&gt;

&lt;p&gt;You can do this with Flutter, but you can’t do this with Kotlin alone.&lt;/p&gt;

&lt;p&gt;If you want to use Kotlin for cross-platform development, you’ll need to have familiarity with both the native iOS and Android frameworks. You could build a Kotlin Multiplatform project and share code via Kotlin, or you could build two completely separate apps. Either way, you’re going to need to understand native development for both iOS and Android.&lt;/p&gt;

&lt;p&gt;So, if you’re wanting to build something for multiple platforms at the same time, Flutter might be the way to go. We’ll look at this in more detail in the next section.&lt;/p&gt;




&lt;h2&gt;
  
  
  What do you want to build?
&lt;/h2&gt;

&lt;p&gt;Likely related to &lt;em&gt;why&lt;/em&gt; you want to learn Kotlin or Flutter is what do you want to build?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do you want to build an awesome Android app?&lt;/li&gt;
&lt;li&gt;Do you want to build an awesome iOS app?&lt;/li&gt;
&lt;li&gt;Do you want to build a mobile app for iOS and Android at the same time?&lt;/li&gt;
&lt;li&gt;Do you want to build for platforms beyond mobile?&lt;/li&gt;
&lt;li&gt;Will you want to write your own backend services?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Do you want to build an awesome Android app?
&lt;/h3&gt;

&lt;p&gt;If your main goal is to build a standalone Android app with the latest and greatest features Android has to offer, choose native Android.&lt;/p&gt;

&lt;p&gt;That doesn’t have to mean native Android + Kotlin. Android + Java is perfectly fine for building quality apps. However, I do believe learning Kotlin will make the development experience more enjoyable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do you want to build an awesome iOS app?
&lt;/h3&gt;

&lt;p&gt;Similarly, if you want to build a standalone iOS app with all the latest features, then I would suggest going for native iOS development with Swift.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do you want to build for both iOS and Android at the same time?
&lt;/h3&gt;

&lt;p&gt;If you want to build for both mobile platforms at the same time the question is a little more interesting. You have 3 main options involving Kotlin and Flutter.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build both a native Android app and a native iOS app&lt;/li&gt;
&lt;li&gt;Build two native apps, but use Kotlin Multiplatform to share code&lt;/li&gt;
&lt;li&gt;Build a Flutter app&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Building 2 separate native apps
&lt;/h4&gt;

&lt;p&gt;This option is going to require you, or your team, to build both apps from scratch without any shared code. If you’re a solo dev, it’s likely going to be the slowest option unless you’re already well versed in both iOS and Android development.&lt;/p&gt;

&lt;p&gt;It’s also probably the safest option. Native development for both platforms is very mature. It’s unlikely that Apple or Google will abandon either platform out of the blue, and you’ll have access to new features as soon as possible.&lt;/p&gt;

&lt;h4&gt;
  
  
  Build 2 separate native apps with Kotlin Multiplatform
&lt;/h4&gt;

&lt;p&gt;If you want to build your apps natively, but want to share as much code as possible you can chose to learn Kotlin and build a Kotlin Multiplatform project.&lt;/p&gt;

&lt;p&gt;This is probably not the best option for less experienced developers. The Kotlin Multiplatform ecosystem is pretty new, and you might find yourself with fewer existing tools/libraries to choose from.&lt;/p&gt;

&lt;h4&gt;
  
  
  Build a Flutter app
&lt;/h4&gt;

&lt;p&gt;Building a Flutter app is likely the quickest way to get an app running on both iOS and Android at the same time; especially if you are a solo dev.&lt;/p&gt;

&lt;p&gt;Development times are quite fast with Flutter, thanks in large part to it’s great hot reload functionality. You’re also able to leverage a single codebase for both platforms. As long as you aren’t needing really low level access to system apis, or treating the look/feel of each platform too differently, you shouldn’t need to write a lot of custom code for platform-specific needs.&lt;/p&gt;

&lt;p&gt;If you’re looking to quickly build an app for both platforms, especially a one-and-done app, Flutter is probably the way to go.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do you want to build for platforms beyond mobile?
&lt;/h3&gt;

&lt;p&gt;The Flutter team continues to invest in making Flutter viable to both desktop and web development. While this functionality is still being developed, the possibility is there to use your single Flutter codebase for additional platforms.&lt;/p&gt;

&lt;p&gt;You could consider a Kotlin Multiplatform project to develop beyond mobile as well, but the value proposition is different. With KMP, you would be sharing code, but still having to write native platform code to create your UI and leverage the shared code. As you add more target platforms, this is going to increase the work/skill sets needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Will you want to write your own backend services?
&lt;/h3&gt;

&lt;p&gt;An edge case to consider is whether you might want to write your own backend services for your projects.&lt;/p&gt;

&lt;p&gt;Kotlin can be used to write backend code, and &lt;a href="https://ktor.io/"&gt;Ktor&lt;/a&gt; can make this quite easy. So if you’re going to be developing backend services in addition to some kind of mobile app, Kotlin could be a good investment since you can reuse the skill across multiple domains.&lt;/p&gt;




&lt;h2&gt;
  
  
  Do you already have development experience?
&lt;/h2&gt;

&lt;p&gt;Another thing to consider is your current level of development experience as it applies to your primary motivation for learning either Kotlin or Flutter.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are you already an Android developer?&lt;/li&gt;
&lt;li&gt;Are you already an iOS dev?&lt;/li&gt;
&lt;li&gt;Are you new to programming?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Already an Android developer?
&lt;/h3&gt;

&lt;p&gt;If you’re already comfortable with native Android development, then learning Kotlin is going to be a much faster than learning Flutter. Knowing Kotlin will simply add to your existing knowledge and skill set and perhaps make you more efficient when building native Android apps.&lt;/p&gt;

&lt;p&gt;Learning Kotlin could also allow you to write backend services in another language besides Java, and would enable you to use Ktor to simplify the process.&lt;/p&gt;

&lt;p&gt;Learning Flutter will require learning a new language (Dart) as well as a new development ecosystem. The time required is likely going to be several times greater than to learn Kotlin.&lt;/p&gt;

&lt;p&gt;If you’re not wanting to start leveraging the cross-platform benefits of Flutter, then it doesn’t make too much sense to learn Flutter only for Android.&lt;/p&gt;

&lt;h3&gt;
  
  
  Already an iOS developer?
&lt;/h3&gt;

&lt;p&gt;If you’re an iOS developer looking to learn either Flutter or Kotlin the situation is a bit different.&lt;/p&gt;

&lt;p&gt;If you’re wanting to continue building native iOS apps, then neither Kotlin or Flutter are of much benefit. Kotlin would at least give you another language with which to write backend code.&lt;/p&gt;

&lt;p&gt;If you are an iOS dev that wants to start writing cross platform applications, then you could go the route of a Kotlin Multiplatform project or a Flutter project.&lt;/p&gt;

&lt;p&gt;Like we discussed previously, Flutter is going to be its own isolated development experience for both mobile platforms while a KMP project is going to require knowledge of both Kotlin and the native development stacks.&lt;/p&gt;

&lt;p&gt;So in this case, either way you’re learning a new language (Dart or Kotlin) and a new framework (Flutter or Android).&lt;/p&gt;

&lt;h3&gt;
  
  
  Are you new to programming?
&lt;/h3&gt;

&lt;p&gt;If you’re completely new to programming in general, then again you likely need to take a step back and consider comparing Flutter to native Android development.&lt;/p&gt;

&lt;p&gt;Learning Kotlin on its own isn’t all that useful if you aren’t applying it to something like mobile or backend development.&lt;/p&gt;

&lt;p&gt;So if you’ll want to develop mobile apps, then you’ll want to compare choosing between Flutter and native Android development.&lt;/p&gt;




&lt;h2&gt;
  
  
  How do you learn?
&lt;/h2&gt;

&lt;p&gt;How do you learn best? This could be an important question before diving into a new learning path for Kotlin or Flutter.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Looking for in-depth guided courses?&lt;/li&gt;
&lt;li&gt;Want to learn as part of your university curriculum?&lt;/li&gt;
&lt;li&gt;Will you look to seasoned vets for advice and best practices?&lt;/li&gt;
&lt;li&gt;Do you regularly turn to blog posts?&lt;/li&gt;
&lt;li&gt;Do you prefer to learn by doing?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Looking for in-depth guided courses?
&lt;/h3&gt;

&lt;p&gt;If you prefer to learn with detailed, guided courses, you’re likely going to have more to choose from in the native development world.&lt;/p&gt;

&lt;p&gt;Because Flutter is a new technology, there aren’t as many resources out here yet.&lt;/p&gt;

&lt;p&gt;To be fair, there aren’t all that many Kotlin-specific courses out there either, but Kotlin is a much smaller concept to learn. If learning Kotlin, it’s likely within the context of Android development for which there are a plethora of courses available.&lt;/p&gt;

&lt;h3&gt;
  
  
  Want to learn as part of your university curriculum?
&lt;/h3&gt;

&lt;p&gt;I’ve talked to a few people that were interested in learning native Android development at university. If you have this opportunity, I say go for it. When coming out of school, you’re likely looking for employment. Having a marketable skill like Android development is great for that, and you shouldn’t worry about whether native is outdated and you should have learned Flutter.&lt;/p&gt;

&lt;p&gt;Get a job first, then upskill as necessary while someone is paying you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Will you look to seasoned vets for advice and best practices?
&lt;/h3&gt;

&lt;p&gt;The developer communities around Android, Kotlin, iOS, Flutter are a great resource for learning, mentorship, problem solving, etc.&lt;/p&gt;

&lt;p&gt;When looking for people to follow, or turn to for guidance, you’re likely going to have an easier time in the native Android/iOS worlds. Again, this is because Flutter is a newer technology and there just aren’t as many people working with it yet.&lt;/p&gt;

&lt;p&gt;That’s not to say you’re without options however. There are &lt;a href="https://twitter.com/walmyrcarvalho/lists/flutter-gdes/members"&gt;many great devs out there working in Flutter&lt;/a&gt;, and the devrel team at Google is going a lot of work to recognize those developers through the &lt;a href="https://developers.google.com/programs/experts/directory/"&gt;GDE program&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In either case, here are some lists of devs to follow for Kotlin and Flutter info:&lt;/p&gt;

&lt;h3&gt;
  
  
  Do you regularly turn to blog posts?
&lt;/h3&gt;

&lt;p&gt;Blog posts are a great resource when learning any new technology. When thinking of Kotlin vs Flutter, there are a couple of things to keep in mind.&lt;/p&gt;

&lt;p&gt;Flutter is relatively new, so there are fewer resources out there. Additionally, as it has evolved quickly, some of those resources might be out of date.&lt;/p&gt;

&lt;p&gt;Kotlin likely has more resources available, but also is evolving quickly and posts regarding advanced topics might be out of date after only a few months.&lt;/p&gt;

&lt;p&gt;If looking into Kotlin for its use in Android and/or iOS development you’ll have years worth of posts to sift through. Many of these will still be relevant, but others wont. So again, you’re left with having to determine how accurate and up-to-date these resources are when you find them.&lt;/p&gt;

&lt;p&gt;Thankfully, I think whichever you choose, Kotlin or Flutter, the developer communities and devrel teams will continue to help us out by writing blog posts, building codelabs, and recording video tutorials.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do you prefer to learn by doing?
&lt;/h3&gt;

&lt;p&gt;If you are someone that prefers to learn by jumping in and building something, then you’re in luck. Both Kotlin and Flutter are very easy to try.&lt;/p&gt;




&lt;h2&gt;
  
  
  Have you considered the risks of choosing Kotlin vs Flutter?
&lt;/h2&gt;

&lt;p&gt;When adopting any new technology, there are risks involved. It might be worth considering some of theses risks before choosing between Kotlin and Flutter.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What’s the organizational risk of adopting Kotlin or Flutter?&lt;/li&gt;
&lt;li&gt;Is there any risk associated with your personal choice between Kotlin or Flutter?&lt;/li&gt;
&lt;li&gt;Is there any risk of losing long-term support?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If considering adopting Kotlin or Flutter in your organization, it’s worth stopping to consider the associated risks.&lt;/p&gt;

&lt;p&gt;Kotlin has been stable, and fully supported for Android for 2 years now. It can be integrated 1 file at a time and will work well with existing code. It’s pretty low risk and low impact to add it to your existing projects.&lt;/p&gt;

&lt;p&gt;Flutter is a much larger risk because it’s a departure from the native development experience. It doesn’t have a long track record of successful projects. There are fewer developers familiar with the technology making it harder to recruit and requiring your existing team to learn a new framework/tools/language. Flutter works best in greenfield applications which makes it harder to adopt incrementally.&lt;/p&gt;

&lt;p&gt;These are all non-trivial concerns to think about.&lt;/p&gt;

&lt;p&gt;Additionally, Google has a track record of killing off projects with little notice, so there might be some small concern that Google gives up on either Flutter or Kotlin.&lt;/p&gt;

&lt;p&gt;Realistically, I think Google will continue to support both of these for the next 2+ years at least, so if you’re considering Kotlin vs Flutter today I wouldn’t be too worried about either of them going away.&lt;/p&gt;




&lt;h2&gt;
  
  
  So, Should you learn Kotlin or Flutter?
&lt;/h2&gt;

&lt;p&gt;At this point, hopefully this post has given you some food for thought that will help guide your decision of whether to learn Kotlin or Flutter.&lt;/p&gt;

&lt;p&gt;Ultimately, it depends, but I can try and give the oversimplified, tldr; version of my opinions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If looking for a job as a mobile developer right now:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you want to build your own cross-platform app from scratch:&lt;/strong&gt;  &lt;strong&gt;If your team wants to build a new app for both mobile platforms:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;consider Flutter, native, Kotlin Multiplatform&lt;/li&gt;
&lt;li&gt;all three options are potentially viable. this one really depends on your team size, structure, and the project itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;If you, or your team, wants to share some important business logic across platforms&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;A big thanks to &lt;a href="https://twitter.com/divyajain2405"&gt;Divya Jain&lt;/a&gt;, &lt;a href="https://twitter.com/Blackburn_Dev"&gt;Shane Blackburn&lt;/a&gt;, and &lt;a href="https://twitter.com/AashishBans"&gt;Aashish Bansal&lt;/a&gt; for offering to review and give feedback 👍&lt;/p&gt;

&lt;p&gt;I love to meet/talk/discuss and help where I can. If you want to chat or ask a question you can follow me on &lt;a href="http://twitter.com/n8ebel"&gt;Twitter,&lt;/a&gt; &lt;a href="https://www.youtube.com/channel/UCVysWoMPvvHQMEJvRkslbAQ"&gt;YouTube&lt;/a&gt;, &lt;a href="https://www.instagram.com/n8ebel"&gt;Instagram&lt;/a&gt; and &lt;a href="https://www.facebook.com/goobar.io/"&gt;Facebook&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/c/goobario"&gt;&lt;strong&gt;Check Out My YouTube Channel&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>flutter</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Code Folding in Android Studio</title>
      <dc:creator>Nate Ebel</dc:creator>
      <pubDate>Wed, 26 Sep 2018 19:57:46 +0000</pubDate>
      <link>https://forem.com/n8ebel/code-folding-in-android-studio-369h</link>
      <guid>https://forem.com/n8ebel/code-folding-in-android-studio-369h</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.youtube.com/c/NateEbel" rel="noopener noreferrer"&gt;Check Out My YouTube Channel&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Focus On What Matters”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When working in our IDE, at times it’s easy to become overwhelmed with all the code on the screen.  To better focus on what’s most important, it can be useful to hide non-essential blocks of code from our editor window.&lt;/p&gt;

&lt;p&gt;The Code Folding shortcuts in Android Studio  help us do just that.&lt;/p&gt;

&lt;p&gt;The allow us to fold Code Blocks &amp;amp; Region Blocks so we can have more fine grained control over what code we are looking at in any given moment.&lt;/p&gt;

&lt;h1&gt;
  
  
  Shortcuts
&lt;/h1&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2F23ndk1tu0zxm0uzcowiy.png" class="article-body-image-wrapper"&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%2Farticles%2F23ndk1tu0zxm0uzcowiy.png" alt="code folding shorcuts" width="800" height="88"&gt;&lt;/a&gt;&lt;/p&gt;
code folding shortcuts



&lt;p&gt;The expand &amp;amp; collapse shortcuts allow us to quickly show or hide code blocks or code regions.&lt;/p&gt;

&lt;p&gt;We can expand all or collapse all by adding shift to the shortcuts above.&lt;/p&gt;

&lt;h1&gt;
  
  
  Code Blocks
&lt;/h1&gt;

&lt;p&gt;We can take an expanded block of code like this anonymous inner class&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Fkc3brc3sjqfvdqhyxwnt.png" class="article-body-image-wrapper"&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%2Farticles%2Fkc3brc3sjqfvdqhyxwnt.png" alt="expanded code block" width="768" height="198"&gt;&lt;/a&gt;&lt;/p&gt;
expanded code block



&lt;p&gt;and collapse it within the IDE, using the collapse shortcut, so it visually looks like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Fj8k0weof0bb0vjygjlvq.png" class="article-body-image-wrapper"&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%2Farticles%2Fj8k0weof0bb0vjygjlvq.png" alt="collapsed code block" width="800" height="36"&gt;&lt;/a&gt;&lt;/p&gt;
collapsed code block



&lt;p&gt;We lose the immediate view of the code, but if that code is not relevant to us in this moment, then it can actually help reduce the visual noise in our IDE.&lt;/p&gt;

&lt;p&gt;To collapse a specific block of code, place your cursor within the block and execute the shortcut.&lt;/p&gt;

&lt;p&gt;If you run the shortcut multiple times, the IDE may continue to collapse blocks of code in increasing scope until everything in the current file is collapse.  The same logic applies when expanding code as well.&lt;/p&gt;

&lt;h1&gt;
  
  
  Region Blocks
&lt;/h1&gt;

&lt;p&gt;We can define custom region blocks using comments.  These regions can be helpful for documenting &amp;amp; group related sections of code; such as the implementation of an interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Ffit9b4hnnz897jtptlyc.png" class="article-body-image-wrapper"&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%2Farticles%2Ffit9b4hnnz897jtptlyc.png" alt="expanded region block" width="642" height="263"&gt;&lt;/a&gt;&lt;/p&gt;
expanded region block



&lt;p&gt;Using the collapse command, we can collapse the entire region so only the region label is visible within our editor.&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Fwyjy0gd15qywgjdznvpl.png" class="article-body-image-wrapper"&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%2Farticles%2Fwyjy0gd15qywgjdznvpl.png" alt="collapsed region block" width="679" height="53"&gt;&lt;/a&gt;&lt;/p&gt;
collapsed region block






&lt;p&gt;For more on code folding, check out my video on YouTube&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/oyKmEc7399Q"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;p&gt;I love to talk Android, tech, or geekery, so if you have feedback or want to chat you can follow me on &lt;a href="https://twitter.com/n8ebel" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, here on &lt;a href="https://dev.to/n8ebel"&gt;dev.to&lt;/a&gt;, or check out &lt;a href="//www.n8ebel.com"&gt;my blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.youtube.com/c/NateEbel" rel="noopener noreferrer"&gt;Check Out My YouTube Channel&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>android</category>
    </item>
  </channel>
</rss>
