<?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: Zuhaib Ahmad</title>
    <description>The latest articles on DEV Community by Zuhaib Ahmad (@xuhaibahmad).</description>
    <link>https://dev.to/xuhaibahmad</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%2F80495%2F4ec879f0-b1c5-436b-a22a-23e7032467c8.jpg</url>
      <title>DEV Community: Zuhaib Ahmad</title>
      <link>https://dev.to/xuhaibahmad</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xuhaibahmad"/>
    <language>en</language>
    <item>
      <title>Building a ChatGPT App with Flutter</title>
      <dc:creator>Zuhaib Ahmad</dc:creator>
      <pubDate>Sun, 05 Mar 2023 06:49:00 +0000</pubDate>
      <link>https://dev.to/xuhaibahmad/building-a-chatgpt-app-with-flutter-5d47</link>
      <guid>https://dev.to/xuhaibahmad/building-a-chatgpt-app-with-flutter-5d47</guid>
      <description>&lt;p&gt;Flutter is a state-of-the-art cross-platform mobile development framework owned by Google that allows developers to create visually stunning, high-performance native applications for iOS, Android, and web. On the other hand, ChatGPT is an AI model that utilizes the power of GPT to generate human-like responses to chat messages.&lt;/p&gt;

&lt;p&gt;In this tutorial, we'll be putting both technologies together to create a ChatGPT application using Flutter. We'll be utilizing the Dart programming language and Flutter's widgets to communicate with ChatGPT API and display the chat interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we start building our application, you'll need to set up your development environment. Here are the necessary prerequisites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://flutter.dev/docs/get-started/install"&gt;Flutter SDK&lt;/a&gt; installed on your machine.&lt;/li&gt;
&lt;li&gt;An IDE, such as Android Studio, IntelliJ IDEA, or Visual Studio Code.&lt;/li&gt;
&lt;li&gt;A working knowledge of Flutter and Dart.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up the Application
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create a new project in your IDE of choice.&lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;http&lt;/code&gt; package and the &lt;code&gt;flutter_dotenv&lt;/code&gt; package to your &lt;code&gt;pubspec.yaml&lt;/code&gt; file using the &lt;code&gt;dependencies&lt;/code&gt; property.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;flutter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;sdk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flutter&lt;/span&gt;
  &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.12.2&lt;/span&gt;
  &lt;span class="na"&gt;flutter_dotenv&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^4.0.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a &lt;code&gt;.env&lt;/code&gt; file in your project's root directory and add your ChatGPT API key.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;YOUR_API_KEY&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Import the necessary packages in your &lt;code&gt;main.dart&lt;/code&gt; file.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'dart:convert'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:http/http.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter_dotenv/flutter_dotenv.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a &lt;code&gt;ChatPage&lt;/code&gt; class that will display the chat interface and handle the user's input.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChatPage&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;ChatPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;ChatPageState&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;ChatPageState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChatPageState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;ChatPage&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Map of messages and whether they were sent by the user&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;_messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;{};&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;_textEditingController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TextEditingController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&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;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'ChatGPT Demo'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="n"&gt;Expanded&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;itemBuilder:&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;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;isUserMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;elementAt&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Row&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="nl"&gt;mainAxisAlignment:&lt;/span&gt; &lt;span class="n"&gt;isUserMessage&lt;/span&gt;
                      &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;MainAxisAlignment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;end&lt;/span&gt;
                      &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MainAxisAlignment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="n"&gt;Flexible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                      &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="nl"&gt;alignment:&lt;/span&gt; &lt;span class="n"&gt;isUserMessage&lt;/span&gt;
                            &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;Alignment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;centerRight&lt;/span&gt;
                            &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Alignment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;centerLeft&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nl"&gt;padding:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;EdgeInsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                        &lt;span class="nl"&gt;margin:&lt;/span&gt; &lt;span class="n"&gt;EdgeInsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;only&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                          &lt;span class="nl"&gt;top:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="nl"&gt;bottom:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="nl"&gt;left:&lt;/span&gt; &lt;span class="n"&gt;isUserMessage&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="nl"&gt;right:&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;isUserMessage&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="p"&gt;),&lt;/span&gt;
                        &lt;span class="nl"&gt;decoration:&lt;/span&gt; &lt;span class="n"&gt;BoxDecoration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                          &lt;span class="nl"&gt;borderRadius:&lt;/span&gt; &lt;span class="n"&gt;BorderRadius&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;circular&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                          &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;isUserMessage&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;blue&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;grey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="p"&gt;),&lt;/span&gt;
                        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;elementAt&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="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;span class="nl"&gt;itemCount:&lt;/span&gt; &lt;span class="n"&gt;_messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&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="n"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;controller:&lt;/span&gt; &lt;span class="n"&gt;_textEditingController&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;onSubmitted:&lt;/span&gt; &lt;span class="n"&gt;_sendMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;decoration:&lt;/span&gt; &lt;span class="n"&gt;InputDecoration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;hintText:&lt;/span&gt; &lt;span class="s"&gt;'Type your message'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="nl"&gt;contentPadding:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;EdgeInsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
              &lt;span class="nl"&gt;suffixIcon:&lt;/span&gt; &lt;span class="n"&gt;IconButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Icon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Icons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;_sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_textEditingController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;text&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;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="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;_sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;_messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;_messages&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="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Send API request to ChatGPT&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="kt"&gt;Uri&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'https://api.openai.com/v1/chat/completions'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;headers:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;'Authorization'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'Bearer &lt;/span&gt;&lt;span class="si"&gt;$openAiKey&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'Content-Type'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'application/json'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;jsonEncode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;lt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;;{&lt;/span&gt;
        &lt;span class="s"&gt;'model'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'gpt-3.5-turbo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"messages"&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;span class="s"&gt;"role"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsonDecode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&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="n"&gt;_messages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'choices'&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="s"&gt;'message'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;'content'&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&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="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Request failed with status: &lt;/span&gt;&lt;span class="si"&gt;${response.statusCode}&lt;/span&gt;&lt;span class="s"&gt;.'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Clear text field&lt;/span&gt;
    &lt;span class="n"&gt;_textEditingController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&amp;lt;&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;deckgo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;highlight&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;&amp;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;Modify&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dart&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;display&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;ChatPage&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="n"&gt;when&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="n"&gt;starts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;deckgo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;highlight&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"dart"&lt;/span&gt; &lt;span class="n"&gt;theme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"material"&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="n"&gt;slot&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;openAiKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'OPENAI_API_KEY'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;runApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyApp&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&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;MaterialApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="s"&gt;'ChatGPT Demo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;home:&lt;/span&gt; &lt;span class="n"&gt;ChatPage&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;That's it! You now have a fully functional ChatGPT application built with Flutter. Launch your app and start chatting with ChatGPT.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iaiyxNGX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.zuhaibahmad.com/c58746e8b6afb08a5d0caa335744baf6/flutter-gpt-demo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iaiyxNGX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.zuhaibahmad.com/c58746e8b6afb08a5d0caa335744baf6/flutter-gpt-demo.gif" alt="ChatGPT App Demo" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;For suggestions and queries, just &lt;a href="http://linkedin.com/in/xuhaibahmad"&gt;contact me&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Painless UI Testing with Kaspresso</title>
      <dc:creator>Zuhaib Ahmad</dc:creator>
      <pubDate>Sat, 14 Mar 2020 11:00:00 +0000</pubDate>
      <link>https://dev.to/xuhaibahmad/painless-ui-testing-with-kaspresso-3cmm</link>
      <guid>https://dev.to/xuhaibahmad/painless-ui-testing-with-kaspresso-3cmm</guid>
      <description>&lt;p&gt;A few months ago I wrote a blog post under a &lt;a href="https://dev.to/android-spec-testing/"&gt;similar title&lt;/a&gt; about better Unit Testing for Kotlin with &lt;a href="https://github.com/kotest/kotest"&gt;Kotest&lt;/a&gt; (formerly KotlinTest). The focus of that post was to demonstrate a more organized, boilerplate free and self-documenting TDD/BDD friendly testing framework for Kotlin.&lt;/p&gt;

&lt;p&gt;I have been using Kotest for about a year now and it is safe to say that it has encouraged me to test more of my code. While frameworks like Kotest and Spek provide a good alternative for unit testing, the UI part still feels lacking. Most of us still use Espresso for writing UI tests that, even with its super clean API, feel very repetitive and verbose. For some time, I worked around this by extracting the repetitive code for reuse. It wasn’t very clean.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caffeine Overflow
&lt;/h3&gt;

&lt;p&gt;Part of my dev-wishlist was to someday establish this perfect loop of TDD flow with Android where all the features start with a failing UI test, followed by multiple unit tests to satisfy the business logic. At the end of which we have a solid well-tested and self-documented feature. So I started searching for other options which lead me to several frameworks, most of which were named after a coffee.&lt;/p&gt;

&lt;p&gt;One of the great finds was &lt;a href="https://github.com/agoda-com/Kakao"&gt;Kakao&lt;/a&gt; by Agoda, it provides a more readable and reusable DSL on top of Espresso. The idea is to encapsulate the UI in &lt;code&gt;Screen&lt;/code&gt; interfaces which can then be reused. Here is an example of what a form UI would look like:&lt;/p&gt;


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


&lt;p&gt;The resulting tests are reduced to a combination of actions and assertions inside the screen:&lt;/p&gt;


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


&lt;h3&gt;
  
  
  But Wait, There’s More!
&lt;/h3&gt;

&lt;p&gt;Kakao seemed like a pretty reasonable solution until I stumbled upon &lt;a href="https://github.com/KasperskyLab/Kaspresso"&gt;Kaspresso&lt;/a&gt;. It combines Espresso and UI Automator into single DSL based API. For the Espresso part, it just wraps around Kakao with some added features such as improved logging, built-in screenshots, ADB command execution, runtime permissions management and more.&lt;/p&gt;




&lt;h3&gt;
  
  
  Grade Calculator 2.0
&lt;/h3&gt;

&lt;p&gt;What could be a better example than to revisit the grade calculator we built in the previous post? Let’s add some UI and this time build in a purely Test-Driven style.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;Let’s create a simple Android project with an empty Activity. Then add the following test dependencies:&lt;/p&gt;


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


&lt;p&gt;If you set up your project using the Android Studio wizard, then most of these dependencies should already be present. The only dependencies that we must add manually are Kotest, Mockk, and Kaspresso.&lt;/p&gt;

&lt;p&gt;Kotest and Mockk are the same as last time for unit testing and mocking, while Kaspresso will be used for UI tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding The UI Test
&lt;/h3&gt;

&lt;p&gt;Let’s add a UI test for the happy path of our calculator without touching the activity first:&lt;/p&gt;


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


&lt;p&gt;If we try to run this test, it will fail because we have not added the &lt;code&gt;GradeCalculatorScreen&lt;/code&gt; yet. This test serves as a blueprint of what we want to achieve for the happy path of grade calculation. Let’s break down each step:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TestCase&lt;/strong&gt; - The first thing you might have noticed is that the test class extends &lt;code&gt;TestCase&lt;/code&gt;, which is a base class provided by Kaspresso that gives access to most of its features.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Activity Test Rule&lt;/strong&gt; - Next, we create an activity test rule for the grade activity. This part is the same as normal Instrumentation tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GradeCalculatorScreen Instance&lt;/strong&gt; - This instance of the screen will be used in the Kaspresso DSL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test Body&lt;/strong&gt; - For the test body, you might notice the chain of 3 separate blocks. You can use the block syntax instead of the expression body, but then it will add an extra indent to all the code inside the block which I do not like very much.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Before-After-Run&lt;/strong&gt; - The &lt;code&gt;before&lt;/code&gt; and &lt;code&gt;after&lt;/code&gt; blocks are interceptors for anything you might want to do before or after the test respectively. For example, &lt;code&gt;before&lt;/code&gt; can be used for mocking and &lt;code&gt;after&lt;/code&gt; can be used to release resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Steps&lt;/strong&gt; - Finally, the run block is where actual testing happens

&lt;ul&gt;
&lt;li&gt;Every step is described with a &lt;code&gt;step&lt;/code&gt; block. This part is optional, you can skip the steps if you want and directly write the encapsulating code. However, it is very helpful since not only it provides a comment on what is happening but this information also gets printed in the logs.&lt;/li&gt;
&lt;li&gt;In the first step, we launch the activity, this can be done directly with the test rule though.&lt;/li&gt;
&lt;li&gt;In the next two steps, we perform some actions on the &lt;code&gt;GradeCalculatorScreen&lt;/code&gt; and then verify their results. Note that all the methods come from the library, we only provide view bindings in the &lt;code&gt;Screen&lt;/code&gt; implementations.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;h3&gt;
  
  
  Implementing The Kaspresso Screen
&lt;/h3&gt;

&lt;p&gt;At this point, we cannot even compile the application due to missing classes. Let’s provide an implementation for our &lt;code&gt;GradeCalculatorScreen&lt;/code&gt;.&lt;/p&gt;


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


&lt;p&gt;As explained earlier, the screen class just binds the UI elements and organizes them into one place. Since we do not have these elements in the layout XML, the project won’t compile unless we add them too. So here’s a simple layout for it:&lt;/p&gt;


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


&lt;p&gt;Now, the test will compile but the test will fail because we have not provided any business logic yet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding The Business Logic
&lt;/h3&gt;

&lt;p&gt;The next step is to provide the business logic to calculate the grade.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Since there is nothing new about this part, I will just copy the tests and resulting logic from the previous post. You can read the &lt;a href="https://dev.to/android-spec-testing/"&gt;Kotest post&lt;/a&gt; to understand better.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Create a &lt;code&gt;GradeCalculatorSpec&lt;/code&gt; class inside the test package and add the specs for grade calculation:&lt;/p&gt;


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


&lt;p&gt;Once all the tests are passing, the resulting implementation would look something like this:&lt;/p&gt;


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


&lt;h3&gt;
  
  
  Binding It All Together
&lt;/h3&gt;

&lt;p&gt;The final step is to bind the &lt;code&gt;GradeCalculator&lt;/code&gt; with the UI. Let’s add a click listener to the button and use the user input to calculate the grade.&lt;/p&gt;


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


&lt;p&gt;If all goes well, all tests should be passing now. Also, if you look at the logcat output, it will have a complete summary of all test steps.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Bonus: If there was no issue with permission, it should have also captured the screenshots for each step automagically! Look inside the gallery for them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here’s the pidcat output of my tests:&lt;/p&gt;


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


&lt;p&gt;Using Kaspresso, you can also handle runtime permissions, change device state, execute ADB commands right from your code. The flexibility it provides for writing tests in truly amazing.&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This is a very basic example that does not handle any edge cases. However, I hope it was enough to give you a taste of test-driven development with Android.&lt;/p&gt;

&lt;p&gt;We started with a crude idea without any implementation details in mind and used tests to shape our logic. There are a couple of benefits to this approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We ended up with a minimum workable solution with 100% code coverage&lt;/li&gt;
&lt;li&gt;As every part of our logic is backed by Unit and UI tests, the tests themselves serve as a documentation for the features.&lt;/li&gt;
&lt;li&gt;Since both the architecture and the logic is shaped by the tests themselves, it is quite easy to freely refactor the code further without worrying about regression bugs.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;You can find complete source code for this post &lt;a href="https://github.com/xuhaibahmad/Kaspresso-Testing-Demo"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For suggestions and queries, just &lt;a href="http://linkedin.com/in/xuhaibahmad"&gt;contact me&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>blog</category>
      <category>kotlin</category>
      <category>android</category>
      <category>espresso</category>
    </item>
    <item>
      <title>Painless Unit Testing with Kotlintest &amp; Mockk</title>
      <dc:creator>Zuhaib Ahmad</dc:creator>
      <pubDate>Sat, 07 Sep 2019 11:00:00 +0000</pubDate>
      <link>https://dev.to/xuhaibahmad/painless-unit-testing-with-kotlintest-mockk-1n82</link>
      <guid>https://dev.to/xuhaibahmad/painless-unit-testing-with-kotlintest-mockk-1n82</guid>
      <description>&lt;p&gt;Testing is hard and not everyone likes to spend their time writing unit tests when they could be building shiny new features.&lt;/p&gt;

&lt;p&gt;While almost every developer understands the value of testing their code, most of us fall prey of laziness in the face of approaching deadlines and the prospect of more exciting work.&lt;/p&gt;

&lt;p&gt;In this post, let’s understand why unit tests serve as the backbone of successful products and learn a new way of writing tests that is much simpler, intuitive and appealing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Testing Matters
&lt;/h2&gt;

&lt;p&gt;Since I mostly work with Android applications. I’ll let you in on a little secret. More than half of the code bases you will come across will have little to no tests. Not just the crappy ones, but sometimes products with thousands of users.&lt;/p&gt;

&lt;p&gt;This is often due to the complex and dull nature of old school &lt;a href="https://junit.org" rel="noopener noreferrer"&gt;JUnit&lt;/a&gt; based testing. Not only the process is quite boring, it also requires a lot of repetitive boilerplate code to be written for even the simplest scenarios, making testing a very time-consuming process.&lt;/p&gt;

&lt;p&gt;Obviously, when you are in a rush to take the product out as soon as possible, testing becomes the least desirable practice.&lt;/p&gt;

&lt;p&gt;More often than not, the end result is that the project becomes unmaintainable within a year. I have seen organizations rewriting already published products only because the code base has become unmaintainable due to spaghetti code that is rotten with bugs.&lt;/p&gt;

&lt;p&gt;Obviously this is not a desirable situation. Testing your code for bugs and architectural flaws from the beginning solidifies your product to be manageable in the longer run.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If you can not measure it, you can not improve it.” - Lord Kelvin&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Testing As You Go
&lt;/h2&gt;

&lt;p&gt;Laying the foundations of your project with extensive testing is not a new idea. &lt;a href="https://en.wikipedia.org/wiki/Behavior-driven_development" rel="noopener noreferrer"&gt;Behavior Driven Development&lt;/a&gt; has been around for decades.&lt;/p&gt;

&lt;p&gt;The practice is to turn feature specifications (or user stories) into a set of unit tests and then writing code that satisfies those specs via passing tests.&lt;/p&gt;

&lt;p&gt;This results in co-development of both your features and their tests side by side. Coupled with a Continuous Integration solution, this setup almost guarantees that you will never have any regression bugs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Specification Based Testing In Practice
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://cucumber.io/" rel="noopener noreferrer"&gt;Cucumber&lt;/a&gt; is the most widely used BDD testing framework right now. It provides a plain language parser called Gherkin which can be used to write tests in plain English that non-programmers can also understand. The framework turns these specifications into acceptance tests which also serves as the documentation for each feature. Here is what a test is written in Gherkin looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gherkin"&gt;&lt;code&gt;&lt;span class="kd"&gt;Feature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; Calculator
  As a user
  I want to use a calculator to add numbers
  So that I don't need to add myself

  &lt;span class="kn"&gt;Scenario&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; Add two numbers -2 &amp;amp; 3
    &lt;span class="nf"&gt;Given &lt;/span&gt;I have a calculator
    &lt;span class="nf"&gt;When &lt;/span&gt;I add -2 and 3
    &lt;span class="nf"&gt;Then &lt;/span&gt;the result should be 1

  &lt;span class="kn"&gt;Scenario&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; Add two numbers 10 &amp;amp; 15
    &lt;span class="nf"&gt;Given &lt;/span&gt;I have a calculator
    &lt;span class="nf"&gt;When &lt;/span&gt;I add 10 and 15
    &lt;span class="nf"&gt;Then &lt;/span&gt;the result should be 25
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neat! Isn’t it? This spec results in unit tests that run with Cucumber. Since this post is not about Cucumber, I won’t go into the implementation details. You can visit this &lt;a href="https://www.baeldung.com/cucumber-scenario-outline" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt; for the full tutorial on BDD style testing with Cucumber. I used the same article to borrow the above example.&lt;/p&gt;

&lt;p&gt;Some other popular BDD frameworks include &lt;a href="http://lettuce.it/" rel="noopener noreferrer"&gt;Lettuce&lt;/a&gt;, &lt;a href="http://jasmine.github.io" rel="noopener noreferrer"&gt;Jasmine&lt;/a&gt;, &lt;a href="http://www.specflow.org/" rel="noopener noreferrer"&gt;SpecFlow&lt;/a&gt;, &lt;a href="https://spekframework.org/" rel="noopener noreferrer"&gt;Spek&lt;/a&gt;, &lt;a href="http://behat.org" rel="noopener noreferrer"&gt;Behat&lt;/a&gt;, &lt;a href="https://github.com/jdave/Jdave" rel="noopener noreferrer"&gt;Jdave&lt;/a&gt; and &lt;a href="http://jbehave.org/" rel="noopener noreferrer"&gt;Jbehave&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Problems with JUnit
&lt;/h2&gt;

&lt;p&gt;JUnit is an industry-standard at this point for all things Java. It has ruled the Java development for decades now and it works. But since it was built for Java, it brings with it most of the common pitfalls of Java-based technologies that feel backward, especially in the world of modern programming languages like Kotlin, JavaScript and Python.&lt;/p&gt;

&lt;p&gt;Having said that, writing all styles of tests are entirely possible with JUnit. &lt;a href="https://site.mockito.org" rel="noopener noreferrer"&gt;Mockito&lt;/a&gt; provides a BDD style extension in its core library that allows you to do similar &lt;code&gt;Give, When, Then&lt;/code&gt; style testing within JUnit test cases.&lt;/p&gt;

&lt;p&gt;Let’s take a look at some of the problems associated with it and why I believe vanilla JUnit is not a good combination for a powerful language like Kotlin:&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Repetition
&lt;/h3&gt;

&lt;p&gt;Like everything in Java, JUnit is also quite verbose. This results in too much repetition of similar contents with a slight change of logic to test different scenarios.&lt;/p&gt;

&lt;p&gt;How many time have you had a test for a HAS and a HAS-NOT condition with all the same contents except for a boolean? For example, a &lt;code&gt;testUserAccessWhenHasToken&lt;/code&gt; and then &lt;code&gt;testUserAccessWhenNotHasToken&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Of course, you can stuff in all your assertions in one test at the cost of readability. However, a good test is supposed to be granular i.e. targeting one case per test.&lt;/p&gt;

&lt;p&gt;Also, your test code is guaranteed to grow as your project gets bigger and at some point, your test code will surpass your application code. If you want to look at examples of this, try looking into the source code of any popular open-source projects such as &lt;a href="https://github.com/ReactiveX/RxJava" rel="noopener noreferrer"&gt;RxJava&lt;/a&gt;, &lt;a href="https://square.github.io/retrofit/" rel="noopener noreferrer"&gt;Retrofit&lt;/a&gt;, &lt;a href="https://square.github.io/okhttp/" rel="noopener noreferrer"&gt;OkHttp&lt;/a&gt;, &lt;a href="https://square.github.io/picasso/" rel="noopener noreferrer"&gt;Picasso&lt;/a&gt;, etc. Almost all of them have 1.5x to 2x more test code compared to their business logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lack Of Contextual Information
&lt;/h3&gt;

&lt;p&gt;If you are like me, then one of the first things that you may have done while switching to Kotlin was to change your long JUnit test names like &lt;code&gt;fun onTouchOutside_shouldDismissDialogAndResumeStreaming()&lt;/code&gt; with back tick notation. While a big improvement, it gave us a license to go wild with it in our attempts to provide more contextual information about each test case. So now our test case has evolved into something like this: &lt;code&gt;fun `on touch outside, dismiss the dialog and resume streaming the paused song` ()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The real issue here is that these names are not enough to provide full context about the test. Unless you are willing to write an entire paragraph to define the pre and post conditions for the scenario.&lt;/p&gt;

&lt;p&gt;Another problem here is with the organization of test cases. Most of the test cases have some shared code that can be logically structured into a hierarchy. However, because JUnit only allows you to write tests in the form of class methods. So you end up writing more tests, more code but with less context about the overall theme of the current group of tests.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Better Way To Write Tests
&lt;/h2&gt;

&lt;p&gt;The reason behind giving you a taste of Cucumber BDD was to show what it would be like to have such idiomatic tests.&lt;/p&gt;

&lt;p&gt;Let’s define a set of specification that we want to build and test. We will be using two libraries &lt;a href="https://github.com/kotlintest/kotlintest" rel="noopener noreferrer"&gt;Kotlintest&lt;/a&gt; and &lt;a href="https://mockk.io/" rel="noopener noreferrer"&gt;Mockk&lt;/a&gt; to help us write tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Feature
&lt;/h3&gt;

&lt;p&gt;Let’s build a grade calculator that tells you your grade based on the marks you obtained. Here are the rules for grading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When obtained marks are 90 or above, then grade is A.&lt;/li&gt;
&lt;li&gt;When obtained marks are between 80 and 89, then grade is B&lt;/li&gt;
&lt;li&gt;When obtained marks are between 70 and 79, then grade is C&lt;/li&gt;
&lt;li&gt;When obtained marks are between 60 and 69, then grade is D&lt;/li&gt;
&lt;li&gt;When obtained marks are below 60, then grade is F&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;First, create an empty Kotlin or Android project and add the following two dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;testImplementation&lt;/span&gt; &lt;span class="s1"&gt;'io.kotlintest:kotlintest-runner-junit5:3.3.2'&lt;/span&gt;
&lt;span class="n"&gt;testImplementation&lt;/span&gt; &lt;span class="s1"&gt;'io.mockk:mockk:1.9.3.kotlin12'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first dependency is Kotlintest which is a testing library built on top of JUnit. It takes advantage of Kotlin’s DSL capabilities to support various type of testing styles.&lt;/p&gt;

&lt;p&gt;Mockk is a Kotlin-based mocking library with a very clean syntax that blends really well with Kotlintest’s specs. It also provides a much more flexible API and a much wider set of feature compared to Mockito or Powermock.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;p&gt;Let’s start by creating an empty &lt;code&gt;GradeCalculator&lt;/code&gt; class and converting our specifications into a Spec.&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;GradeCalculatorSpec&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;BehaviorSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;

    &lt;span class="nc"&gt;Given&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a grade calculator"&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;calculator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;spyk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;GradeCalculator&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

        &lt;span class="nf"&gt;every&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;totalMarks&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;returns&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;total&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;totalMarks&lt;/span&gt;

        &lt;span class="nc"&gt;When&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"obtained marks are 90 or above"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"grade is A"&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="nc"&gt;When&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"obtained marks are between 80 and 89"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"grade is B"&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="nc"&gt;When&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"obtained marks are between 70 and 79"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"grade is C"&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="nc"&gt;When&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"obtained marks are between 60 and 69"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"grade is D"&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="nc"&gt;When&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"obtained marks are below 60"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"grade is F"&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;This does not quite look like our traditional JUnit test. So let’s break it down and understand bit by bit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BehaviorSpec&lt;/strong&gt; - We are extending something called a &lt;em&gt;BehaviorSpec&lt;/em&gt; which is basically a Spec written in BDD style (remember the Give, When, Then from Cucumber?). There are dozens of different other Spec styles available in Kotlintest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spyk&lt;/strong&gt; - You may notice that I wrapped the &lt;code&gt;GradeCalculator&lt;/code&gt; object with a &lt;code&gt;spyk&lt;/code&gt; method. If you have used Mockito before than the concept is the same. Basically, a spy is a wrapper that lets you mock some methods and variables of the object while using the actual values for the rest. I did it to demonstrate the use of Mockk here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every/Returns&lt;/strong&gt; - Similar to Mockito’s &lt;code&gt;when/then&lt;/code&gt; style, this construct is used by Mockk to prepare mock values. All we are saying is to return a mock value whenever anyone in this code block asks for this value. The value we are mocking is total marks which are going to help calculate the grade.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When/Then&lt;/strong&gt; - Finally, there are a bunch of &lt;code&gt;Then&lt;/code&gt; blocks nested inside &lt;code&gt;When&lt;/code&gt; blocks with some description. The &lt;code&gt;When&lt;/code&gt; block is nothing but a way to organize tests in a logical fashion while each &lt;code&gt;Then&lt;/code&gt; serves as the actual test where the assertion happens. So you can have a test with just a &lt;code&gt;Then&lt;/code&gt; statement but then there’s no point of using it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, let's add some functionality to the &lt;code&gt;GradeCalculator&lt;/code&gt; 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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GradeCalculator&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;totalMarks&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;fun&lt;/span&gt; &lt;span class="nf"&gt;getGrade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obtainedMarks&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;totalMarks&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;String&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;percentage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getPercentage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obtainedMarks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;totalMarks&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;when&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;percentage&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"A"&lt;/span&gt;
            &lt;span class="n"&gt;percentage&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;89&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"B"&lt;/span&gt;
            &lt;span class="n"&gt;percentage&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;79&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt;
            &lt;span class="n"&gt;percentage&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;69&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"D"&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"F"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getPercentage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obtainedMarks&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;totalMarks&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;Int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obtainedMarks&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;totalMarks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFloat&lt;/span&gt;&lt;span class="p"&gt;()&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="nf"&gt;roundToInt&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;Here I added a &lt;code&gt;totalMarks&lt;/code&gt; field which we mock in our test. This value is used in the &lt;code&gt;getPercentage&lt;/code&gt; method to calculate the percentage between total and obtained marks.&lt;/p&gt;

&lt;p&gt;Finally, the &lt;code&gt;getGrade&lt;/code&gt; calculates the grade by comparing the calculated percentage with different ranges.&lt;/p&gt;

&lt;p&gt;You can build this class in a TDD fashion by running the tests first and adding the functionality to make the failing tests pass one by one. I believe the end result would still be somewhat similar.&lt;/p&gt;

&lt;p&gt;In the end, let's add some assertions to test the specifications we just wrote. The final implementation would look something 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="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.zuhaibahmad.bddtestingtutorial&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.kotlintest.shouldBe&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.kotlintest.specs.BehaviorSpec&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.mockk.every&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.mockk.spyk&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GradeCalculatorSpec&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;BehaviorSpec&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;

    &lt;span class="nc"&gt;Given&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a grade calculator"&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;calculator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;spyk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;GradeCalculator&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

        &lt;span class="nf"&gt;every&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;totalMarks&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;returns&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;total&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;totalMarks&lt;/span&gt;

        &lt;span class="nc"&gt;When&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"obtained marks are 90 or above"&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;grade&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getGrade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;93&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="nc"&gt;Then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"grade is A"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&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="nc"&gt;When&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"obtained marks are between 80 and 89"&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;grade&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getGrade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="nc"&gt;Then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"grade is B"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"B"&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="nc"&gt;When&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"obtained marks are between 70 and 79"&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;grade&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getGrade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;78&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="nc"&gt;Then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"grade is C"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C"&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="nc"&gt;When&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"obtained marks are between 60 and 69"&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;grade&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getGrade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;68&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="nc"&gt;Then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"grade is D"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"D"&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="nc"&gt;When&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"obtained marks are below 60"&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;grade&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getGrade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;59&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nc"&gt;Then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"grade is F"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"F"&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;h3&gt;
  
  
  Outcome
&lt;/h3&gt;

&lt;p&gt;I discussed above that JUnit tests lack contextual information and proper grouping of co-related tests. You can see how every test in the spec has a hierarchy which can be used to compose complex cases.&lt;/p&gt;

&lt;p&gt;Furthermore, for this particular style of testing, kotlintest provides an additional &lt;code&gt;And&lt;/code&gt; block to allow you to create even more complex tests without losing contextual information. For example, you may want to construct a test 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="nc"&gt;When&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user list is fetched from API"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;And&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"the internet is NOT available"&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nc"&gt;Then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Test something"&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="c1"&gt;// Some assertions&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;And&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"the internet is available"&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nc"&gt;Then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Test something"&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="c1"&gt;// Some assertions&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;Finally, not just the tests are well organized, the test results in Android Studio have that nested style too. Here’s the result of our tests in the IDE:&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.zuhaibahmad.com%2Fassets%2Fimages%2Fposts%2Fspec-test-results.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%2Fwww.zuhaibahmad.com%2Fassets%2Fimages%2Fposts%2Fspec-test-results.png" alt="Spec Test Result"&gt;&lt;/a&gt;&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;Testing your code right from the start of the project provides a solid foundation for future development.&lt;/li&gt;
&lt;li&gt;The idea of TDD and BDD is not new, it forces you to write your domain-specific code and the architecture itself to be testable. However, due to the verbosity of JUnit and tight deadlines, testing falls behind quite often.&lt;/li&gt;
&lt;li&gt;Aside from code repetition, another big problem with JUnit is the lack of contextual information due to the flat hierarchy of tests. When every case is represented in the form of a class method, it becomes quite difficult to group and organize related tests.&lt;/li&gt;
&lt;li&gt;Modern testing frameworks like kotlintest takes advantage of the flexibility provided by Kotlin to allow writing more intuitive unit tests.&lt;/li&gt;
&lt;li&gt;The result is less boilerplate code and more meaningful tests.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;You can find complete source code for this post &lt;a href="https://github.com/xuhaibahmad/Spec-Testing-Demo" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For suggestions and queries, just &lt;a href="http://linkedin.com/in/xuhaibahmad" rel="noopener noreferrer"&gt;contact me&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>android</category>
      <category>unittesting</category>
      <category>bdd</category>
    </item>
    <item>
      <title>Inter-Process Communication in Android - Lessons &amp; Learnings</title>
      <dc:creator>Zuhaib Ahmad</dc:creator>
      <pubDate>Sun, 28 Apr 2019 11:00:00 +0000</pubDate>
      <link>https://dev.to/xuhaibahmad/inter-process-communication-in-android-lessons-learnings-1p6n</link>
      <guid>https://dev.to/xuhaibahmad/inter-process-communication-in-android-lessons-learnings-1p6n</guid>
      <description>&lt;p&gt;Recently, I was tasked with building a solution for OTA (Over-the-Air) updates for one of our products at &lt;a href="https://sodalabs.co/" rel="noopener noreferrer"&gt;SodaLabs&lt;/a&gt;. Now for those of you who are not familiar with the concept, here’s a definition by &lt;a href="https://searchmobilecomputing.techtarget.com/definition/OTA-update-over-the-air-update" rel="noopener noreferrer"&gt;TechTarget&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An over-the-air update is the wireless delivery of new software or data to mobile devices. Wireless carriers and original equipment manufacturers (OEMs) typically use over-the-air (OTA) updates to deploy firmware and configure phones for use on their networks. The initialization of a newly purchased phone, for example, requires an over-the-air update. With the rise of smartphones, tablets and internet of things (IoT) devices, carriers and manufacturers have also turned to over-the-air updates for deploying new operating systems (OSs) to these devices.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Basically, the updates you receive for your Android, iOS, Windows, Mac or Linux devices are distributed through the mechanism known as OTA programming.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going the Sandbox Way
&lt;/h2&gt;

&lt;p&gt;We had a couple of choices around how to build this OTA client, but in the end we decided to build it as a completely separate project. The reason was that both the main product and OTA client were equally complex solutions and we didn’t want to make it more complex by adding the OTA as part of the main project.&lt;/p&gt;

&lt;p&gt;The OTA would essentially be just a service that runs as a background process and communicates with the main application (the product whose updates this OTA was supposed to manage) via AIDL i.e. the IPC mechanism used by Android.&lt;/p&gt;

&lt;p&gt;This was the first time I was going to be working with IPC in general. So unsurprisingly, there was a lot of frustration, learning and fixing through trial and error involved.&lt;/p&gt;

&lt;p&gt;My goal in this post is to write about the basics and share some insights from my experience so that you can avoid the confusions that I had to face.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inter-Process Communication
&lt;/h2&gt;

&lt;p&gt;Let’s start by understanding what Inter-Process communication is. Inter-Process Communication or IPC, in short, is a mechanism that allows multiple independent processes to communicate and exchange data.&lt;/p&gt;

&lt;p&gt;This communication is often achieved through the use of some shared interfaces defined through Interface Description Language (IDL). What it does is basically establish a set of rules that all the interested processes follow. These shared interfaces serve as a common language that all the parties use to communicate with each other.&lt;/p&gt;

&lt;h2&gt;
  
  
  How IPC Works In Android
&lt;/h2&gt;

&lt;p&gt;All the applications in Android runs in its own process in a sandbox environment. Which means that each application is independent of others. This isolation helps improve the performance of the overall system and in achieving better security through different levels of permissions and access privileges.&lt;/p&gt;

&lt;p&gt;Android has its own version of IDL called Android Interface Definition Language (AIDL), which has very much a Java-esque syntax. You basically start by defining an interface (or multiple based on your use case) and then implement the interface in your application and in the client application that wishes to communicate our app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding The Architecture
&lt;/h2&gt;

&lt;p&gt;One important thing to understand is that IPC communication in Android is also client-server based. Which means that one application has to act as the server while others can interact with it using the interface it exposes.&lt;/p&gt;

&lt;p&gt;Generally, that Server application is the one you are writing and which you wish to be controlled from outside sources. Following are the components and steps involved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;An AIDL interface:&lt;/strong&gt; You define an interface in your server application containing the API that you want to expose to your clients.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Implementation of AIDL interface:&lt;/strong&gt; Rebuilding your project will generate a java interface from your AIDL file, which you can then use to write a concrete implementation of it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Expose the interface to the clients:&lt;/strong&gt; Now that you have a concrete implementation of your AIDL interface, it is time to expose it to your clients by binding it with a Service. This Service can be invoked by external applications and then used a communication channel.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Exchanging data via IPC:&lt;/strong&gt; On Android, one process cannot normally access the memory of another process. So to talk, they need to decompose their objects into primitives that the operating system can understand, and marshall the objects across that boundary for you. This means that you can only exchange primitive type data through IPC in the most basic from.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Writing the parcelable implementations:&lt;/strong&gt; Since in most real-world applications you cannot live off just the primitives. Android also provides a mechanism to exchange your Objects through IPC with the use of Parcelables.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the 5 main steps required to implement the IPC capabilities in an application. However, admittedly they are not simple and bound to give you a lot of trouble. Let’s look at the implementation now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Off To The Code
&lt;/h2&gt;

&lt;p&gt;Let’s build a very basic application that let’s you perform addition. To demonstrate the use of data exchange with both primitives and objects, instead of returning a simple integer value for result, we will return a made-up &lt;code&gt;Result&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;Start by creating a simple project with two modules, one serving as a Client while the other as the Server. You can find the link to the complete code at the end of post.&lt;/p&gt;

&lt;h3&gt;
  
  
  The AIDL Interface
&lt;/h3&gt;

&lt;p&gt;Now that you have a basic setup, let’s first define our very simple AIDL interface in which we want to expose a single method called &lt;code&gt;performAddition&lt;/code&gt; which takes 2 integer values and returns a made-up &lt;code&gt;Result&lt;/code&gt; object.&lt;/p&gt;

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

// IAddition.aidl
package com.zuhaibahmad.aidldemo;

import com.zuhaibahmad.aidldemo.Result;
// Declare any non-default types here with import statements

interface IAddition {
    Result performAddition(int numOne, int numTwo);
}


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

&lt;/div&gt;

&lt;p&gt;Now as I mentioned above, since we are using a custom object, we need to define a simple AIDL implementation for it as well.&lt;/p&gt;

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

// Result.aidl
package com.zuhaibahmad.aidldemo;

parcelable Result;


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

&lt;/div&gt;

&lt;p&gt;Build the project and if no errors occur, then you should be able to find a java implementation of of your AIDL interface.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Once successful, make sure to copy both of your AIDL files to the client project as well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Implementation Of The AIDL Interface
&lt;/h3&gt;

&lt;p&gt;Next step is to provide concrete implementation of the AIDL interfaces. For the &lt;code&gt;Result&lt;/code&gt; object, all you need is a &lt;code&gt;parcelable&lt;/code&gt; POJO for it. However! You need to write it the old school java way.&lt;/p&gt;

&lt;p&gt;I know you love Kotlin and must be thinking of using &lt;code&gt;parcelize&lt;/code&gt; or at least take advantage of the simpler Kotlin code for data classes, but for some reason Kotlin based parcelables don’t work at the time of this writing.&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%2Fi6gdp7pr78upax55jhts.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%2Fi6gdp7pr78upax55jhts.gif" alt="Oh well!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So here’s your implementation for &lt;code&gt;Result&lt;/code&gt; class in &lt;em&gt;pure&lt;/em&gt; java style:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make sure to copy this class into client’s source code as well since it is needed by client to interpret the &lt;code&gt;Result&lt;/code&gt; AIDL interface.&lt;/p&gt;
&lt;/blockquote&gt;

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

package com.zuhaibahmad.aidldemo;

import android.os.Parcel;
import android.os.Parcelable;

public class Result implements Parcelable {
    private int numOne;
    private int numTwo;
    private int result;

    public Result() {}

    public Result(int numOne, int numTwo, int result) {
        this.numOne = numOne;
        this.numTwo = numTwo;
        this.result = result;
    }

    public int getNumOne() {
        return numOne;
    }

    public void setNumOne(int numOne) {
        this.numOne = numOne;
    }

    public int getNumTwo() {
        return numTwo;
    }

    public void setNumTwo(int numTwo) {
        this.numTwo = numTwo;
    }

    public int getResult() {
        return result;
    }

    public void setResult(int numResult) {
        this.result = numResult;
    }

    @Override
    public String toString() {
        return numOne + " + " + numTwo + " = " + result;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeInt(numOne);
        parcel.writeInt(numTwo);
        parcel.writeInt(result);
    }

    public static final Parcelable.Creator&amp;lt;Result&amp;gt; CREATOR = new Parcelable.Creator&amp;lt;Result&amp;gt;(){

        @Override
        public Result createFromParcel(Parcel parcel) {
            Result res=new Result();
            res.numOne = parcel.readInt();
            res.numTwo = parcel.readInt();
            res.result = parcel.readInt();
            return res;
        }

        @Override
        public Result[] newArray(int size) {
            return new Result[size];
        }
    };
}


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

&lt;/div&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%2Fu7p8zahz59zym4sf5djg.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%2Fu7p8zahz59zym4sf5djg.gif" alt="My eyes bleed"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anyways, let’s now provide the implementation for our &lt;code&gt;IAddition&lt;/code&gt; AIDL interface in the server application:&lt;/p&gt;

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

package com.zuhaibahmad.aidldemo

import android.app.Service
import android.content.Intent
import android.os.IBinder
import android.util.Log

class AdditionService : Service() {

    override fun onBind(intent: Intent?): IBinder? {
        Log.e("server", "Binding Service")
        return object : IAddition.Stub() {
            override fun performAddition(numOne: Int, numTwo: Int): Result {
                return Result(numOne, numTwo, numOne + numTwo)
            }
        }
    }
}


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

&lt;/div&gt;

&lt;p&gt;While we are at it, let’s also register this service in our &lt;code&gt;manifest&lt;/code&gt; file. With that our server application will be ready:&lt;/p&gt;

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

&amp;lt;service
    android:name=".AdditionService"
    android:enabled="true"
    android:exported="true" &amp;gt;
    &amp;lt;intent-filter&amp;gt;
        &amp;lt;action android:name="com.zuhaibahmad.aidldemo.AdditionService" /&amp;gt;
    &amp;lt;/intent-filter&amp;gt;
&amp;lt;/service&amp;gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Hooking The Service To The Client
&lt;/h3&gt;

&lt;p&gt;Last step is to bind the &lt;code&gt;AdditionService&lt;/code&gt; in the server application to the client app and starting it remotely. I have a very basic activity with the following UI for client app:&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%2Fzuhaibahmad.com%2Fassets%2Fimages%2Fposts%2Faidl_demo_ui.png%23center" 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%2Fzuhaibahmad.com%2Fassets%2Fimages%2Fposts%2Faidl_demo_ui.png%23center" alt="Client App Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s implement the activity now:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

package com.zuhaibahmad.aidldemo

import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.support.v7.app.AppCompatActivity
import android.util.Log
import kotlinx.android.synthetic.main.activity_main.btEquals
import kotlinx.android.synthetic.main.activity_main.etNumOne
import kotlinx.android.synthetic.main.activity_main.etNumTwo
import kotlinx.android.synthetic.main.activity_main.tvResult

class MainActivity : AppCompatActivity(), ServiceConnection {

    private var isBound: Boolean = false
    private var iRemoteService: IAddition? = null

    // Called when the connection with the service is established
    override fun onServiceConnected(className: ComponentName, service: IBinder) {
        // Following the example above for an AIDL interface,
        // this gets an instance of the IRemoteInterface, which we can use to call on the service
        Log.e("client", "Service connected!")
        iRemoteService = IAddition.Stub.asInterface(service)
        isBound = true
    }

    // Called when the connection with the service disconnects unexpectedly
    override fun onServiceDisconnected(className: ComponentName) {
        Log.e("client", "Service disconnected!")
        iRemoteService = null
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        bindService()

        btEquals.setOnClickListener {
            onPerformAddition()
        }
    }

    private fun onPerformAddition() {
        val numOne = etNumOne.text.toString().toInt()
        val numTwo = etNumTwo.text.toString().toInt()

        tvResult.text = if (isBound) {
            val result = iRemoteService?.performAddition(numOne, numTwo)
            result.toString()
        } else {
            "Service not bound!"
        }
    }

    override fun onDestroy() {
        unbindService()
        super.onDestroy()
    }

    private fun bindService() {
        Log.e("client", "Attempting to bind service")
        val serviceIntent = Intent()
        serviceIntent.setClassName(PACKAGE_NAME, SERVICE_NAME)
        serviceIntent.action = ACTION_REMOTE_BIND
        bindService(serviceIntent, this, Context.BIND_AUTO_CREATE)
    }

    private fun unbindService() {
        if (isBound) {
            // Detach our existing connection.
            unbindService(this)
            isBound = false
        }
    }

    companion object {
        @JvmStatic
        val PACKAGE_NAME: String = "com.zuhaibahmad.aidldemo"

        @JvmStatic
        val SERVICE_NAME: String = "com.zuhaibahmad.aidldemo.AdditionService"

        @JvmStatic
        val ACTION_REMOTE_BIND = "$SERVICE_NAME-remote-bind"
    }
}


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

&lt;/div&gt;

&lt;p&gt;If all goes well, you should be able to compute your additions through the server app using AIDL interfaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things To Remember
&lt;/h2&gt;

&lt;p&gt;In the end, as you may have realized that this mechanism is not very robust and prone to error. So here are few tips from what I learnt working with Android’s IPC about the things that could easily go wrong and make you waste a lot of time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Be &lt;strong&gt;very&lt;/strong&gt; careful about the intent that you use to trigger the service, a minor typo will lead to service never starting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the same note, if you face a situation at the start where you are not getting the results, verify your service bindings first before diving into debugging. It could just be a faulty service binding and will save you a lot of effort.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remember that ONLY primitive types are allowed, so always make sure that you are not accidentally accepting or returning a non-primitive object.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One of the biggest pain was with threading, I never realized that thread would affect IPC as well. Basically, calls made from the local process are executed in the same thread that is making the call. If this is your main UI thread, that thread continues to execute in the AIDL interface. So be very careful if you are using RxJava or any other async mechanism.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remember, Kotlin classes does not work for parcelable implementations with AIDL. At least not at the time of this writing, and what’s worse is that it does not give you any error.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Helpful Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This awesome post by &lt;a href="https://devarea.com/android-services-and-aidl/" rel="noopener noreferrer"&gt;DevArea&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Detailed guide about IPC in Android on &lt;a href="https://developer.android.com/guide/components/aidl" rel="noopener noreferrer"&gt;Official Android Resources&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Also, this &lt;a href="https://android.jlelse.eu/android-aidl-937daf89e685" rel="noopener noreferrer"&gt;Medium Article&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;You can find complete source code for this post &lt;a href="https://github.com/xuhaibahmad/AIDL-Demo" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For suggestions and queries, just &lt;a href="http://linkedin.com/in/xuhaibahmad" rel="noopener noreferrer"&gt;contact me&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>android</category>
      <category>ipc</category>
    </item>
    <item>
      <title>Pythonic Imports in Kotlin</title>
      <dc:creator>Zuhaib Ahmad</dc:creator>
      <pubDate>Sat, 01 Dec 2018 16:00:00 +0000</pubDate>
      <link>https://dev.to/xuhaibahmad/pythonic-imports-in-kotlin-36kc</link>
      <guid>https://dev.to/xuhaibahmad/pythonic-imports-in-kotlin-36kc</guid>
      <description>&lt;p&gt;If you have been working with Kotlin for some time now, you might have encountered issues with name conflicts with Kotlin’s reserved keywords. A common example is with the popular mocking library &lt;a href="https://site.mockito.org/"&gt;Mockito&lt;/a&gt;, where the &lt;code&gt;when&lt;/code&gt; method which is now used by Kotlin for its switch-like construct. So you end up doing something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`when`(messenger.getMessage()).thenReturn("Hello World!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another scenario is when you want to name the imported class or extension function something more meaningful and readable. Which can be acheived to some extent with the use of a &lt;code&gt;typealias&lt;/code&gt;. However, there’s a better solution available right into the Kotlin standard library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pythonic Way of Handling Imports
&lt;/h2&gt;

&lt;p&gt;One the most flexible things I find in &lt;code&gt;Python&lt;/code&gt; is the ability to name the imported classes almost anything you want, just like a variable. So you would simply import a class with a name that suits your style e.g.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import matplotlib.pyplot as plt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you can use &lt;code&gt;plt&lt;/code&gt; as a variable throughout your script.&lt;/p&gt;

&lt;h1&gt;
  
  
  Kotlin’s Import-As Alias
&lt;/h1&gt;

&lt;p&gt;I wished to have this for Android development after I ran into some ambiguity issues with a recent project. Upon some searching, I was surprized to find that Kotlin had this feature all along. Just like Python, you can simply add imports with an &lt;code&gt;as&lt;/code&gt; keyword.&lt;/p&gt;

&lt;p&gt;Let’s look at how our Mockito problem is resolved now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.mockito.Mockito.`when` as whenever
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now use &lt;code&gt;whenever&lt;/code&gt; in place of the less pleasant &lt;code&gt;'when'&lt;/code&gt; througout the class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;whenever(messenger.getMessage()).thenReturn("Hello World!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So that was it. Another reason to love Kotlin (and Python as well)! ;)&lt;/p&gt;




&lt;p&gt;For suggestions and queries, just &lt;a href="http://linkedin.com/in/xuhaibahmad"&gt;contact me&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>android</category>
    </item>
    <item>
      <title>Parcelize: Boilerplate Free Parcelization With Kotlin</title>
      <dc:creator>Zuhaib Ahmad</dc:creator>
      <pubDate>Mon, 20 Aug 2018 12:25:00 +0000</pubDate>
      <link>https://dev.to/xuhaibahmad/parcelize-boilerplate-free-parcelization-with-kotlin-16ka</link>
      <guid>https://dev.to/xuhaibahmad/parcelize-boilerplate-free-parcelization-with-kotlin-16ka</guid>
      <description>&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Serialization" rel="noopener noreferrer"&gt;Serialization&lt;/a&gt; is the process of converting an object into a stream of bytes for ease of use for different I/O operations. Examples include writing to a database, memory or a file. In context of Android, the most common usecase is to pass an object around Activities and Fragments.&lt;/p&gt;

&lt;p&gt;The main idea is to be able to preserve the state of the object in the most primitive way and be able recreated it when needed. The reverse process is called Deserialization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Java Serialization &amp;amp; Android
&lt;/h2&gt;

&lt;p&gt;The way our old boy Java used to handle serialization was very simple - You would only need to implement a &lt;a href="https://stackoverflow.com/questions/25850328/marker-interfaces-in-java" rel="noopener noreferrer"&gt;marker interface&lt;/a&gt; i.e. &lt;code&gt;java.io.Serializable&lt;/code&gt; and objects of that class would be automagically serializable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class MyObject implements Serializable {
    private int data;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This looks perfect, let’s leave it here and use this awesome interface everywhere.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But wait! This oversimplification comes at a big cost. The process involves reflection and creation of tonnes of helper objects behind the scenes. Which results in excessive garbage collection and poor performance.&lt;/p&gt;

&lt;p&gt;In order to solve this problem, Android came with its own mechanism - &lt;a href="https://developer.android.com/reference/android/os/Parcelable.html" rel="noopener noreferrer"&gt;Parcelable&lt;/a&gt;. Although it is more robust, it sacrifices the simplicity of &lt;code&gt;Serialzable&lt;/code&gt; to acheive that. This results in more boilerplate code but which is completely reflection free.&lt;/p&gt;

&lt;p&gt;They key to acheiving that, is that we have to explicitly define the serialization process using the &lt;code&gt;writeToParcel&lt;/code&gt; method. Here’s what your ordinary parcelable class with a single field looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class MyObject implements Parcelable {
    private int data;

     public int describeContents() {
         return 0;
     }

     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(data);
     }

     public static final Parcelable.Creator&amp;lt;MyObject&amp;gt; CREATOR
             = new Parcelable.Creator&amp;lt;MyObject&amp;gt;() {

         public MyObject createFromParcel(Parcel in) {
             return new MyObject(in);
         }

         public MyObject[] newArray(int size) {
             return new MyObject[size];
         }
     };

     private MyObject(Parcel in) {
         data = in.readInt();
     }
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have been using this for years now, but if you have been using something like &lt;a href="https://github.com/johncarl81/parceler" rel="noopener noreferrer"&gt;Parceler&lt;/a&gt; or if you are used to minimal Kotlin code now, then your reaction would probably be something 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%2Fmedia.giphy.com%2Fmedia%2FpVAMI8QYM42n6%2Fgiphy.gif%23center" 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.giphy.com%2Fmedia%2FpVAMI8QYM42n6%2Fgiphy.gif%23center" alt="Gross!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Kotlin To The Rescue (Again?!)
&lt;/h2&gt;

&lt;p&gt;The release of Kotlin 1.1.4 added experimental support for generating Android Parcelable implementations using the &lt;code&gt;@Parcelize&lt;/code&gt; annotation. It brings back the simplicity of &lt;code&gt;Serializable&lt;/code&gt; but without reflection. It instead uses annotation processing to acheive that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;Since it is an experimental feature right now, you will need to enable the support for it by adding the following snippet to your &lt;code&gt;gradle&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;androidExtensions {
    experimental = true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, add &lt;code&gt;apply plugin: ‘kotlin-android-extensions’&lt;/code&gt; to your gradle file if it isn’t there already.&lt;/p&gt;

&lt;h3&gt;
  
  
  Usage
&lt;/h3&gt;

&lt;p&gt;The process of making any class parcelable involves adding only two things - a &lt;code&gt;@Parcelize&lt;/code&gt; annotation and marking the class with &lt;code&gt;Parcelable&lt;/code&gt; implementation.&lt;/p&gt;

&lt;p&gt;Here’s what our &lt;code&gt;MyObject&lt;/code&gt; class would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Parcelize
data class MyObject (val data: Int) : Parcelable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that was it! When combined with data classes, we ended up with even simpler code than Java’s &lt;code&gt;Serializable&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;For suggestions and queries, just &lt;a href="http://linkedin.com/in/xuhaibahmad" rel="noopener noreferrer"&gt;contact me&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>android</category>
    </item>
    <item>
      <title>Why Reactive Should Be Default for Mobile</title>
      <dc:creator>Zuhaib Ahmad</dc:creator>
      <pubDate>Sat, 04 Aug 2018 01:10:00 +0000</pubDate>
      <link>https://dev.to/xuhaibahmad/why-reactive-should-be-default-for-mobile-5ebd</link>
      <guid>https://dev.to/xuhaibahmad/why-reactive-should-be-default-for-mobile-5ebd</guid>
      <description>&lt;p&gt;In the early days of software, the way code was written was pretty straight forward. You would start at a single entry point in the program (typically a &lt;strong&gt;main&lt;/strong&gt; function), execute the instructions sequentially and end the program gracefully. It was simple and easy to conceptualize.&lt;/p&gt;

&lt;p&gt;Due to the linear control flow, it was not only easier to manage the &lt;a href="https://en.wikipedia.org/wiki/State_(computer_science)" rel="noopener noreferrer"&gt;state&lt;/a&gt; of the program but also to test and debug it because all the possible outcomes were predictable. The success of this imperative approach contributed to the way programming mindset established in the years to come. Today, most of us like to think in imperative fashion regardless of the platform or technology we work with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Imperative Approach Fails With Modern Systems
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“All modern systems are asynchronous.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This may seem misleading at first but if you think about it, almost every system today requires us to code in non-blocking fashion. What I mean by non-blocking is that, you need to eliminate waiting periods from the system as much as you can. For example, it’s not ideal to display a loading indicator to the user while a network request is being processed. Although many still follow this pattern but from user experience standpoint, this is a recipe for disaster.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Nobody likes to wait and they’ll leave if they are not served instantly.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The situation worsens with mobile platforms where the OS itself is a source of a countless external changes. You could just flip your device and it’ll break your app unless you have added 3x more code than required just to handle a rotation scenario. What is surprising though, is that almost all of these popular mobile platforms were not designed to be reactive despite them being asynchronous by nature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reactive Programming
&lt;/h2&gt;

&lt;p&gt;Hmmm… So what exactly is Reactive Programming? Let’s take some help from Wikipedia:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“In computing, reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change.”&lt;/p&gt;
&lt;/blockquote&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.giphy.com%2Fmedia%2FSqmkZ5IdwzTP2%2Fgiphy.gif%23center" 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.giphy.com%2Fmedia%2FSqmkZ5IdwzTP2%2Fgiphy.gif%23center" alt="Wut?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Never mind! So, consider you have a program in which we have a Button and Label. They are defined as classes, like any other thing in an object oriented system. All this program does is updates the Label’s text to “Clicked!” when the Button is clicked. So we can say that the Button can somehow affect the text inside the Label, right?&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%2Fzuhaibahmad.com%2Fassets%2Fimages%2Fposts%2Frelation.png%23center" 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%2Fzuhaibahmad.com%2Fassets%2Fimages%2Fposts%2Frelation.png%23center" alt="OO Relation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the case is simple, Button can be clicked and Label can be updated, both can be defined as a function in their respective classes. Now, here’s a question! If you were to code this interaction, where would you put the logic for updating the label when the button is clicked? Is it inside the Button itself or the Label?&lt;/p&gt;

&lt;p&gt;Let’s say you go with the button, which btw is how we normally do it, then in this case you’ll need a reference of Label inside your button which you can update whenever the button is clicked. This essentially is Proactive way of programming. We basically delegated all the responsibility of state-management to the Button and let the Label stay passive i.e. don’t care about what is going on outside. Just follow the instructions when interacted.&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%2Fzuhaibahmad.com%2Fassets%2Fimages%2Fposts%2Fproactive_relation.png%23center" 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%2Fzuhaibahmad.com%2Fassets%2Fimages%2Fposts%2Fproactive_relation.png%23center" alt="Proactive Relation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The class &lt;code&gt;Button&lt;/code&gt; would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Button (val label: Label) {
  public fun onClick() {
    label.setText("Clicked!")
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The alternative to this approach is Reactive programming. We basically just invert the roles so that the state owner has the ability to change itself, letting the Button call for change and Label react to it.&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%2Fzuhaibahmad.com%2Fassets%2Fimages%2Fposts%2Freactive_relation.png%23center" 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%2Fzuhaibahmad.com%2Fassets%2Fimages%2Fposts%2Freactive_relation.png%23center" alt="Reactive Relation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, the &lt;code&gt;Button&lt;/code&gt; class would be similar to this (notice how there’s absolutely no trace of label or any outside dependency):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Button {

  interface ClickListener {
    fun doOnClick()
  }

  var listener: ClickListener? = null

  public fun onClick() {
    listener?.doOnClick()
  }

  public fun addOnClickListener(l: ClickListener) {
    listener = l
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While the &lt;code&gt;Label&lt;/code&gt; will carry all the code for state its management along with list of all the registered clients.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Label (val buttons: MutableList&amp;lt;Button&amp;gt;) {

  private var text = ""

  init {
    buttons.forEach {
      it.addOnClickListener { 
        this.setText("Clicked!") 
      }
    }
  }

  private fun setText(text: String) {
    this.text = text
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;But why reactive? What changes with this approach?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, the &lt;a href="https://en.wikipedia.org/wiki/Inversion_of_control" rel="noopener noreferrer"&gt;Inversion of Control&lt;/a&gt; i.e. Label class is now completely responsible of managing its own state and can easily hide away all the implementation details from outside world.&lt;/p&gt;

&lt;p&gt;Second but related, is that now we have only one source of change. What I mean by that is how previously we had to make &lt;code&gt;setText&lt;/code&gt; method public and all the clients could call it whenever they wanted, which means increased complexity. Now we have a hidden &lt;code&gt;setText&lt;/code&gt; method that is called from only one place i.e. inside &lt;code&gt;Button&lt;/code&gt;’s &lt;code&gt;doOnClick&lt;/code&gt; callback and you can attach as many clients to it as you want using the &lt;code&gt;addOnClickListener&lt;/code&gt; callback. This leads to &lt;a href="https://en.wikipedia.org/wiki/Separation_of_concerns" rel="noopener noreferrer"&gt;Separation of Concern&lt;/a&gt; and simplified codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reactive Extensions
&lt;/h2&gt;

&lt;p&gt;As described in the previous section, &lt;a href="https://en.wikipedia.org/wiki/Callback_(computer_programming)" rel="noopener noreferrer"&gt;Callbacks&lt;/a&gt; are key enablers of reactive programming. However, this way of doing things can lead to a very uncomfortable situation known as &lt;a href="https://stackoverflow.com/.../what-is-callback-hell-and-how-and-why-rx-solves-it" rel="noopener noreferrer"&gt;Callback Hell&lt;/a&gt;. &lt;a href="//reactivex.io/"&gt;Reactive Extensions&lt;/a&gt; (abbreviated as RX) is a framework that helps address such issues.&lt;/p&gt;

&lt;p&gt;The basic building blocks of the library are &lt;strong&gt;Observable&lt;/strong&gt; , &lt;strong&gt;Observers&lt;/strong&gt; and &lt;strong&gt;Operators&lt;/strong&gt;. If you are familiar with the &lt;a href="https://en.wikipedia.org/wiki/Observer_pattern" rel="noopener noreferrer"&gt;Observer Pattern&lt;/a&gt;, this is essentially the same pattern with some enhancements. You make things Observable and let some other things Observe these observables, during the process where Observable produces some data and the Observable receives it, you apply some Operators to mold the data in the form you like to have at the receiving end.&lt;/p&gt;

&lt;p&gt;To learn more about the framework, checkout this &lt;a href="https://www.youtube.com/watch?v=k3D0cWyNno4&amp;amp;t=1s" rel="noopener noreferrer"&gt;talk by Kaushik Gopal&lt;/a&gt; or the &lt;a href="https://gist.github.com/staltz/868e7e9bc2a7b8c1f754" rel="noopener noreferrer"&gt;guide by André Staltz&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mobile &amp;amp; RX Movement
&lt;/h2&gt;

&lt;p&gt;Now that we know about Reactive Programming and its helper framework. The question is how that solve problems associated with mobile platform that I mentioned at the start of this post?&lt;/p&gt;

&lt;p&gt;Instead of giving long explanations of my own, I’d rather direct you to this awesome &lt;a href="https://www.youtube.com/watch?v=0IKHxjkgop4&amp;amp;t=2179s" rel="noopener noreferrer"&gt;talk by Jake Wharton&lt;/a&gt; where he discusses these problems in context of Android and their solution with use of RxJava.&lt;/p&gt;

&lt;p&gt;The crux is basically don’t hate yourself, go async and let the world handle their own problems instead of making your code rely on outside changes in proactive fashion.&lt;/p&gt;

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

&lt;p&gt;State management is hard, especially on mobile platforms. While ideally SDKs should themself be reactively designed, we shouldn’t let that be a source of unreliability in our applications. Thanks to RX movement, we have reactive extensions port for almost every well known language. In context of Android specifically, the rise of Kotlin has provided a great opportunity to finally start writing our applications in functional and reactive manner.&lt;/p&gt;




&lt;p&gt;Image Source - &lt;a href="http://reactivex.io/" rel="noopener noreferrer"&gt;ReactiveX&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
For suggestions and queries, just &lt;a href="http://linkedin.com/in/xuhaibahmad" rel="noopener noreferrer"&gt;contact me&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>reactivex</category>
      <category>reactiveprogramming</category>
      <category>java</category>
      <category>android</category>
    </item>
    <item>
      <title>Going Clean With MVP | A Guide To Model-View-Presenter On Android</title>
      <dc:creator>Zuhaib Ahmad</dc:creator>
      <pubDate>Sun, 21 May 2017 03:10:00 +0000</pubDate>
      <link>https://dev.to/xuhaibahmad/going-clean-with-mvp-a-guide-to-model-view-presenter-on-android-1pik</link>
      <guid>https://dev.to/xuhaibahmad/going-clean-with-mvp-a-guide-to-model-view-presenter-on-android-1pik</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Let’s face it! All of us wrote tons and tons of code inside &lt;code&gt;MainActivity.java&lt;/code&gt;, many still do…&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Writing code that &lt;em&gt;“works”&lt;/em&gt; is fine and acceptable as you start working with a new language or framework. After all, the whole point is to get the work done, right? Not exactly!&lt;/p&gt;

&lt;p&gt;We all start from the same place where every “hello world” marks an accomplishment. However, as you grow as an experienced developer, you start to realize that object-oriented programming is more than just writing the code that &lt;em&gt;works&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Almost every project requires some level of testing and maintenance throughout its lifecycle. This makes it a strict requirement to write modular code that is easy to read, modify, test and maintain for future collaborators.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. - John Woods&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Obviously, our &lt;em&gt;"I love &lt;code&gt;MainActivity&lt;/code&gt;"&lt;/em&gt; guy won’t find this an easy task. Why? Because when you write every single piece of code in the class where it is needed. You end up with a codebase which of course, gets the job done, but makes it almost impossible to test and maintain in the longer run.&lt;/p&gt;




&lt;h2&gt;
  
  
  Model-View-Presenter
&lt;/h2&gt;

&lt;p&gt;MVP is an architectural pattern that attempts to decouple the business logic from the views by providing simpler activities with all the important work behind separate presentation layers. This results in a highly readable, maintainable and most importantly testable code.&lt;/p&gt;

&lt;p&gt;Some might argue that MVP is not an architectural pattern per se as it is only responsible for managing the presentation of the data. However, we leave the debate here and move on to the “&lt;em&gt;why?&lt;/em&gt;” aspect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Need for MVP?
&lt;/h2&gt;

&lt;p&gt;Android activities are cluttered with closely coupled components where everything is structured in a &lt;em&gt;“throw the code on the wall”&lt;/em&gt; manner. This makes it an intrinsic problem for android code to be hard to test and extend. Anyone who went through the pain of learning android application testing can tell you that in the beginning it almost feels impossible to test android activities due to unmockable &lt;em&gt;(is this even a word?)&lt;/em&gt; SDK components and lifecycle management complexities.&lt;/p&gt;

&lt;p&gt;When you separate the business logic away from the activity in a separate presentation layer, it automatically makes it trivial to mock and test your code the way you would test any other java class.&lt;/p&gt;

&lt;p&gt;The other difficulty apart from code testing is the maintenance of existing codebase. If you are reading this post and understand what I have said so far, I am assuming that you are at that point where you are familiar with the &lt;a href="https://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29"&gt;SOLID&lt;/a&gt; principles of object oriented design by &lt;a href="https://en.wikipedia.org/wiki/Robert_Cecil_Martin"&gt;Robert C. Martin a.k.a Uncle Bob&lt;/a&gt;. The last part of the five principles refers to the &lt;em&gt;Dependency Inversion Principle (DIP)&lt;/em&gt; which encourages the programmers to write code in a way that &lt;strong&gt;it depends upon abstractions instead of the concrete implementations&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The way MVP is implemented nowadays (or at least they way I learned to) is through &lt;code&gt;Contract&lt;/code&gt; interfaces that describes the responsibilities of &lt;code&gt;Views&lt;/code&gt; and the &lt;code&gt;Presenters&lt;/code&gt;, making the maintenance of code as simple as adding a new method to the interface and its implementation in the corresponding class. Note that this decoupling also allows us for interchangeable views for the same business logic.&lt;/p&gt;

&lt;p&gt;Now let’s put a full-stop to the theoretical stuff and explore the implementation details of Model, View and Presenter by building a very basic &lt;strong&gt;&lt;em&gt;hello world MVP app&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;Before we go ahead, it’s important that you understand that there is no &lt;strong&gt;&lt;em&gt;“ultimate”&lt;/em&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;em&gt;“best”&lt;/em&gt;&lt;/strong&gt; way of implementing MVP. Most people use their own implementations with some modifications, which is completely acceptable as long as the end goal is achieved. Which is to structure your code to decouple the implementation logic from the presentation layer. The way I’m doing it is only the way I like it, if you find another variation of it, don’t confuse and use the style that suits you.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Model
&lt;/h2&gt;

&lt;p&gt;Model is an interface responsible for managing data. Model’s responsibilities include using APIs, caching data, managing databases and so on. The model can also be an interface that communicates with other modules in charge of these responsibilities.&lt;/p&gt;

&lt;p&gt;For the sake of simplicity, I’m not using any model classes in this example but I hope you got the idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  The View
&lt;/h2&gt;

&lt;p&gt;Do not confuse this with your &lt;code&gt;XML&lt;/code&gt; views. Views in MVP are simply the components responsible for managing the user interface. This includes all the UI manipulation operations such as setting text to some &lt;code&gt;TextView&lt;/code&gt;, toggling visibility of &lt;code&gt;Views&lt;/code&gt;, displaying animations etc. Basically, everything that has to do with the User Interface, goes into this place.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep your views as dumb as possible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The idea is to keep your &lt;code&gt;Presenters&lt;/code&gt; unaware of “how” to present data to the user. All they have is a &lt;code&gt;View&lt;/code&gt; instance that takes this data as input and performs the presentation tasks. So if you were to display an error to the user in case he forgets to fill a field in the form, all your presenter has to do is call the &lt;code&gt;view.displayError(errorMessage)&lt;/code&gt; method on the &lt;code&gt;View&lt;/code&gt; instance.&lt;/p&gt;

&lt;p&gt;Now realize that the &lt;code&gt;Presenter&lt;/code&gt; doesn’t know what happens next, whether the error is displayed as a &lt;code&gt;Toast&lt;/code&gt;, or as a &lt;code&gt;Dialog&lt;/code&gt; or a &lt;code&gt;Snackbar&lt;/code&gt; or what color is the message etc. The &lt;code&gt;View&lt;/code&gt; on the other hand does not know anything about the data it is provided and its origins, it is only interested in accepting the supplied data and manipulate the UI accordingly. This makes it very easy to mock &lt;code&gt;Views&lt;/code&gt; while testing your business logic so you can focus on the stuff that is important.&lt;/p&gt;

&lt;p&gt;The way I like to define my &lt;code&gt;Views&lt;/code&gt; is through a &lt;em&gt;View interface&lt;/em&gt; which resides inside the &lt;em&gt;Contract Interface&lt;/em&gt; for that particular activity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface View extends BaseView&amp;lt;Presenter&amp;gt; {

    void displayMessage(String text);

    void displayResult(int result);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now all I have to do is create a new class and make it implement this interface and we have a candidate that can serve as View for our activity. I guess you might have guessed that we can provide multiple implementations of View as well for different use cases.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class MainActivity extends AppCompatActivity implements ContractMain.View{

    @BindView(R.id.toolbar)
    Toolbar mToolbar;
    @BindView(R.id.container)
    CoordinatorLayout mContainer;
    @BindView(R.id.numberOneEditText)
    EditText mNumberOneEditText;
    @BindView(R.id.numberTwoEditText)
    EditText mNumberTwoEditText;
    @BindView(R.id.resultTextView)
    TextView mResultTextView;

    private ContractMain.Presenter mPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        setSupportActionBar(mToolbar);

        mPresenter = new MainPresenter(this, this);
        mPresenter.start();
    }

    @Override
    public void displayMessage(String text) {
        Snackbar.make(mContainer, text, Snackbar.LENGTH_LONG).show();
    }

    @Override
    public void setPresenter(ContractMain.Presenter presenter) {
        mPresenter = presenter;
    }

    @Override
    public ContractMain.Presenter getPresenter() {
        return mPresenter;
    }

    @OnClick(R.id.addButton)
    public void onAddButtonClicked() {
        String numberOne = mNumberOneEditText.getText().toString();
        String numberTwo = mNumberTwoEditText.getText().toString();

        mPresenter.performAddition(numberOne, numberTwo);
    }

    @Override
    public void displayResult(int result) {
        mResultTextView.setText(String.valueOf(result));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Presenter
&lt;/h2&gt;

&lt;p&gt;Think of the presenters as the &lt;strong&gt;&lt;em&gt;Boss&lt;/em&gt;&lt;/strong&gt; here. Similar to how you used to manage everything from your activity in the &lt;strong&gt;&lt;em&gt;&lt;code&gt;I Love MainActivity&lt;/code&gt;&lt;/em&gt;&lt;/strong&gt; era, Presenters now handles all the management tasks and keeps your activities/fragments less busy. So instead of throwing your &lt;code&gt;DatabaseHandler&lt;/code&gt;, &lt;code&gt;ApiHandler&lt;/code&gt;, &lt;code&gt;PeanutButterMaker&lt;/code&gt; and instances of whatnot in the activity class and make it look like a huge pile of crappy code, you just provide it with the &lt;code&gt;Presenter&lt;/code&gt; instance and place all the other important stuff inside your &lt;code&gt;Presenter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now just like the Views, presenters are also defined through a child interface inside the contract interface of the activity that owns it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Presenter extends BasePresenter {

    void performAddition(String numberOne, String numberTwo);

    boolean isEmptyInput(String numOne, String numTwo);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now all I need to do is to make my activity/fragment implement this interface and provide implementations for the defined operations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MainPresenter implements ContractMain.Presenter {

    private final ContractMain.View mView;
    private final Context mContext;

    MainPresenter(ContractMain.View view, Context context) {
        mView = view;
        mContext = context;
    }

    @Override
    public void start() {
        // Do your initialization work here
    }

    @Override
    public void performAddition(String numberOne, String numberTwo) {

        if (isEmptyInput(numberOne, numberTwo)) {
            // Display error message if any of the inputs is empty
            mView.displayMessage(mContext.getString(R.string.error_empty_input));
        } else {
            // Compute and pass the result to view for display
            final int firstNumber = Integer.parseInt(numberOne);
            final int secondNumber = Integer.parseInt(numberTwo);

            final int result = firstNumber + secondNumber;
            mView.displayResult(result);
        }
    }

    @Override
    public boolean isEmptyInput(String numOne, String numTwo) {
        return numOne == null || numOne.length() == 0 ||
            numTwo == null || numTwo.length() == 0;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Outcome
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;So you might be wondering what did we achieve apart from dividing our activity into 3 pieces?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first benefit of using this approach is that we achieved a more modular and scalable architecture. If you were to add &lt;strong&gt;subtract&lt;/strong&gt; functionality to this activity, all you would do is define a new method &lt;code&gt;void performSubtraction(String numberOne, String numberTwo)&lt;/code&gt; in the &lt;code&gt;Presenter&lt;/code&gt; interface and provide its implementation. Your contracts are the documentation for your code itself.&lt;/p&gt;

&lt;p&gt;The second and most important change is that our activity is now fully testable. You could simply mock the View and test all the application logic using your &lt;code&gt;Presenter&lt;/code&gt;. Below are a couple of tests for the activity we implemented earlier. I’m using &lt;code&gt;Mockito&lt;/code&gt; for mocking dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@RunWith(MockitoJUnitRunner.class)
public class MainTest {

    private static final String EMPTY_INPUT_ERROR_MESSAGE
        = "Please Provide Both Numbers!";

    @Mock
    private ContractMain.View mView;
    @Mock
    private Context mContext;

    private ContractMain.Presenter mPresenter;

    @Before
    public void setUp() throws Exception {
        mPresenter = new MainPresenter(mView, mContext);
    }

    @Test
    public void performAddition_shouldReturnResult() {
        final String numberOne = String.valueOf(2);
        final String numberTwo = String.valueOf(3);

        mPresenter.performAddition(numberOne, numberTwo);

        verify(mView).displayResult(5);
    }

    @Test
    public void performAddition_shouldDisplayErrorMessage() {
        final String numberOne = String.valueOf(2);
        final String numberTwo = null;
        // Mock error string because our mock context
        // wouldn't be able to return it
        when(mContext.getString(R.string.error_empty_input))
            .thenReturn(EMPTY_INPUT_ERROR_MESSAGE);

        mPresenter.performAddition(numberOne, numberTwo);

        verify(mView).displayMessage(EMPTY_INPUT_ERROR_MESSAGE);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;At this point, it may make sense to your or it won’t, but sooner or later, you’ll realize that you need some level of modularization in your code if it requires proper testing and be able to remain maintainable for long-term. If not MVP, you might go with one of the several other architectural patterns that are available. For me, MVP makes more sense than any other in the context of Android.&lt;/p&gt;




&lt;p&gt;Image rights belong to macoscope.&lt;/p&gt;




&lt;p&gt;Source Code is available at &lt;a href="https://github.com/xuhaibahmad/MVP-Tutorial"&gt;GitHub repository&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
For suggestions and queries, just &lt;a href="http://linkedin.com/in/xuhaibahmad"&gt;contact me&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>blog</category>
      <category>android</category>
      <category>java</category>
      <category>mvp</category>
    </item>
  </channel>
</rss>
