<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Levi Albuquerque</title>
    <description>The latest articles on DEV Community by Levi Albuquerque (@levimoreira).</description>
    <link>https://dev.to/levimoreira</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%2F61847%2F5f608be7-55c0-4c55-bbb7-90d90576810d.jpeg</url>
      <title>DEV Community: Levi Albuquerque</title>
      <link>https://dev.to/levimoreira</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/levimoreira"/>
    <language>en</language>
    <item>
      <title>Kotlin Data Structures - Arrays and Strings</title>
      <dc:creator>Levi Albuquerque</dc:creator>
      <pubDate>Sat, 13 Jul 2019 15:16:53 +0000</pubDate>
      <link>https://dev.to/levimoreira/kotlin-data-structures-arrays-and-strings-3729</link>
      <guid>https://dev.to/levimoreira/kotlin-data-structures-arrays-and-strings-3729</guid>
      <description>&lt;p&gt;Hey, so this is the first post in a series containing a basic introduction to Kotlin data structures. I'll try to be the most hands on as possible, so for that reason I'll be using problems from Cracking the Code Interview as examples of usage of such data structures. Today we'll be starting with two of the most basic ones: Arrays and Strings.&lt;/p&gt;

&lt;h1&gt;
  
  
  Strings
&lt;/h1&gt;

&lt;p&gt;Strings in Kotlin, like in Java, are immutable, so we have to be very careful when handling them and mind the cases where new strings would be created without explicit warning. The class &lt;em&gt;String&lt;/em&gt; is used to represent a string instance, each element of a string can be retrieved as a &lt;em&gt;Char&lt;/em&gt; instance by indexed access, therefore you can think of it as an array of Char objects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;word&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello World"&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;letterH&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, going through each element of a String is as easy as using a for-loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similar to many languages out there, you can escape special characters using the backslash, like "\n".&lt;/p&gt;

&lt;p&gt;Another interesting featue of strings in Kotlin is how we can use something called string templates. If we'd like to insert values into a string at runtime, we may use string templates. To do so we'd need to use &lt;em&gt;$&lt;/em&gt; before the variable we'd like to insert into the string or use curly braces if we're evaluating an expression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;oneThousand&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;

    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1 thousand = $oneThousand"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1 thousand and one = ${oneThousand + 1}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Funny enough, if we decompile the bytecode back to java code we get the old + concatenation we're used to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;   &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@NotNull&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;Intrinsics&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;checkParameterIsNotNull&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"args"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;oneThousand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;var2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1 thousand = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;oneThousand&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;var2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1 thousand and one = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oneThousand&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
   &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One last thought about Kotlin strings is that they use the same idea of String Pools as in Java. This means that if two strings are equal (structuraly speaking) they point to the same place in memory. Why is this important, you may ask? In kotlin we can compare two variablesby using the structural equality == and the referential equality ===. Because of String Pools and the whole string imutabilty, if we initialize two variables with the same string value, they'll hold the same referece, the code bellow would run to completion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;first&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"first"&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;second&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"first"&lt;/span&gt;

    &lt;span class="nf"&gt;assertTrue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;assertTrue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="p"&gt;===&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most of the Kotlin types have nice extension functions to make our lives working with them easier. Here's a list of my favorite ones:&lt;/p&gt;

&lt;h3&gt;
  
  
  associate()
&lt;/h3&gt;

&lt;p&gt;This method takes each character of the original string and apply a transformation that returns a Map. You can use it to create a map of characters counts of your string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;s&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Levi Moreira de Albuquerque"&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;bin&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;associate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="nc"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;L&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;M&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  capitalize() and decapitalize()
&lt;/h3&gt;

&lt;p&gt;It takes a Locale and capitalizes the first letter of the string according to that Locale.&lt;/p&gt;

&lt;h3&gt;
  
  
  toSet
&lt;/h3&gt;

&lt;p&gt;Would you like to know if there are repeated values in a string and can use extra space? Just use toSet():&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;s1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Levi Moreira de Albuquerque"&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;s2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"abcdefghijk"&lt;/span&gt;

    &lt;span class="k"&gt;false&lt;/span&gt;
    &lt;span class="k"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Arrays
&lt;/h1&gt;

&lt;p&gt;Arrays in Kotlin are representd by the Array class, the basic anatomy of this class is as follows, this is the general implementation of an Array, but kotlin has specialized classes for primitive types such as IntArray, FloatArray and DoubleArray.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;
    &lt;span class="k"&gt;operator&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;
    &lt;span class="k"&gt;operator&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Unit&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Accessing an array happens just like in Java, you can use square brackets and an index to access a position. Though this is just syntactic sugar to the get() and set() methods ilustrated above. &lt;/p&gt;

&lt;p&gt;The primitive types arrays get translated into their counterparts when targetting the JVM plataform, for instance IntArray is represented by int[], FloatArray to float[] and so on. This is clear when we decompile the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;s1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;IntArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We get this very ugly result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;      &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;var2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;var3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;var2&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt;

      &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;var4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;var4&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;var2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;var4&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
         &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;var6&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
         &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;var9&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;var4&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;var4&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
         &lt;span class="n"&gt;var3&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;var4&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;var9&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like strings, Arrays have some very interesting extension functions, some of my favorite ones are listed here:&lt;/p&gt;

&lt;h3&gt;
  
  
  binarySearch
&lt;/h3&gt;

&lt;p&gt;Performs a binary search in the array, note that the array needs to be sorted for the result to work as expected.&lt;/p&gt;

&lt;h3&gt;
  
  
  forEach
&lt;/h3&gt;

&lt;h3&gt;
  
  
  intersect
&lt;/h3&gt;

&lt;p&gt;Returns a set with the numbers that existing both in the first array and in the given collection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;s1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;IntArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;s2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;IntArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;intersect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toList&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;span class="na"&gt;
    [0, 1, 4, 9, 16]&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  joinToString
&lt;/h3&gt;

&lt;p&gt;Creates a string with the elements of the array using a separator (a comma isthe default value). We can also add a prefix/postfix to each element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;s1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;IntArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;joinToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;separator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  max, min, average, sum
&lt;/h3&gt;

&lt;p&gt;Performs the given action (find max, min or calculate the sum/average) with the elements of the given array.&lt;/p&gt;

&lt;h1&gt;
  
  
  The example
&lt;/h1&gt;

&lt;p&gt;As an example of usage of such data structures we'll have a look at the first problem from the first chapter of Cracking the Code Interview. We need to devise an algorithm that can detect if a string contains only unique characters. The impementation is pretty straightfoward if we don't care about performance we cook up a O(n^2) time algorithm. But we'd like to have an  O(n) algorithm and for that we'll use a BitSet. &lt;/p&gt;

&lt;p&gt;A BitSet is simply an array of bits, we'll initialize our array with the number of characters in the extended ASCII alphabet (I made an assumption that we'll be only feeding ASCII strings), therefore we'll be using a constant amount of space. &lt;/p&gt;

&lt;p&gt;The idea is simple, the array is initialized with &lt;strong&gt;false&lt;/strong&gt; in all positions. We'll go through the input string checking each character, the integer version of the character will index the BitSet, if the given position is true we can immediately return &lt;em&gt;false&lt;/em&gt; because there's a duplicate (we've seen it before), otherwise we return true in the end, because we looped through the whole string and didn't find any duplicates. I've also added a small check at the beginning because if a string is larger than the alphabet, it &lt;em&gt;must&lt;/em&gt; contain repeated characters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isUnique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;bits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BitSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bits&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;()])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;bits&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see in the method above, both the BitSet and the String can be accessed by using an index. Also, I've used the &lt;strong&gt;.toInt()&lt;/strong&gt; extension method to convert a Char to its integer equivalent.&lt;/p&gt;

&lt;p&gt;I hope this was helpful to give you an introduction about some basic data structures in Kotlin. In the next post we'll talk about LinkedLists, see you there :)&lt;/p&gt;

</description>
      <category>android</category>
      <category>androiddev</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>Compare yourself with yourself</title>
      <dc:creator>Levi Albuquerque</dc:creator>
      <pubDate>Mon, 15 Apr 2019 00:14:15 +0000</pubDate>
      <link>https://dev.to/levimoreira/compare-yourself-with-yourself-2g44</link>
      <guid>https://dev.to/levimoreira/compare-yourself-with-yourself-2g44</guid>
      <description>&lt;p&gt;You're surfing Linkedin and an update pops up about an ex school colleague of yours. They've just been accepted to one of the big four and you wished that was you. This type of situation used to make me question everything I was career-wise. Why was I so behind my peers? Why couldn't I be more "known" in the community? Why wasn't I as successful? These questions popped into my head and clouded my judgement to the most obvious reason that could answer my questions: every person is different and I shouldn't compare myself and my career path to that of others. &lt;/p&gt;

&lt;p&gt;The aims and reasons that moves each one of us are completely different, so the outcomes of those must be different and realizing this made me stop comparing myself with others. It's not very easy, in our industry there's some sort of intrinsic competition between peers and you're always comparing yourself to see where you stand among them, but if you study yourself and compare with yourself, with a little of good sense that should be enough to see if you're evolving in terms of your career or if you're in the same place for far too long.&lt;/p&gt;

&lt;p&gt;Here's a list of things that helped me stop comparing myself with other people:&lt;/p&gt;

&lt;h3&gt;
  
  
  1 - Accept you can't learn/do everything.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmemegenerator.net%2Fimg%2Finstances%2F82054185%2Fso-little-time-so-much-to-learn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmemegenerator.net%2Fimg%2Finstances%2F82054185%2Fso-little-time-so-much-to-learn.jpg" alt="So little time, so much to learn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think of this as a Fear of Missing-out, but more career driven. There's a lot of new stuff going on and you fear you don't know enough about them. It's difficult, I know. Every time something new comes up in the Android world I just want to test it right on the spot. But I usually don't have time to do so, after work, studying and taking care of my family there's little time left to do these tests and write more code. This used to bump me out a lot in the past. I was stressed out because I couldn't stay on top of everything that was going on, but once I've accepted that it was not humanly possible to do so things go better. &lt;/p&gt;

&lt;p&gt;First I've accepted that I knew something, my knowledge must have some value, otherwise I wouldn't have a job, I know something, not everything of course, that's impossible, but something. &lt;/p&gt;

&lt;p&gt;I've tried to structure and time-box the new things I'd like to learn, I would do a list and give some points to each new topic and they would go up or down the list depending on how important that was. Another thing that helped me was applying that in my current job. Sometimes that is difficult because adding new technologies to a project must be a team decision, but I would present the idea and hope for the best. Sometimes it would work and I wouldn't need to spend extra time learning that. If it didn't work, back on the list it went and at some point or another I would spare a couple of hours to study that. Being patient is very important at this stage because you won't be able to learn everything in a day.&lt;/p&gt;

&lt;h3&gt;
  
  
  2 - Everyone has their own clock.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpics.me.me%2F%253E%25E4%25B8%25BF-%253E%25E4%25B8%25BF-%25EF%25BD%258C%25EF%25BD%258F%25EF%25BD%2593%25EF%25BD%2593-%25EF%25BD%258F%25EF%25BC%2587-%25EF%25BD%2583%25EF%25BD%258C%25EF%25BD%258F%25EF%25BD%2583%25EF%25BD%258B-6286711.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpics.me.me%2F%253E%25E4%25B8%25BF-%253E%25E4%25B8%25BF-%25EF%25BD%258C%25EF%25BD%258F%25EF%25BD%2593%25EF%25BD%2593-%25EF%25BD%258F%25EF%25BC%2587-%25EF%25BD%2583%25EF%25BD%258C%25EF%25BD%258F%25EF%25BD%2583%25EF%25BD%258B-6286711.png" alt="Different types of clock"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Time works differently for everyone, and I'm talking about both micro time, like what time you wake up and start working, and macro time, like at what age do you expect to start forming a family. It's just how it is, everyone was raised differently, even within the same family and that's why it's so strange to compare yourself with someone else. Other people had different opportunities, learned things differently and have a different career focus, so why not decide if you're behind just by comparing with yourself one year ago? I can say that a good exercise for me was to look back at myself in time. What was I doing one year ago? Two years? Is it the same, is it different? Do I feel that I've learned new stuff or just continued the same?&lt;/p&gt;

&lt;p&gt;I don't like to feel stuck, I guess nobody does. And the only way of knowing if you're stuck is by checking periodically what you've done to not be stuck. Here's a couple of things that I like to consider when evaluating my progress through time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What have I learned since the last time I checked?&lt;/li&gt;
&lt;li&gt;Do I find satisfaction in my job? Do I learn new things?&lt;/li&gt;
&lt;li&gt;Have I tried anything new recently?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By evaluating what I am at the moment when compared to what I was some time ago I can make a clear judgment whether or not I have advanced and if maybe it's time for my to focus more on my education, or maybe change projects at work or even find a new more challenging job. And it's all about evaluating yourself and your own level of happiness from where you are.&lt;/p&gt;

&lt;p&gt;At this point you might be asking yourself, how you're supposed to evaluate where you are, how do you know you've spent too long in the same job or doing the same thing. The next step is the piece key for knowing that.&lt;/p&gt;

&lt;h3&gt;
  
  
  3 - Have a career plan for yourself.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.makeameme.org%2Fcreated%2FCareer-goals-What.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.makeameme.org%2Fcreated%2FCareer-goals-What.jpg" alt="Career goals?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, in order to know if you're moving forward you need to know the direction you're heading to. And that's where a career plan is here to help. And I'm not talking about a structured path where you list each and every step of the way until retirement, that's not good because that would be like predicting the future and unless you can accurately do that I don't recommend going that far. I believe that the question "Where do you see yourself in x years" is a good way to start planning your career. Some nice steps to take are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can pick big names where you'd like to be working in a couple of years but understand that it would be much easier to pick positions instead. If you're willing to work in any nice company at that position that gives you a lot of possibilities.&lt;/li&gt;
&lt;li&gt;If you're like me and you've picked a big name, make a plan defining steps you think it would be necessary to increase your chances of reaching your goals.&lt;/li&gt;
&lt;li&gt;Leave some space for the unknown. You don't know what will exactly happen in the future, so plan ahead, but leave some space to accommodate possible issues. That way you won't feel frustrated if you don't reach your go at the amount of time you expected.&lt;/li&gt;
&lt;li&gt;Define milestones. For instance, in my career plan, by the end of this year I'd like to have been accepted in a Master's programme in my hometown. Next year, I'd like to try a summer internship in a nice company, and so on and so forth. That way you can evaluate if you're moving towards that goal or away from it.&lt;/li&gt;
&lt;li&gt;Don't get stressed if things go out of your plan, there's always chance to either recover the time lost or to change your plan altogether.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Defining where you'd like to be in x years, 2x years, 3x years and etc is a great way of having some baseline to compare yourself with. That way you'll know if you're making progress in your career and you won't have to worry if anyone else is making more or less progress than you because the only progress that will matter is yours. After all your career is shaped by you.&lt;/p&gt;

&lt;p&gt;I hope this can help other people not to feel so anxious (like I used to feel, and honestly still feel sometimes) about the way their careers are going. &lt;/p&gt;

</description>
      <category>development</category>
      <category>career</category>
    </item>
    <item>
      <title>Android Dependency Injection with Koin</title>
      <dc:creator>Levi Albuquerque</dc:creator>
      <pubDate>Mon, 25 Feb 2019 20:07:30 +0000</pubDate>
      <link>https://dev.to/levimoreira/android-dependency-injection-with-koin-i34</link>
      <guid>https://dev.to/levimoreira/android-dependency-injection-with-koin-i34</guid>
      <description>&lt;p&gt;Dependency Injection, or DI, is a design pattern/technique as old as time itself. You've probably heard it a couple of times during your career and it always comes up in the list of "good practices" when developing Android apps, but why is that?&lt;br&gt;
Let's first understand a bit of what DI is and how it was done in Android and then we can have a look at how Koin approaches the idea.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is DI?
&lt;/h3&gt;

&lt;p&gt;Dependency Injection consists in simply providing the dependencies needed by an object without creating them within the object itself. As the name says we'll inject that dependency somehow into the object. I know, it sounded a bit confusing, let's see an example:&lt;/p&gt;

&lt;p&gt;Let's say you have a repository class in your app that you can use to access your api service. You could create your class as such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MovieRepositoryImpl&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nc"&gt;MovieRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;tmdbService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TmdbApi&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getMovies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Single&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TopMovieListResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tmdbService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTopMovies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;


&lt;p&gt;This however imposes a strong coupling between the service class and the repository, you're creating the service within the repository. How would you go about unit testing the Repository? You can't test just the repository because the service is there and you can't control how it behaves. Dependency Injection favors and helps us to create a mindset to enable writing testable code. We could modify the code and provide the service dependency when we create the repository, through the constructor:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MovieRepositoryImpl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;tmdbService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;TmdbApi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nc"&gt;MovieRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getMovies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Single&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TopMovieListResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tmdbService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTopMovies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now when we try to test the repository we can provide a mock instance of the service and we can correctly unit test the repository. This is still not DI &lt;em&gt;per se&lt;/em&gt;, but rather an approach to coding that enables us to do it later. We can write code that makes DI easier (and makes testing easier) providing dependencies in various manners:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Constructor Injection:&lt;/strong&gt; This is the preferable way of organizing your code, we should try to always provide dependencies at the moment of creation of an object. This however can become a bit messy if there are a large number of dependencies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Field Injection:&lt;/strong&gt; This type of injection requires some type of harness that will populate the field with the desired dependency. This makes testing a bit harder, but if we make use of a DI framework (more soon) we can choose how this field is populated and we can provide mocks to be injected in them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Method Injection:&lt;/strong&gt; We can make use of a setter method to provide the right dependency. By using a setter method, however, we can end-up with an object that is in an invalid state.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  What is a DI Framework
&lt;/h3&gt;

&lt;p&gt;A DI framework is nothing more than a tool to help you organize how DI is done in your code. Depending on the framework you'll need to follow some steps in order to create a new class. By using a DI framework we can leverage from both constructor and field injections in a more organized way that enables us to develop a more decoupled and testable code. A very famous DI framework used in Android is Dagger, more specifically Dagger2 the latest version of it. About Dagger2 I have one thing to say:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic1.squarespace.com%2Fstatic%2F531721eae4b01a2dce5576a6%2Ft%2F53abf4bde4b0a06bed81a379%2F1403778240963%2F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic1.squarespace.com%2Fstatic%2F531721eae4b01a2dce5576a6%2Ft%2F53abf4bde4b0a06bed81a379%2F1403778240963%2F" alt="steep"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The learning curve for Dagger2 is pretty steep and you can find many series online explaining how to setup Dagger2 in your project. The first configuration is always the toughest, after that Dagger is easily extendable and adding new dependencies is as easy as adding arguments to a method. For the purposes of learning how to apply Koin you'd need some idea of how Dagger works, specially the idea of &lt;em&gt;Modules&lt;/em&gt; and &lt;em&gt;Dependency graph&lt;/em&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Module: A module is a central place where you can tell the framework how to create new instances of a dependency. You can add a variety of configurations in this module to help the framework decide how the new instance will be created. This is how a module looks like in Dagger2 for instance:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Module&lt;/span&gt;
&lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MainProfileModule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Binds&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;provideView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MainProfileFragment&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;MainProfileContract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;

    &lt;span class="nd"&gt;@Binds&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;providePresenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="n"&gt;presenter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MainProfilePresenter&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;MainProfileContract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Presenter&lt;/span&gt;

    &lt;span class="nd"&gt;@Binds&lt;/span&gt;
    &lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;provideDataHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="n"&gt;dhandler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MainProfileDataHandler&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;MainProfileContract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataHandler&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Dependency graph: It's an "imaginary" (in memory graph) that the framework uses to keep track of where the dependencies are injected.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Koin
&lt;/h3&gt;

&lt;p&gt;This is Koin as stated by the creators:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A  pragmatic lightweight dependency injection framework for Kotlin developers. Written in pure Kotlin using functional resolution only: no proxy, no code generation, no reflection!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's some differences between Koin and Dagger:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dagger2 is written in Java, Koin is purely kotlin so it looks more natural when used with Kotlin.&lt;/li&gt;
&lt;li&gt;Koin works as a Service Locater masked as Dependency Injection (if that makes any sense)&lt;/li&gt;
&lt;li&gt;Koin does not generate code == smaller build time&lt;/li&gt;
&lt;li&gt;Koin requires more manual configuration as opposed to using Annotations like Dagger2.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This all means a nice &lt;em&gt;kotlinesque&lt;/em&gt; alternative to Dagger2. This doesn't mean we should start replacing Dagger with Koin in every project we start from now on. Dagger is very powerful and once you get past the initial setup, it's quite easy to use. Koin is just another option to managing dependencies in a nice organized way, if you'll use it or not it will depend on your needs.&lt;/p&gt;

&lt;p&gt;To add Koin into your project just add the dependencies to your app level build.gradle file:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gradle"&gt;&lt;code&gt;    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s2"&gt;"org.koin:koin-android:${koin}"&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s2"&gt;"org.koin:koin-android-viewmodel:${koin}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Usage and Configuration
&lt;/h3&gt;

&lt;p&gt;The project I'll be using to demonstrate the use of Koin can be found &lt;a href="https://github.com/Levi-Moreira/CinemaBuff" rel="noopener noreferrer"&gt;here&lt;/a&gt;. It's a simple app that shows the top rated movies from the TMDB API. Here's a peek of how it looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fm5yynjkolg68w2s7rs3x.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fm5yynjkolg68w2s7rs3x.gif" alt="app image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After I've setup most of the classes in my code (keeping in mind the DI mindset) I've started writing my modules. I've started with the network module where I keep all network related injections.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Some observations from the gist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; means we need this instance to be a singleton. If you'd like to create a new instance every time the dependency is needed you can use "factory" instead.&lt;/li&gt;
&lt;li&gt;When defining how/what type of instance you'd like koin to create you can specify a name and therefore have a named instance. This exists in Dagger through the @Named annotation and is specially useful if you have many instances of the same type.&lt;/li&gt;
&lt;li&gt;If you'd like Koin to provide an instance for you when creating another instance you can use the get() method and pass an optional name if it is an named instance. Koin whill locate the instance and inject it when creating this new object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've also created a separate module to concentrate all "Movie" related object creation:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In this gist you can see one of the nicest things about Koin. It has support for Arch Components, specially ViewModel. When I tried to use Dagger2 and ViewModel I had to inject a ViewModelFactory and from that create my ViewModel, in here we need only to declare it as a  and it will be easily injectable in our activity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;movieViewModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MovieViewModel&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your object is not a view model it can easily be injected as well, just use either inject() or get():&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Property Injection&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;myRepository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MovieRepository&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// Direct instance request&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;myRepository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;MovieRepository&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last piece of configuration that we need to do is to initialize Koin. This needs to be done in the onCreate method from your Application class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;startKoin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;appModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;networkModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;movieModule&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And simple as that all pieces are connected and you've created an easily testable app with decoupled dependencies :)&lt;/p&gt;

</description>
      <category>android</category>
    </item>
    <item>
      <title>Being fishy with Android - Background work</title>
      <dc:creator>Levi Albuquerque</dc:creator>
      <pubDate>Mon, 18 Feb 2019 16:13:58 +0000</pubDate>
      <link>https://dev.to/levimoreira/being-fishy-with-android---background-work-4e9g</link>
      <guid>https://dev.to/levimoreira/being-fishy-with-android---background-work-4e9g</guid>
      <description>&lt;p&gt;Here I am again talking about threads and processes and background stuff :)&lt;/p&gt;

&lt;p&gt;One of the first things you learn when doing Android (or even iOS) is to keep heavy load processing off the Main Thread. The Main Thread is too busy drawing those beautiful animations you love seeing and it doesn't like being stopped to do mundane things such as network requests. It will complain, mark my words.&lt;/p&gt;

&lt;p&gt;There are many ways of doing background work in Android, many APIs have been developed (and deprecated, right Loaders?) and it's always good to remember who they are and when they can help you. This is going to be very quick, I promise :)&lt;/p&gt;

&lt;h3&gt;
  
  
  AsyncTasks
&lt;/h3&gt;

&lt;p&gt;Let's start with the first one you've heard about, AsyncTasks. You hear about it first because it's one of the easier APIs to run work off the Main Thread and then easily publish the results of such work back to it. The usage is quite straightforward. I'll use the canonical example of an AsyncTask that performs a download operation whilst showing a progress bar. First, you have to think about three things:&lt;/p&gt;

&lt;p&gt;1 - The input type of the task you want to run. For me, I'll take an array of URL instances which contains the Urls for the files I wished to download.&lt;br&gt;
2 - The type of intermediate output you'd like to show. In my case that's an integer representing the percentage of the files that has been downloaded so far so I can update my progress bar.&lt;br&gt;
3 - The third thing you need to think about is the type produced by your task. In my case it will be a Long because I'd like to know how many bytes were downloaded at the end of the task.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DownloadFilesAsyncTask&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AsyncTask&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onPreExecute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;showProgressBar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;doInBackground&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;vararg&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;?):&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;downloadedSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;filesToDownload&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;until&lt;/span&gt; &lt;span class="n"&gt;filesToDownload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;downloadedSize&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;downloadFileWithSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="nf"&gt;publishProgress&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;downloadedSize&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onProgressUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;vararg&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setValueInProgressBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onPostExecute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;closeProgressBar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;showDialog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a rather simplified version so you can get the idea: we've created a custom class that extends &lt;code&gt;AsynTask&lt;/code&gt;. Usually you'll want to implement this as an inner class of the Activity that requires the task to be performed. Up top we've defined the three things we had in mind when creating this AsyncTask: the input type (URL), the Progress output type (Int) and the final output type(Long). From that we just necessarily need to implement one single method: &lt;code&gt;doInBackground&lt;/code&gt;, but I've written some of the others so we could see all the capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;onPreExecute&lt;/code&gt; will run in the Main Thread, this means you can access (touch) any view in the activity. Use this to prepare the UI for the task ahead.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;doInBackground&lt;/code&gt;, as the name says will be run in a different Thread. You need to peform you work and return a value in the end. Here you can use the publishProgress to output a progress on your task to the UI.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onProgressUpdate&lt;/code&gt; is called anytime you call &lt;code&gt;publishProgress&lt;/code&gt; inside &lt;code&gt;doInBackground&lt;/code&gt; and this method is executed in the UI thread.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onPostExecute&lt;/code&gt; is called when your task finishes. Here you can show in the UI the final result from your task.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To use it, you must call it in the UI thread:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;DownloadFilesAsyncTask&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AsyncTasks are nice and all but this tight coupling with the UI you gain with the easy way of using it can cause a couple of headaches when not cared for carefully. Just to mention one of them imagine if you start running a very long AsyncTask and the user rotates the device... You know where I'm getting at right? The activity will be destroyed, the AsyncTask will finish at some point and it'll try to access the views that no longer exist, boom! Your app crashes... So, be careful when using them. As the docs say: "AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.)"&lt;/p&gt;

&lt;h3&gt;
  
  
  JobScheduler
&lt;/h3&gt;

&lt;p&gt;As the name says this is the go to API for scheduling tasks in Android. Another option is AlarmManager which we'll talk a bit about later, but the JS APIs were launched in Lolipop therefore they contain far more interesting and complete methods for running tasks.&lt;/p&gt;

&lt;p&gt;Usually we'd use JobScheduler in the following cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;When we'd like to execute tasks within a certain system constraint. This means for instance that JS is ideal for when we'd like to run tasks only when the device is plugged or when we have wifi connection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tasks that can be deferred. The JS API will defer tasks for when is most appropriate to run them, this means that such tasks can't be time critical.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Periodic tasks.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first step to use this API is to create an instance of JobService to handle your work.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyJobService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;JobService&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onStopJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;JobParameters&lt;/span&gt;&lt;span class="p"&gt;?):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onStartJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;JobParameters&lt;/span&gt;&lt;span class="p"&gt;?):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As this is a &lt;strong&gt;&lt;em&gt;Service&lt;/em&gt;&lt;/strong&gt; it will need to be defined in the Manifest file as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;service&lt;/span&gt;
   &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;".MyJobService"&lt;/span&gt;
   &lt;span class="na"&gt;android:permission=&lt;/span&gt;&lt;span class="s"&gt;"android.permission.BIND_JOB_SERVICE"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you could see the JobService requires us to override two methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;onStartJob:&lt;/strong&gt; As the name says this method is called as soon as Android decides to start running our service. Note that the job will run on the Main Thread unless otherwise specified, that means you'll need to put any heavy lifting work on another thread. This method should return true if the job is to keep running. The job will keep running until you call &lt;em&gt;jobFinished()&lt;/em&gt; or until any of the constraints you set to run the job can't be satisfied.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;onStopJob:&lt;/strong&gt; This method is called only when the service is cancelled before it's finished. This can happen because of multiple reasons, for instance, because the constraints it was set to run against can't be satisfied. If you return true in this method the job will be rescheduled.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you've implemented the service, the next step is to start the job. To do so you need to create a &lt;em&gt;JobInfo&lt;/em&gt; instance through a builder. In this &lt;em&gt;JobInfo&lt;/em&gt; you can specify any constraints that you might have to run this job, for example you can set it to run only when the device is connected to the power, or when it is connected to the WiFi.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;componentName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ComponentName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;MyJobService&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;jobInfo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JobInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;componentName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setRequiresCharging&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To finally schedule your job is quite simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;jobScheduler&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getSystemService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;JOB_SCHEDULER_SERVICE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;JobScheduler&lt;/span&gt;
        &lt;span class="n"&gt;jobScheduler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jobInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please note that whilst the service is running, your app will keep a wakelock (will prevent the device from going to sleep). Therefore if you forget to finish it (either automatically or manually) it will drain your battery, so never forget to do so.&lt;/p&gt;

&lt;h3&gt;
  
  
  Firebase JobDispatcher
&lt;/h3&gt;

&lt;p&gt;Did you notice something odd about the JobScheduler API? It was released for Lollipop+ devices, so we didn't actually had an option for scheduling background work for pre-Lollipop devices. Well, we &lt;strong&gt;didn't&lt;/strong&gt;. The Firebase JobDispatcher library was created exactly for that reason. To use it we'd need to include the dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gradle"&gt;&lt;code&gt;&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'com.firebase:firebase-jobdispatcher:0.8.5'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'd need to create an instance of &lt;em&gt;JobService&lt;/em&gt;, like the one before, overriding similar methods. But we'll use the &lt;em&gt;JobService&lt;/em&gt; from the library. We add the service to the manifest just like before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;service&lt;/span&gt;
    &lt;span class="na"&gt;android:exported=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
    &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;".MyJobService"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;intent-filter&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"com.firebase.jobdispatcher.ACTION_EXECUTE"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/intent-filter&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/service&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Things are a bit different when we need to schedule the job. First we create a dispatcher:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;dispatcher&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FirebaseJobDispatcher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;GooglePlayDriver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we use the dispatcher to both create the &lt;em&gt;Job&lt;/em&gt; (here we can add constraints just like before) and schedule it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;myJob&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dispatcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newJobBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MyJobService&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tag"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;dispatcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mustSchedule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myJob&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To cancel a specific job we simply call &lt;em&gt;cancel&lt;/em&gt; on the dispatcher passing the tag we've set when we created the job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;dispatcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tag"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  AlarmManager
&lt;/h3&gt;

&lt;p&gt;AlarmManager is as old as Android itself, this API is very useful for firing up tasks at a specific time, periodically. It should be used only when the task must execute at a specific time and you don't need the conditions that the JobScheduler provide. I won't be providing an example for it, but the &lt;a href="https://developer.android.com/training/scheduling/alarms"&gt;official page&lt;/a&gt; is a great place to retrieve examples. &lt;a href="https://developer.android.com/topic/libraries/architecture/workmanager/"&gt;WorkManager&lt;/a&gt; would be the best option to use in most cases, and AlarmManager is one of the composing APIs of WorkManager. &lt;/p&gt;

&lt;p&gt;I'm not going to talk about Services or WorkManager because I'm dedicating different posts in the near future just for them :)&lt;/p&gt;

</description>
      <category>android</category>
    </item>
    <item>
      <title>Three Continuous Integration options for Android Projects</title>
      <dc:creator>Levi Albuquerque</dc:creator>
      <pubDate>Wed, 27 Jun 2018 19:22:40 +0000</pubDate>
      <link>https://dev.to/levimoreira/3-ci-options-for-android-projects-ohf</link>
      <guid>https://dev.to/levimoreira/3-ci-options-for-android-projects-ohf</guid>
      <description>&lt;p&gt;Hello y'all :)&lt;/p&gt;

&lt;p&gt;Since we last spoke I've been meddling with some pretty nice things. One of those is Continuous Integration options for Android projects. So I've identified three that can be used with various levels of setup difficulty, usage price and integration and I came up with a list of options that worked for me. Note that I had had experience with CI only in Django projects, besides I'm no expert in CI at all.&lt;/p&gt;

&lt;h4&gt;
  
  
  Quick reminder: Continuous Integration
&lt;/h4&gt;

&lt;p&gt;Continuous integration is a great principle that helps projects evolve safely when considering a team of developers. This means that the devs can integrate the code they write continuously, this code is regularly "checked" for bugs (through tests written by the devs themselves) and helps detect bugs early whilst keeping everyone up to date. Usually CI practices involve setting up a CI Server responsible for checking the code that the devs write in order to detect bugs. You may be asking yourself how does it do that? Well, this involves a setup in the server as well as a mindset with the developers that use the tool:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We keep the code in a remote repository (Github, Gitlab, Bitbucket...). Well, everyone does that already...&lt;/li&gt;
&lt;li&gt;The CI server is configured to "know" how to build and test the code. This is usually a script that mimics the commands we use locally to do those same things. For example, in Android when we want to run unit tests we usually do:&lt;code&gt;./gradlew test&lt;/code&gt;. So our CI server "knows" how to run that command.&lt;/li&gt;
&lt;li&gt;The CI server also knows about how to build and sometimes how to deploy the artifacts produced by the build (apks in the case of Android).&lt;/li&gt;
&lt;li&gt;We usually commit code to the repo and the CI server, that knows about push events, will pull the code and run some pre-defined steps to run and build the code.&lt;/li&gt;
&lt;li&gt;We should frequently push code (to keep the "continuous" part of the integration flowing)&lt;/li&gt;
&lt;li&gt;We shouldn't push untested code, this means we should at least run the existing tests locally to see if our changes didn't break them. Ideally you need to add to the test suit whilst developing (TDD, right?).&lt;/li&gt;
&lt;li&gt;We shouldn't push broken, half-finished or otherwise not built code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now with the options&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1 : Circle CI
&lt;/h3&gt;

&lt;p&gt;The first option I'd like to talk about is Circle CI. It's very advertised due to its nice integration with Github. For free you get 1 container that will be able to run 1 "parallel" job. It's enough for testing and small projects so let's dive into it.&lt;/p&gt;

&lt;p&gt;You'll see that with such tools the setup is quite similar, we need to add a configuration file to our project's base folder and all the CI setup is done in this file. &lt;/p&gt;

&lt;p&gt;In the case of Circle CI this file is called &lt;code&gt;./circleci/config.yml&lt;/code&gt;. The structure is also somehow similar to other options, you can see the complete file &lt;a href="https://github.com/Levi-Moreira/CinemaBuff/blob/master/.circleci/config.yml" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
Basically, this files tells Circle CI the following:&lt;/p&gt;

&lt;p&gt;1- Define a job step called "build"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;working_directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;~/code&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2- Use the docker image circleci/android:api-28-alpha which contains all the Android SDK options for running command line builds/tests/deploys.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;circleci/android:api-28-alpha&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3 - Define a series of steps that include making gradlew runnable, download the project dependencies, running linters, building and unit testing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
         &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Chmod permissions&lt;/span&gt;
         &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sudo chmod +x ./gradlew&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Download Dependencies&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./gradlew androidDependencies&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Unit Tests&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./gradlew test&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Linters&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./gradlew check&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./gradlew assemble&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please note, this configuration file is a simplified version. We can add many steps to this build which include integration and UI tests, packaging and even deployment. This is just a simple example.&lt;/p&gt;

&lt;p&gt;Once you've added the configuration file all you need to do is go in the Circle CI page and add a new project pointing it to your Github repo. This part is really straightforward so here's a picture of the builds when they're executed in their servers:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fxsm54jn71vk96glkky9s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fxsm54jn71vk96glkky9s.png" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you integrate Circle CI you can add it as a dependence in your PR workflow, that way the tests will need to pass in the CI server before you can merge. It will show in your PR like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5vfklzx0xmb43ud79v1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5vfklzx0xmb43ud79v1z.png" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above is a great segway for our next option.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2 : Gitlab
&lt;/h3&gt;

&lt;p&gt;The next option is Gitlab. You can either host your complete project in their site and use the CI system, or you can use their integration with Github and use only CI option. If you choose the latter (which is the one I've tested for Android) the setup involves giving authorization to Gitlab to clone your repo and it will add a webhook (just like Circle CI) to monitor push events in the original repo.To finish our set up we'll add a configuration file just like we did with Circle CI, but this time our file is called &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;. &lt;a href="https://github.com/Levi-Moreira/CinemaBuff/blob/master/.gitlab-ci.yml" rel="noopener noreferrer"&gt;Here's&lt;/a&gt; the complete file.&lt;/p&gt;

&lt;p&gt;This configuration file was inspired by the one in this &lt;a href="https://medium.com/evenbit/build-and-test-android-with-gitlab-continuous-integration-e51aba6ba53e" rel="noopener noreferrer"&gt;post&lt;/a&gt;. You can see that it's a bit similar to the one I used for Circle CI. The idea is the same:&lt;br&gt;
1 - Define two stages, build and test. Also, tell Gitlab to use the java docker image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openjdk:8-jdk&lt;/span&gt;

&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2 - The &lt;code&gt;before_script&lt;/code&gt; is used to do configurations you'll run before the main purpose of each step. In the case of the build step we use the build.gradle file to identify the compile sdk version we'd need to use. We also define an environment variable called ANDROID_COMPILE_SDK that will be used to download the SDK files (this can be easily added in the CI configuration menu in Gitlab, under the option "variables"). The variable ANDROID_SDK_TOOLS is used to download other sdk files. In this script we also set up an environment variable called ANDROID_HOME pointing to the folder where we've installed the sdk tools. We add the folder to the container PATH so we can run its utilities in other places. Finally we made gradlew runnable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;export ANDROID_COMPILE_SDK=`egrep '^[[:blank:]]+compileSdkVersion'  app/build.gradle | awk '{print $2}'`&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo $ANDROID_SDK_TOOLS&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo $ANDROID_COMPILE_SDK&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;wget --quiet --output-document=/tmp/sdk-tools-linux.zip https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_TOOLS}.zip&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;unzip /tmp/sdk-tools-linux.zip -d .android&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;export ANDROID_HOME=$PWD/.android&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;export PATH=$PATH:$PWD/.android/platform-tools/&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo y | .android/tools/bin/sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;chmod +x ./gradlew&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3 - For any branch, except for master, I'll call the command &lt;code&gt;./gradlew assembleDebug&lt;/code&gt;. If the push event happened in the master branch we call &lt;code&gt;./gradlew assembleRelease&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./gradlew assembleDebug&lt;/span&gt;

  &lt;span class="na"&gt;only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./gradlew assembleRelease&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4 - For testing, if the push event happened in any branch, we'll call &lt;code&gt;./gradlew test&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;unit_test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;

  &lt;span class="na"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;export ANDROID_HOME=$PWD/.android&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;export PATH=$PATH:$PWD/.android/platform-tools/&lt;/span&gt;

  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./gradlew test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that because we've set the artifacts of the build phase to expire only in 4 hours, our &lt;code&gt;before_script&lt;/code&gt; for the testing phase didn't need to setup the SDK all over again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 3 : Jenkins
&lt;/h3&gt;

&lt;p&gt;Circle CI and Gitlab are the "easy" options, but that comes with a cost. For full on professional projects the free resources might not be enough and then we'd need to go into one of the paid plans. For that reason I brought the third option: Jenkins.&lt;/p&gt;

&lt;p&gt;Jenkins is open sourced and the limit for its operation is set by the server where you're hosting it. Awn, yeah. It's "free" because you won't pay a licence to use it, but you need to host it somewhere, and THAT's not free. I've been using a t2-small EC2 instance and it's been working great.&lt;/p&gt;

&lt;p&gt;Most of the tutorials I've find about this are a bit outdated, but the basic steps are listed below:&lt;/p&gt;

&lt;p&gt;1 - Install the JDK in your instance, this is usually a simple command such as the one bellow. Moreover, install unzip because you'll need it later and git for using git commands in the CI steps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;java-8-openjdk
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;unzip
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2 - Install &lt;a href="https://jenkins.io/doc/book/installing/" rel="noopener noreferrer"&gt;Jenkins&lt;/a&gt;.&lt;br&gt;
3 - Download the command line tools for Android, you can check which one is the latest &lt;a href="https://developer.android.com/studio/#downloads" rel="noopener noreferrer"&gt;here&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-iu&lt;/span&gt; jenkins wget https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4 - Create a folder to host the android sdk and unzip the sdk into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-iu&lt;/span&gt; jenkins &lt;span class="nb"&gt;mkdir &lt;/span&gt;sdk
&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-iu&lt;/span&gt; jenkins unzip sdk-tools-linux-4333796.zip &lt;span class="nt"&gt;-d&lt;/span&gt; sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5 - Accept the license:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;yes&lt;/span&gt; |sudo &lt;span class="nt"&gt;-iu&lt;/span&gt; jenkins sdk/tools/bin/sdkmanager &lt;span class="nt"&gt;--licenses&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6 - Install Platform Tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-iu&lt;/span&gt; jenkins sdk/tools/bin/sdkmanager &lt;span class="s1"&gt;'platforms;android-27'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you've gone through the steps you can start setting up jobs in your Jenkins dashboard. First we need to tell Jenkins where we've installed the SDK, this can be done by going into System Configuration in the Jenkins dashboard:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3pxualvmp42jwzmw9gey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3pxualvmp42jwzmw9gey.png" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After setting the sdk folder we need to create a set of credentials so Jenkins can pull the code from our repository. You can go into the Credentials menu and under the Jenkins namespace click in Add Credential:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvz430cafihtk9bhk6pmf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvz430cafihtk9bhk6pmf.png" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For username you can use your own Github username, the password is a bit different. You'll need to go into your Github account, under settings -&amp;gt; Developer settings options and select Personal token. You'll need to generate a token to be used by jenkins as the password for the credential.&lt;/p&gt;

&lt;p&gt;After setting up the credential you can create the job. Go into new item in your Jenkins dashboard and select Freestyle project. In the following screen make sure you set up:&lt;/p&gt;

&lt;p&gt;1- Github project&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fd9y123ym18d7zz6uwx58.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fd9y123ym18d7zz6uwx58.png" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2 - Git repo, credentials and branches to watch for push events.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvdgx9npzmyfwm6zja9it.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvdgx9npzmyfwm6zja9it.png" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3 - Build trigger&lt;/p&gt;

&lt;p&gt;Build triggers determine how our jobs will start running, for our case we want to detect push events from Github, so we select "GitHub hook trigger for GITScm polling".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4o03dco6car0wqsa41zc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4o03dco6car0wqsa41zc.png" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For that to work you need to go into the settings for your repo and add a new webhook. Just fill in the payload URL option with: &lt;code&gt;http://&amp;lt;JENKINS_HOST_ADDRESS&amp;gt;/github-webhook/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fv22kna5wptxcq9xim3ew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fv22kna5wptxcq9xim3ew.png" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4 - Build steps&lt;/p&gt;

&lt;p&gt;Here we add two steps (by clicking in Add Gradle Script). Check to use gradlew wrapper and add the tasks &lt;code&gt;assembleRelease&lt;/code&gt; and &lt;code&gt;test&lt;/code&gt;. Don't forget to check the box to make gradlew runnable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fc8q0hyyynozcm78z3azu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fc8q0hyyynozcm78z3azu.png" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Woof. That's a lot to configure isn't it? I guess that's why they've come up with &lt;a href="https://jenkins.io/doc/book/blueocean/getting-started/" rel="noopener noreferrer"&gt;Blue Ocean&lt;/a&gt;... After that your jenkins setup is ready to receive push events and build/test automatically.&lt;/p&gt;

&lt;p&gt;So, to sum it up:&lt;/p&gt;

&lt;p&gt;Circle CI is great for its integration with Github, from what I've seen in the docs it is pretty versatile with a wide range of options to cover most CI scenarios out there. Gitlab is also very good, but there's somehow an overhead if you want to integrate it with Github, it feels less natural than Circle CI, but still very functional. I believe if you host your code with them, then it works really well (I've been working in projects where the code is hosted in Gitlab and we use the CI option almost seamlessly). Jenkins is perfect for customization, it offers the greatest flexibility, but there's a learning curve to understand how it works and the interface is less intuitive than the other two.&lt;/p&gt;

&lt;p&gt;I guess that's it :) These are only my points of view from a small amount of time dedicated to exploring these tools. From those three I've only been working regularly with Gitlab so I can vouch for it, the other two, well, you've read my opinions... Also, these are NOT the only options out there, other famous option is Travis CI for instance.&lt;/p&gt;

</description>
      <category>android</category>
      <category>development</category>
      <category>ci</category>
    </item>
    <item>
      <title>I "Love" Anti-patterns</title>
      <dc:creator>Levi Albuquerque</dc:creator>
      <pubDate>Sat, 09 Jun 2018 19:08:40 +0000</pubDate>
      <link>https://dev.to/levimoreira/i-love-anti-patterns-1bj1</link>
      <guid>https://dev.to/levimoreira/i-love-anti-patterns-1bj1</guid>
      <description>&lt;p&gt;Everyone talks about design patterns, but getting to know the other side of the force can be as enlightening as visiting the old good friends. I don't like to produce them, of course, but rather learning about them. As developers we're always trying to improve ourselves, but to be able to improve we need to make mistakes and some of these are mistakes we make during our careers. Getting to know the most common ones can help us steer clear of them. Here I present a top 5 with my favorite ones :)&lt;/p&gt;

&lt;h2&gt;
  
  
  5 - Big ball of mud
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.synthesis.co.za%2Fwp-content%2Fuploads%2Fbfi_thumb%2FAgileArchitecture1-1rl3zo5ig9008zq8zgwie6cn9vnbl7um76y52b72jvbo.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.synthesis.co.za%2Fwp-content%2Fuploads%2Fbfi_thumb%2FAgileArchitecture1-1rl3zo5ig9008zq8zgwie6cn9vnbl7um76y52b72jvbo.jpeg" alt="Ball of mud"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a nice way of referring to a piece of code that doesn't have a clear architecture. Many of us are guilty of producing balls of mud in the beginning of our history with a technology. I remember when I was beginning with Android writing a lot of code inside the Activity and hoping for the best. Some symptoms that you have a BBM:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A lot of repeated code&lt;/li&gt;
&lt;li&gt;Data is completely decentralized, appearing in many locations and many times repeatedly&lt;/li&gt;
&lt;li&gt;The code looks like it's been patched many times by many different people.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The original term was coined by Brian Foote and Joseph Yoder and it says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A Big Ball of Mud is a haphazardly structured, sprawling, sloppy, duct-tape-and-baling-wire, spaghetti-code jungle. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is easily remedied with the use of an architecture, or a minimum level of organization in our code. &lt;/p&gt;

&lt;h2&gt;
  
  
  4 - Design By Committee
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.sutter-group.com%2Fwp-content%2Fuploads%2F2015%2F03%2Fdesign-by-committee-featured.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.sutter-group.com%2Fwp-content%2Fuploads%2F2015%2F03%2Fdesign-by-committee-featured.jpg" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A.K.A :  Gold Plating, Make Everybody Happy&lt;br&gt;
Gold Plating is the foe of perfectionists. It's simply wanting to add more and more features, even tough the product is ready. It's also all about being too elaborate or complex without needing to be so. Some symptoms that this is happening:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Meetings are taking excessively long time and don't feel like grasping the important aspects of the project:&lt;/li&gt;
&lt;li&gt;Design development costs more and takes more time than initially planned.&lt;/li&gt;
&lt;li&gt;Overly designed feature beyond the scope of the client's requirements.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To keep things on track: the duration of the meetings and the sticking to the requirements are essential.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 - Cargo cult programming
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fpolemicsreport.com%2Fwp-content%2Fuploads%2F2016%2F09%2Fcult.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fpolemicsreport.com%2Fwp-content%2Fuploads%2F2016%2F09%2Fcult.jpg" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have you ever joined a cult? Was it fun? Or did you spent most of the time not knowing what actually was going on there? &lt;em&gt;(insert awkward face)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Well, that's basically what cargo cult programming is. You've just heard of a new tech, process or tool and you simply want to join in the hype even though you know nothing about it. Usually, this happens when we're young and fresh in our trade, but sometimes more experienced developers are guilty of joining in. Some symptoms this is happening around you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use of technologies just because it's "trendy" without evaluating the costs of implementing it&lt;/li&gt;
&lt;li&gt;Copy-and-paste programing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2 - Lava flow
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.npr.org%2Fassets%2Fimg%2F2018%2F05%2F07%2Fgettyimages-955631046_wide-0861ad06ae15b220e5d142e708423687dbfe574b-s1000-c85.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.npr.org%2Fassets%2Fimg%2F2018%2F05%2F07%2Fgettyimages-955631046_wide-0861ad06ae15b220e5d142e708423687dbfe574b-s1000-c85.jpg" alt="ALT"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You know that room in your house where the messy stuff lives. Or even that pile of clothes that gets shifted around in your room and that would be much better off organized inside your closet? Those are your own personal lava flows :)&lt;/p&gt;

&lt;p&gt;Lava flow is that piece of code that gets shifted around in our projects just because we don't want to think about all the work it would take to get rid of it. You know it's useless, ugly and potentially buggy. But the stress of working on it puts you off from the necessity of striping your project off it. Sometimes it's code you didn't even write and you're like 99% sure it's not used anywhere. But that 1% keeps you from cleaning it up.&lt;/p&gt;

&lt;p&gt;Some symptoms that you have this in your project are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There's a part of the code where nobody likes to go.&lt;/li&gt;
&lt;li&gt;Some bits of the code look important and "might" be used somewhere else.&lt;/li&gt;
&lt;li&gt;You refer to some bits of your code as "that part that &lt;em&gt;(insert the name of a previous colleague)&lt;/em&gt; did, it probably serves a purpose, probably...&lt;em&gt;(awkward pause)&lt;/em&gt;"&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1 - Copy and paste programming
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Feffectivesoftwaredesign.files.wordpress.com%2F2016%2F05%2Fcopying_and_pasting.jpg%3Fw%3D640" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Feffectivesoftwaredesign.files.wordpress.com%2F2016%2F05%2Fcopying_and_pasting.jpg%3Fw%3D640" alt="Alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've all done this once(and still do) and I'm not saying it's wrong copy and pasting from other sources. Code reuse is a primary topic and foundation in our trade. We can't reinvent the wheel every time we need to add a new feature to our app. The world is huge and many things have been tried, tested and done, so why not reuse what's out there?&lt;/p&gt;

&lt;p&gt;The problem rises when we overdo it, or do it without thinking. Copy and paste solutions without analyzing the impact of them in our code or in the overall architecture of the project is bound to cause many headaches down the line. Some of the symptoms this is happening in your project are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You see the same bug repeating itself, even tough you've fixed it somewhere else.&lt;/li&gt;
&lt;li&gt;Your code starts looking like a piece of (literally) patchwork.&lt;/li&gt;
&lt;li&gt;Some parts of your code become obscure as you don't actually know how they work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A culture of quick-fixes rather than code quality can stimulate such Anti-Pattern. A simple fix for this is to create a culture of code reuse that stimulates analysis over speed.&lt;/p&gt;

&lt;p&gt;Most of the patterns here are discussed in depth &lt;a href="https://www.amazon.com/AntiPatterns-Refactoring-Software-Architectures-Projects/dp/0471197130" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;
That's it, I hope you guys enjoyed the reading :)&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>development</category>
      <category>codesmells</category>
    </item>
    <item>
      <title>A word on Android Threading</title>
      <dc:creator>Levi Albuquerque</dc:creator>
      <pubDate>Sun, 03 Jun 2018 15:15:44 +0000</pubDate>
      <link>https://dev.to/levimoreira/a-word-on-android-threading-5aem</link>
      <guid>https://dev.to/levimoreira/a-word-on-android-threading-5aem</guid>
      <description>&lt;p&gt;A couple of days ago I saw a question o StackOverflow asking: "Where is the main method in Android?". I thought to myself, that's a very interesting question and I think I'll write something about it alongside with other threading stuff. Yeah, the fact that we don't see the &lt;code&gt;main()&lt;/code&gt; method in Android has everything to do with threading.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where are you, main?
&lt;/h2&gt;

&lt;p&gt;Let's start with the question above. Where's the main method in Android?&lt;br&gt;
Well, as any java application, the entry point is the main method and, even tough we don't see it, every app starts off from a main() method just like other java apps. The class that holds it is the &lt;a href="https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ActivityThread.java" rel="noopener noreferrer"&gt;ActivityThread&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;The ActivityThread is responsible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Preparing the Main Looper - That is the Looper (more on that later) where the MainThread will be run.&lt;/li&gt;
&lt;li&gt;Designating a special Handler to this Main Looper&lt;/li&gt;
&lt;li&gt;Starts the Main Looper (by calling its loop() method).&lt;/li&gt;
&lt;li&gt;A whole lot of other stuff...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is basically saying that the &lt;code&gt;ActivityThread&lt;/code&gt; will designate a class to execute the many methods necessary to render the UI of your app and keep it running.&lt;/p&gt;

&lt;p&gt;And now you may be asking yourselves: &lt;em&gt;Ok Levi, but you didn't mention how my main activity get's called. You just talked about a thread that is responsible by managing UI stuff&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And I'll tell you: &lt;em&gt;Calm down, we'll get to that&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Inside the &lt;code&gt;ActivityThread.java&lt;/code&gt; file (it's a huge file) there is another class called simply &lt;code&gt;H&lt;/code&gt; that extends the Handler class and it was used before when we designated a special Handler to the Main Looper. This class is used extensively throughout the ActivityThread because it's a special Handler that deals with the possible states that our (or for that matter any other app in Android) can be.&lt;br&gt;
Every handler has a nice little method called &lt;code&gt;handleMessage&lt;/code&gt; and this special handle's method looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;handleMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Message&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DEBUG_MESSAGES&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Slog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;v&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;TAG&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"&amp;gt;&amp;gt;&amp;gt; handling: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;what&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;what&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;LAUNCH_ACTIVITY:&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="nc"&gt;ActivityClientRecord&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ActivityClientRecord&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;packageInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getPackageInfoNoCheck&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                            &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;activityInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;applicationInfo&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compatInfo&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;handleLaunchActivity&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="o"&gt;....&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is just a small portion of it of course, it's a huge switch handling every different state. But in this portion we can see it handling the &lt;code&gt;LAUNCH_ACTIVITY&lt;/code&gt; case. In there it calls the method &lt;code&gt;handleLaunchActivity()&lt;/code&gt; which in turn calls the &lt;code&gt;performLaunchActivity()&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;handleLaunchActivity&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ActivityClientRecord&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Intent&lt;/span&gt; &lt;span class="n"&gt;customIntent&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="nc"&gt;Activity&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;performLaunchActivity&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customIntent&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
 &lt;span class="o"&gt;...&lt;/span&gt;
 &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The latter is very important because it adds a bunch of known structures we're used to simply use in Android such as Application, Context and Intent. It also calls the  &lt;code&gt;mInstrumentation.callActivityOnCreate()&lt;/code&gt; that will, guess what, call our darling &lt;code&gt;onCreate()&lt;/code&gt; method in our main Activity.&lt;/p&gt;

&lt;p&gt;So, it's a long path from &lt;code&gt;main()&lt;/code&gt; to &lt;code&gt;onCreate()&lt;/code&gt; to sum it up:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ActivityThread's main gets executed&lt;/li&gt;
&lt;li&gt;The UI Thread is set up with its Looper, special Handler and etc.&lt;/li&gt;
&lt;li&gt;The Special Handler initiates the process of creating the Activity object&lt;/li&gt;
&lt;li&gt;The Activity object is created with associated properties&lt;/li&gt;
&lt;li&gt;The onCreate method is called.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Magic words: Handler, Message, MessageQueue, Looper
&lt;/h2&gt;

&lt;p&gt;Now, we've talked about how we get from &lt;code&gt;main()&lt;/code&gt; to &lt;code&gt;onCreate()&lt;/code&gt; and we've used some pretty words like Handler and Looper and when you're developing an app you rarely see these in code (maybe a Handler here and there, but a Looper is quite rare, unless you're dealing with dark stuff like low level multi-threading). We see these quite frequently though when our app crashes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.android.com%2Fstudio%2Fimages%2Fdebug%2Fandroid-monitor-logcat_2-2_2x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.android.com%2Fstudio%2Fimages%2Fdebug%2Fandroid-monitor-logcat_2-2_2x.png" alt="alt text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That happens because they are the foundation of how android performs multi-threading. Let's start with some definitions:&lt;/p&gt;

&lt;h3&gt;
  
  
  Looper
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://developer.android.com/reference/android/os/Looper" rel="noopener noreferrer"&gt;Looper&lt;/a&gt; is a low-level class responsible for executing a message loop for a thread. If you take a look at the implementation of the loop() method in this class, this becomes quite clear:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(;;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Message&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// might block&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// No message indicates that the message queue is quitting.&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;It's an infinite loop that reads messages from a MessageQueue and execute them. Funny thing is when I was in college we used to meddle with threads by putting them in an infinite loop. I guess that was useful now, right? Also, we loop through a thread because there is an overhead associated with creating Threads in java which can be diminished if we reuse some of the threads. Threads are meant to run once and be gone, but with a loop we can keep them around for more time.&lt;/p&gt;

&lt;h3&gt;
  
  
  MessageQueue
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://developer.android.com/reference/android/os/MessageQueue" rel="noopener noreferrer"&gt;MessageQueue&lt;/a&gt; is simply that, a queue that gives messages. Not much else to say.&lt;/p&gt;

&lt;h3&gt;
  
  
  Message
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://developer.android.com/reference/android/os/Message" rel="noopener noreferrer"&gt;Message&lt;/a&gt; is a special wrapper class that wraps some data that can be exchanged between threads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Runnable
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://developer.android.com/reference/java/lang/Runnable" rel="noopener noreferrer"&gt;Runnable&lt;/a&gt; in simple terms is a wrapper for a piece of work you wish to perform (a task, for lack of a better word).&lt;/p&gt;

&lt;h3&gt;
  
  
  Handler
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://developer.android.com/reference/android/os/Handler" rel="noopener noreferrer"&gt;Handler&lt;/a&gt; processes messages (or Runnables) and schedule their processing to a Looper, that is, it receives messages and it also add messages to/from the MessageQueue associated with it. A handler is associated with a thread only and its MessageQueue, but a thread can have (and it usually does) multiple handlers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//adds to the MessageQueue&lt;/span&gt;

&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Runnable&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// this will run in the MQ thread&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;handleMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Message&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// process messages from the MQ&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  So, how do they connect together?
&lt;/h4&gt;

&lt;p&gt;A Handler dealing with a Message or a Runnable (units of work in Android) adds one of them to a MessageQueue that is associated with a Looper and a Thread. The Looper keeps the Thread alive looping through them and asking a Handler to execute the messages it pops from the MessageQueue.&lt;/p&gt;

&lt;p&gt;We usually don't create these classes by ourselves but rather use a HandlerThread that creates a Looper with a Thread automatically for us.&lt;/p&gt;

&lt;p&gt;This is just an intro to a much more deeper and complex subject (not only in Android) but I hope it was useful to someone out there :)&lt;/p&gt;

</description>
      <category>android</category>
      <category>threading</category>
    </item>
    <item>
      <title>Smiley faces with MLKit :)</title>
      <dc:creator>Levi Albuquerque</dc:creator>
      <pubDate>Sun, 20 May 2018 17:09:26 +0000</pubDate>
      <link>https://dev.to/levimoreira/smiley-faces-with-mlkit--410a</link>
      <guid>https://dev.to/levimoreira/smiley-faces-with-mlkit--410a</guid>
      <description>&lt;p&gt;So Google I/O was last week, very exciting and all and this week whilst preparing the sample app for this post I saw this on instagram that's a nice summation of the conference:&lt;/p&gt;


&lt;div class="instagram-position"&gt;
  &lt;iframe id="instagram-liquid-tag" src="https://www.instagram.com/p/Bip26L9gJAi/embed/captioned/"&gt;
  &lt;/iframe&gt;
  
&lt;/div&gt;


&lt;p&gt;So Machine Learning, Machine Learning everywhere. And I don't blame them, ML is this "magical" tool that makes everything work so much better for humans.It takes a lot of effort, sometimes hours/days of "training", but the final result is, for instance, a virtual assistance that can set hair appointments for you and uses freakishnessly (is this even a word) realistic onomatopoeic sounds...&lt;/p&gt;

&lt;p&gt;But let's focus on the matter at hand. &lt;/p&gt;

&lt;p&gt;I love Firebase &amp;lt;3. I know sometimes it's a headache, but it has its uses and they're very versatile. You can either use all of them in one project or just some parts of it. For example, I'm currently working on an app that uses the Real Time Database, Cloud Functions and FCM to implement a chat feature. The rest is integrated with a different Backend, but for the chat feature we use Firebase and it works like a charm (with some caveats, of course).&lt;br&gt;
This year, Google has added the MLKit beta version to Firebase with three "simple" key capabilities:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ready to use APIs for common problems faced by ML users in real world applications such as: Text Recognition, Face Detection, Bar Code Scanning, Image Labelling, Landmark recognition&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Possibility to use these models on-device and in the cloud.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can deploy a custom model (if you have it ready in Tensor Flow Lite)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So it all looks quite interesting and in my mind this is how the conversation goes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Google&lt;/strong&gt;: Do you want to use Machine Learning in your app? &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev&lt;/strong&gt;: Yes, sir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google&lt;/strong&gt;: Here are some ready-to-use APIs. If you use the horse-power in your phone to run the model, you won't have to pay anything. Now, if you want to use our machines in the cloud, then let's see those green bills.. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev&lt;/strong&gt;: These models don't work for my specific problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google&lt;/strong&gt;: Okay, then write one using our other product and you can deploy using this product.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You might be saying now, please just show me the code...&lt;br&gt;
The example I'm going to use in this app is a very simple smile detector. I'm an Android Dev so I'll use Kotlin because:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.juvo.be%2Fsites%2Fdefault%2Ffiles%2Fblog%2Fkotlin.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.juvo.be%2Fsites%2Fdefault%2Ffiles%2Fblog%2Fkotlin.jpg" alt="Alt-text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First thing, dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;google&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;firebase-core&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;15.0.2&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;google&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;firebase-ml-vision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;15.0.0&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty simple, just Firebase Core and ML-Vision.&lt;/p&gt;

&lt;p&gt;The method bellow is the one I used after acquiring the image. In order to process your images you need to convert them to an object that the API understands, in this case a FirebaseVisionImage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;   &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;faceDetect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Bitmap&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;firebaseImage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FirebaseVisionImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromBitmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;detector&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FirebaseVision&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getVisionFaceDetector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;firebaseOptions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;detector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;detectInImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;firebaseImage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addOnSuccessListener&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;processFaces&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;addOnFailureListener&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;printStackTrace&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="nc"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;makeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Something bad happended. Cry in a corner."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LENGTH_SHORT&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this method I use a bitmap (for simplicity) to create the FirebaseVisionImage but you can use other &lt;a href="https://firebase.google.com/docs/reference/android/com/google/firebase/ml/vision/common/FirebaseVisionImage" rel="noopener noreferrer"&gt;formats&lt;/a&gt; like byteArray, byteBuffer, filePath, mediaImage. Also, to create the detector which will be used to actually classify our images you need an instance of FirebaseVisionFaceDetectorOptions to configure your detector. The one I'm using looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;firebaseOptions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FirebaseVisionFaceDetectorOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setModeType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;FirebaseVisionFaceDetectorOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ACCURATE_MODE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setLandmarkType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;FirebaseVisionFaceDetectorOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ALL_LANDMARKS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setClassificationType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;FirebaseVisionFaceDetectorOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ALL_CLASSIFICATIONS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setMinFaceSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.15f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTrackingEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I set the mode type to ACCURATE_MODE meaning I want to favor accuracy over speed. The landmarks type is set to ALL_LANDMARKS because it improved pose estimation. The classification is set to ALL_CLASSIFICATIONS because I need it to detect the smiling feature in images. The min face size tells what's the smaller face it will be able to detect, I've set this to 15% of the size of the image. Enabling tracking helps us keep track of the faces that had be found so far (if the model is presented with multiple images).&lt;/p&gt;

&lt;p&gt;Everyone who uses Firebase knows that most async APIs there work under Task objects. It's no different here, we attach a listener to receive the result of the detection when it completes successfully and another for when something wrong happens and you should shed a tear...&lt;/p&gt;

&lt;p&gt;As a result you'll receive a list (filled or not) with "Faces" that you can check many properties in. For example, you can call getBoundingBox() to check the location of the face within the image, or getSmilingProbability() which is the probability (from 0.0 to 1.0, if -1 it didn't find a smile) of this face to be smiling.&lt;/p&gt;

&lt;p&gt;For me I'm simply doing this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;processFaces&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;faces&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FirebaseVisionFace&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;faces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;makeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Is there a face here?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LENGTH_SHORT&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;face&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;faces&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;face&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;smilingProbability&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="nc"&gt;FirebaseVisionFace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;UNCOMPUTED_PROBABILITY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;smileProb&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;face&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;smilingProbability&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;smileProb&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="nc"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;makeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Smily face :)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LENGTH_SHORT&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="nc"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;makeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Not a Smily face :("&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LENGTH_SHORT&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nc"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;makeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Is there a face here?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LENGTH_SHORT&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So for each face it finds it will check if the probability of a smile is larger than 0.5 (I could use a larger number), if so then it shows a smiley toast :). If not :(.&lt;/p&gt;

&lt;p&gt;So as a tool for speeding up development of ML models in mobile apps I reckon ML Kit does a decent job, I've written this app in a couple of hours and only because I was worried the UI was too ugly (it's still is lol). The built-in models are quite accurate (from what I've tested) and (not tested by me) the custom models are a great option for very specific applications. Let's see how much the usage and the tools will evolve in the next few months...&lt;/p&gt;

&lt;p&gt;That's it, I hope you liked this post because it was a lot of fun writing &lt;a href="https://github.com/Levi-Moreira/MLKitTestApp" rel="noopener noreferrer"&gt;it&lt;/a&gt; ;) &lt;/p&gt;

</description>
      <category>android</category>
      <category>firebase</category>
      <category>mlkit</category>
      <category>google</category>
    </item>
  </channel>
</rss>
