Jekyll2024-02-08T13:45:00+00:00https://luboganev.dev/atom.xmlLyubomir Ganev - Android devPersonal website of Lyubomir GanevLyubomir Ganevluboganev@gmail.comObserve as state is the new post value2022-03-14T00:00:00+00:002022-03-14T00:00:00+00:00https://luboganev.dev/post/observe-as-state-is-the-new-postvalue<h3 id="livedata---to-set-value-or-to-postvalue">LiveData - To set value or to postValue?</h3>
<p>Before the times of Jetpack Compose, we used to directly observe LiveData for changes in Android components that have lifecycle, such as for example Activity and Fragment. When writing updates to the LiveData, we have two options to choose from - <code class="language-plaintext highlighter-rouge">setValue</code> and <code class="language-plaintext highlighter-rouge">postValue</code>. The first one is synchronous operation and has to be executed on the main thread. The second one is asynchronous and can be invoked on other threads. PostValue internally schedules an update to be executed on the main thread Looper for the next Looper cycle, similar to how we can call post or postDelayed on a view.</p>
<p>This behavior is pretty straight forward and essentially results into the following guidelines when to use what:</p>
<ul>
<li>If you only care about the last value of a LiveData, you can simply always use postValue.</li>
<li>If you care about all intermediate values, then you need to be calling setValue, but then you also need to take care about thread safety yourself.</li>
</ul>
<h3 id="welcome-to-the-future---jetpack-composes">Welcome to the future - Jetpack Compose’s</h3>
<p>Jetpack Compose has its own lifecycle and functions rather differently than what we know from the imperative world of setting view properties by hand. It has its own primitive for observable data called State. In order to glue the LiveData world to the Compose world, we can use a helper extension funciton called <a href="https://developer.android.com/reference/kotlin/androidx/compose/runtime/livedata/package-summary#(androidx.lifecycle.LiveData).observeAsState()">observeAsState</a>. So all is good now, we’re all set and can use LiveData the same way as before, right? Not so fast.</p>
<h3 id="the-issue-with-observeasstate">The “issue” with observeAsState</h3>
<p>The documentation of the observeAsState() method reads:</p>
<blockquote>
<p>Every time there would be new value <strong>posted</strong> into the LiveData the returned State will be updated causing recomposition of every State.value usage.</p>
</blockquote>
<p>This got me thinking. Is it just English wording or does the word “post” actually convey also a functional meaning here? What happens when we call LiveData.setValue instead of postValue but we use this new function to transform it to Compose State?</p>
<p>Turns out it is not just a matter of wording. The observeAsState function actually behaves in a way that we will not receive every single intermediate update to the LiveData, regardless of whether we have called setValue or postValue. So it is essentially a forced postValue behavior always. This is a huge difference to what we’re used to and can lead to very unexpected bugs especially when we “just” change a view based UI to Compose, without touching the logic in the ViewModel.</p>
<h3 id="the-solution">The solution?</h3>
<p>There is no silver bullet, since it really depends on your use case. Probably the only time you really care about not missing an update to the LiveData is when you use it to propagate some events or commands, or when you accumulate some data over time. Those are not really the use cases LiveData was created for but hey, it used to work fine before, so why change it :)</p>
<p>The official Android architecture guidelines explain in great detail how to properly model ui events coming from the ViewModel through LiveData state here: <a href="https://developer.android.com/jetpack/guide/ui-layer/events?hl=en#handle-viewmodel-events">Handle ViewModel events</a>. This will resolve the issue of missing value. However, sometimes implementing this can be quite tricky if your ViewModel is consuming several asynchronous sources of data that utlimately map to UI state changes. It is not trivial to implement logic that waits for the confirmation from the UI that an event has been consumed and only then triggers a LiveData update with some new data that came asynchronously while waiting for the confirmation.</p>
<p>One solution to resolve the complexity could be to simply split up the UI events into their own dedicated LiveData with the correct confirmation handling as described by the official guide and keep the static UI state data into its own LiveData, where we care only about the last value.</p>
<p>Alternatively, you could opt out of the official way and simply consume the events LiveData outside of the Compose, so they would behave exactly the way you’re used to, given that you produce them by calling setValue.</p>
<p>You can also try to use different type of data channel, such a <a href="https://kotlinlang.org/docs/flow.html">Kotlin Flow</a> or what is a popular “replacement” for LiveData nowadays - the <a href="https://developer.android.com/kotlin/flow/stateflow-and-sharedflow">SharedFlow or StateFlow</a>. These however, have their own specific behavior which might be what you want or not depending on your use case. I will try to summarize some key aspects of LiveData, StateFlow, SharedFlow in the following table.</p>
<table>
<thead>
<tr>
<th> </th>
<th>LiveData</th>
<th>StateFlow</th>
<th>SharedFlow</th>
</tr>
</thead>
<tbody>
<tr>
<td>Nullability is defined by the type</td>
<td>No</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<td>Has getter for latest data</td>
<td>Yes</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Receive latest value immediately when observe/collect</td>
<td>Yes if there is already a value</td>
<td>Yes</td>
<td>No by default, but Yes if replay(1) is added and there was an emission</td>
</tr>
<tr>
<td>Can be initialized without initial value</td>
<td>Yes</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Backpressure needs handling</td>
<td>No</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<td>Each intermediate data update is received when observe / collect</td>
<td>Yes when setValue; No when postValue</td>
<td>No if exactly the same data (equals = true)</td>
<td>Yes</td>
</tr>
<tr>
<td>Each intermediate data update is received when observeAsState / collectAsState</td>
<td>No</td>
<td>Haven’t tested myself. Not sure.</td>
<td>Haven’t tested myself. Not sure.</td>
</tr>
</tbody>
</table>
<p>I would like to apologize for the last two missing cases I didn’t have time to test, but feel free to ping me with the results and I’ll update the post.</p>
<h3 id="the-moral-of-the-story">The moral of the story</h3>
<p>Jetpack Compose is an amazing toolkit for building modern UI. However, it has a learning curve that should not be underestimated. The way it works is very different from the classic view based Androiud UI and the glue functions for calling other Jetpack APIs do not necessarily behave exactly how you would expect. Therefore, be sure to always check how something works and don’t take your existing knowledge of the current platform as an absolute truth that applies to all new technology you encounter.</p>Lyubomir Ganevluboganev@gmail.comLiveData - To set value or to postValue? Before the times of Jetpack Compose, we used to directly observe LiveData for changes in Android components that have lifecycle, such as for example Activity and Fragment. When writing updates to the LiveData, we have two options to choose from - setValue and postValue. The first one is synchronous operation and has to be executed on the main thread. The second one is asynchronous and can be invoked on other threads. PostValue internally schedules an update to be executed on the main thread Looper for the next Looper cycle, similar to how we can call post or postDelayed on a view.Don’t let the scope trick you2020-10-18T00:00:00+00:002020-10-18T00:00:00+00:00https://luboganev.dev/post/dont-let-the-scope-trick-you<h3 id="kotlin-standard-library-scope-functions">Kotlin standard library scope functions</h3>
<p>The Kotlin language standard library comes with numerous very useful functions. Probably the most often used ones are the scope functions <code class="language-plaintext highlighter-rouge">let</code>, <code class="language-plaintext highlighter-rouge">with</code>, <code class="language-plaintext highlighter-rouge">run</code>, <code class="language-plaintext highlighter-rouge">also</code>, <code class="language-plaintext highlighter-rouge">apply</code>. In this post we will focus only on a common use case for the function <code class="language-plaintext highlighter-rouge">let</code>. For further information about the others please refer to the official library documentation available here: <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/">Kotlin standard library</a></p>
<h3 id="lets-use-let-for-nullability-checks">Let’s use <code class="language-plaintext highlighter-rouge">let</code> for nullability checks</h3>
<p>This is by far one of the most common uses I have observed in code. I assume that it is partially due to the fact that many mobile developers have tried the Swift language where <strong>optional</strong> types are in the type system just as <strong>nullable</strong> types are for Kotlin. Moreover, the keyword <code class="language-plaintext highlighter-rouge">let</code> also exists in Swift, and is commonly used to safely <strong>unwrap</strong> optional types and use them if they are not null.</p>
<p>However, the <code class="language-plaintext highlighter-rouge">let</code> in Kotlin is not a keyword but a higher order function, which brings some benefits but also hidden traps if you use it in a naive way. Let’s dive into an example.</p>
<h3 id="simple-example-of-nullability-handling">Simple example of nullability handling</h3>
<p>Let’s assume we have a weather report about current temperature. However, the temperature could also be null if for example our sensors have not delivered any data yet.</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="kd">var</span> <span class="py">temperature</span><span class="p">:</span> <span class="nc">Int</span><span class="p">?</span> <span class="p">=</span> <span class="mi">20</span>
<span class="n">temperature</span><span class="o">?.</span><span class="nf">let</span> <span class="p">{</span>
<span class="nf">storeInDb</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
<span class="p">}</span></code></pre></figure>
<p>This is a perfectly valid use case for a simple let function usage. We use it all the time and it is totally fine. However, the problems start if you actually need to also perform and action in case when the variable has value <code class="language-plaintext highlighter-rouge">null</code>. Normally in Kotlin, when handling nullability we are used to using the <strong>Elvis operator</strong> <code class="language-plaintext highlighter-rouge">?:</code>. Let’s just naively apply this practice to this use case as well. We’ll end up with the following code:</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="kd">var</span> <span class="py">temperature</span><span class="p">:</span> <span class="nc">Int</span><span class="p">?</span> <span class="p">=</span> <span class="mi">20</span>
<span class="n">temperature</span><span class="o">?.</span><span class="nf">let</span> <span class="p">{</span>
<span class="nf">storeInDb</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
<span class="p">}</span> <span class="o">?:</span> <span class="p">{</span>
<span class="nf">clearStoredValueFromDb</span><span class="p">()</span>
<span class="p">}</span></code></pre></figure>
<p>Now, at first glance this code looks just fine and logical. It should work, right? Unfortunately not always.</p>
<h3 id="the-issue-with-using-let-and--for-control-flow">The issue with using <code class="language-plaintext highlighter-rouge">let</code> and <code class="language-plaintext highlighter-rouge">?:</code> for control flow</h3>
<p>Our control flow logic is not anymore binary. It all depends down on what the <code class="language-plaintext highlighter-rouge">storeInDb</code> is returning… Let me explain. To understand what goes wrong, we need to take a closer look at what the <code class="language-plaintext highlighter-rouge">let</code> function is actually doing.</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="k">inline</span> <span class="k">fun</span> <span class="p"><</span><span class="nc">T</span><span class="p">,</span> <span class="nc">R</span><span class="p">></span> <span class="nc">T</span><span class="p">.</span><span class="nf">let</span><span class="p">(</span><span class="n">block</span><span class="p">:</span> <span class="p">(</span><span class="nc">T</span><span class="p">)</span> <span class="p">-></span> <span class="nc">R</span><span class="p">):</span> <span class="nc">R</span></code></pre></figure>
<p>So, the <code class="language-plaintext highlighter-rouge">let</code> function returns the value, which the passed lambda function return. We know that lambda functions in Kotlin normally have the return value of their last expression. So in our case, this will be the return value of the <code class="language-plaintext highlighter-rouge">storeInDb</code> function. The problem is, in the naive and quick fix we have done, it is not obvious what this value is. Therefore we need to look at the source code of the function <code class="language-plaintext highlighter-rouge">storeInDb</code> to figure out what is going on.</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="k">fun</span> <span class="nf">storeInDb</span><span class="p">(</span><span class="n">temperature</span><span class="p">:</span> <span class="nc">Int</span><span class="p">):</span> <span class="nc">Error</span><span class="p">?</span> <span class="p">{</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">db</span><span class="p">.</span><span class="nf">store</span><span class="p">(</span><span class="s">"temp"</span><span class="p">,</span> <span class="n">temprarature</span><span class="p">)</span>
<span class="k">return</span> <span class="k">null</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">e</span><span class="p">:</span> <span class="nc">Exception</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nc">Error</span><span class="p">(</span><span class="s">"Could not store in the DB."</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>So I think by now it would be clear that the addition we did actually created a bug. You see, the <code class="language-plaintext highlighter-rouge">storeInDb</code> has a return type, which is an optional Error. When it fails to store the value, it returns an error with a message. However, when it successfully stores the value, it returns null. So how will this affect our initial code? Well let’s put this all together and see the execution step by step.</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="k">fun</span> <span class="nf">storeInDb</span><span class="p">(</span><span class="n">temperature</span><span class="p">:</span> <span class="nc">Int</span><span class="p">):</span> <span class="nc">Error</span><span class="p">?</span> <span class="p">{</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">db</span><span class="p">.</span><span class="nf">store</span><span class="p">(</span><span class="s">"temp"</span><span class="p">,</span> <span class="n">temprarature</span><span class="p">)</span> <span class="c1">// 4. The store is successful</span>
<span class="k">return</span> <span class="k">null</span> <span class="c1">// 5. Returning null, since no error happened</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">e</span><span class="p">:</span> <span class="nc">Exception</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nc">Error</span><span class="p">(</span><span class="s">"Could not store in the DB."</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="py">temperature</span><span class="p">:</span> <span class="nc">Int</span><span class="p">?</span> <span class="p">=</span> <span class="mi">20</span> <span class="c1">// 1. The value we have is not null</span>
<span class="n">temperature</span><span class="o">?.</span><span class="nf">let</span> <span class="p">{</span> <span class="c1">// 2. Since the value is not null, we invoke the lambda in the let function</span>
<span class="nf">storeInDb</span><span class="p">(</span><span class="n">it</span><span class="p">)</span> <span class="c1">// 3. We call the store function. 6. The store function returns `null`</span>
<span class="p">}</span> <span class="o">?:</span> <span class="p">{</span>
<span class="c1">// 7. Since the whole previous block returned a null value, we execute the operation inside the elvis block</span>
<span class="nf">clearStoredValueFromDb</span><span class="p">()</span> <span class="c1">// 8. We delete the value we have just stored.</span>
<span class="p">}</span></code></pre></figure>
<h3 id="the-solution">The solution</h3>
<p>It’s simple. Just don’t use <code class="language-plaintext highlighter-rouge">let</code> function and <code class="language-plaintext highlighter-rouge">?:</code> operators for control flow decisions. Just use plain old if else with a temp local variable to allow for smart casing to work in Kotlin, like this:</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="kd">var</span> <span class="py">temperature</span><span class="p">:</span> <span class="nc">Int</span><span class="p">?</span> <span class="p">=</span> <span class="mi">20</span>
<span class="kd">val</span> <span class="py">temp</span> <span class="p">=</span> <span class="n">temperature</span>
<span class="k">if</span> <span class="p">(</span><span class="n">temp</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">storeInDb</span><span class="p">(</span><span class="n">temp</span><span class="p">)</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nf">clearStoredValueFromDb</span><span class="p">()</span>
<span class="p">}</span></code></pre></figure>
<p>It doesn’t look any more cluttered than before, but you don’t risk having weird bugs.</p>
<h3 id="the-moral-of-the-story">The moral of the story</h3>
<p>Be mindful when using Kotlin’s amazing language features and rich standard library. Do not fall for the trap for fancy looking or minimalistic code, if it makes the code non-readable or prone to errors.</p>Lyubomir Ganevluboganev@gmail.comKotlin standard library scope functions The Kotlin language standard library comes with numerous very useful functions. Probably the most often used ones are the scope functions let, with, run, also, apply. In this post we will focus only on a common use case for the function let. For further information about the others please refer to the official library documentation available here: Kotlin standard libraryBound services with Messenger2017-07-30T00:00:00+00:002017-07-30T00:00:00+00:00https://luboganev.dev/post/bound-services-messenger<h3 id="android-inter-process-communication-ipc">Android inter-process communication (IPC)</h3>
<p>TL;DR; if you want to get a very good understanding into how Android inter-process communication works, check out the following outstanding video about the Android Binder framework internals. It is long, but I really recommend it!</p>
<div class="responsive-embed responsive-embed-16by9">
<iframe src="https://www.youtube.com/embed/hiq3mGfLOtE" frameborder="0" allowfullscreen=""></iframe>
</div>
<blockquote>
<p>Inter Process Communication (IPC) has been a part of Android since 1.0, and yet most of us take it for granted. Intents, content providers, and system service managers hide the IPC infrastructure provided by Binder, but without it, the Android OS and our apps would simply fall apart. Binder/IPC is the glue that holds it all together. It enables Android’s memory management, security sandboxing, efficient threading, and countless other features on the Android platform.</p>
</blockquote>
<h3 id="what-are-bound-services">What are bound services</h3>
<p>A bound service is the server in a client-server interface. It allows other components to bind to the service, send requests, receive responses, and perform interprocess communication (IPC). Multiple clients can connect to a service simultaneously. A bound service typically lives only while it serves another application component and does not run in the background indefinitely, but an indefinitely running service can also be implemented in a way that clients can bind to it. For more information on service lifecycle, please refer to the official Android documentation about <a href="https://developer.android.com/guide/components/bound-services.html#Lifecycle">Managing the lifecycle of a bound service</a>.</p>
<h3 id="how-to-build-a-bound-service">How to build a bound service</h3>
<p>There are 3 different ways implement a bound service:</p>
<ul>
<li><strong>Extending the Binder class</strong> - this approach can be used when the client and the service live in the same codebase and run in the same process. When clients connect to the service, they can simply cast the received IBinder to the service implementation class, because both Service and Client are in the same codebase. Then they can directly call the service methods in a safe way. The client calls and service reponses run in the application main thread by default, but can be extended to run in a background thread with a bit of extra work.</li>
<li><strong>Using a Messenger</strong> - we will go into much detail about this particular technique in this article. For now, it’s just important to mention it supports communication between different processes and also across different code bases with the help of a bit of shared code. The threading model depends on the implementation, but typically there is a single background thread with message queue, where all clients send commands.</li>
<li><strong>Using AIDL</strong> - This approach is the most abstract and most flexible of all. It does not normally require any shared code except for the service interface declared in the so called Android Interface Definition Language (AIDL) files. Each connected client sends calls to the service from a different thread, so it also requires thread-safe implementation on the service side.</li>
</ul>
<h3 id="bound-services-with-messenger">Bound services with Messenger</h3>
<p>In this article we will implement a bound service, using the Messenger approach. We’ll also extract part of the needed code as common shared code, we will call contract. This will allow us to use the Messenger approach even between apps that do not shared a common code base. You can find here the
<a href="https://developer.android.com/guide/components/bound-services.html#Messenger">official documentation</a> for implementing Messenger bound service.</p>
<h5 id="which-components-do-we-need">Which components do we need</h5>
<ul>
<li><a href="https://developer.android.com/reference/android/app/Service.html">Service</a> - A Service is an application component representing either an application’s desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use. In our case we need to extend this class in order to implement a bound service.</li>
<li><a href="https://developer.android.com/reference/android/content/ServiceConnection.html">ServiceConnection</a> - this interface is used by a client in order to establish connection with a bound service. It gets callbacks from the OS, when the client connects to a service or when the connection is lost.</li>
<li><a href="https://developer.android.com/reference/android/os/Messenger.html">Messenger</a> - This class represents a reference to a Handler, which others can use in order to send messages to it. This allows for the implementation of message-based communication across processes, by creating a Messenger pointing to a Handler in one process, and handing that Messenger to another process. In our case, when connected to a bound service, the clients receive a Messenger initialized by that service. They can use it to send IPC calls to the bound service. If they want to receive responses back from the bound service, then they need to initialize their own Messenger, and pass it via the <a href="https://developer.android.com/reference/android/os/Message.html#replyTo">replyTo</a> field of the messages they send to the bound service. This way, when the bound service receives a Message containing a replyTo Messenger, it could extract this Messenger and send the response messages through it.</li>
<li><a href="https://developer.android.com/reference/android/os/Messenger.html">Handler</a> - A Handler allows to send and process Message objects associated with a thread’s MessageQueue. In our case, the service needs to initialize a Handler, wrap it into a Messenger and provide this Messenger to connected clients so that they can send messages. The incoming messages can be processed in the <a href="https://developer.android.com/reference/android/os/Handler.html#handleMessage(android.os.Message)">handleMessage</a> method of the Handler.</li>
<li><a href="https://developer.android.com/reference/android/os/Message.html">Message</a> - Defines a message containing a description and arbitrary data object that can be sent to a Handler. In our case, both client calls to the bound service and service responses will be wrapped into instances of the Message class and passed through the corresponding Messenger.</li>
<li><a href="https://developer.android.com/reference/android/content/Intent.html">Intent</a> - An intent is an abstract description of an operation to be performed. In our case it is used when clients want to bind to a remote service. It contains the necessary information, so that the OS can locate the application and component, where the implementation of the bound service is done. On the service side, when client binds, the incoming Intent can be used to identify the connecting client.</li>
<li><a href="https://developer.android.com/reference/android/os/Bundle.html">Bundle</a> - A mapping from String keys to various <a href="https://developer.android.com/reference/android/os/Parcelable.html">Parcelable</a> values. In our case, Bundles are used to define the properties of the bind Intent constructed by the client. In addition, all data in Message sent back and forth between client and service is a Bundle.</li>
</ul>
<h5 id="defining-the-common-contract">Defining the common contract</h5>
<p>When Messengers are used for bound service communication, there are no explicit calls to particular service methods, instead Messages have to include enough payload and metadata to uniquely define the operation which the service should perform.</p>
<p>In addition, Messages are very generic objects, therefore the service and the client have to share a common contract for defining the available commands, flags, payload formatting, and common Parcelable data classes. This contract has to be shared between the client and service, which means a shared library in case they are located in different apps.</p>
<p>The following code snippets wrap the common contract into a convenient to use class.</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="kd">class</span> <span class="nc">MessengerContract</span> <span class="p">{</span>
<span class="kd">class</span> <span class="nc">InvalidPayloadException</span><span class="p">(</span><span class="n">message</span><span class="p">:</span> <span class="nc">String</span><span class="p">)</span> <span class="p">:</span> <span class="nc">RuntimeException</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
<span class="k">companion</span> <span class="k">object</span> <span class="p">{</span>
<span class="k">private</span> <span class="k">const</span> <span class="kd">val</span> <span class="py">SERVICE_PACKAGE_NAME</span> <span class="p">=</span> <span class="s">"com.luboganev.testground"</span>
<span class="k">private</span> <span class="k">const</span> <span class="kd">val</span> <span class="py">SERVICE_CLASS_NAME</span> <span class="p">=</span> <span class="s">"$SERVICE_PACKAGE_NAME.demos.ipcMessenger.service.MessengerService"</span>
<span class="kd">val</span> <span class="py">serviceBindIntent</span><span class="p">:</span> <span class="nc">Intent</span>
<span class="k">get</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nc">Intent</span><span class="p">()</span>
<span class="p">.</span><span class="nf">setComponent</span><span class="p">(</span>
<span class="nc">ComponentName</span><span class="p">(</span><span class="nc">SERVICE_PACKAGE_NAME</span><span class="p">,</span> <span class="nc">SERVICE_CLASS_NAME</span><span class="p">)</span>
<span class="p">)</span>
<span class="p">}</span>
<span class="k">const</span> <span class="kd">val</span> <span class="py">WHAT_SAY_HELLO</span> <span class="p">=</span> <span class="mi">1</span>
<span class="k">const</span> <span class="kd">val</span> <span class="py">WHAT_ADD_TWO_NUMBERS</span> <span class="p">=</span> <span class="mi">2</span>
<span class="k">const</span> <span class="kd">val</span> <span class="py">WHAT_ADD_TWO_NUMBERS_RESULT</span> <span class="p">=</span> <span class="mi">3</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>We start by defining common constants, such as Message types, properties related to establishing the initial service connection and common exception. Next up, we define a class related to each Request-Response communication channel between the service and the client.</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="o">..</span><span class="p">.</span>
<span class="kd">class</span> <span class="nc">SayHello</span> <span class="p">{</span>
<span class="k">companion</span> <span class="k">object</span> <span class="p">{</span>
<span class="k">private</span> <span class="kd">val</span> <span class="py">PAYLOAD_KEY_MESSAGE</span> <span class="p">=</span> <span class="s">"message"</span>
<span class="k">fun</span> <span class="nf">buildRequestMessage</span><span class="p">(</span><span class="n">messageText</span><span class="p">:</span> <span class="nc">String</span><span class="p">)</span> <span class="p">:</span> <span class="nc">Message</span> <span class="p">{</span>
<span class="kd">val</span> <span class="py">message</span> <span class="p">=</span> <span class="nc">Message</span><span class="p">.</span><span class="nf">obtain</span><span class="p">(</span><span class="k">null</span><span class="p">,</span> <span class="nc">WHAT_SAY_HELLO</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">message</span><span class="p">.</span><span class="n">data</span> <span class="p">=</span> <span class="nf">wrapRequestMessagePayload</span><span class="p">(</span><span class="n">messageText</span><span class="p">)</span>
<span class="k">return</span> <span class="n">message</span>
<span class="p">}</span>
<span class="k">private</span> <span class="k">fun</span> <span class="nf">wrapRequestMessagePayload</span><span class="p">(</span><span class="n">messageText</span><span class="p">:</span> <span class="nc">String</span><span class="p">):</span> <span class="nc">Bundle</span> <span class="p">{</span>
<span class="kd">val</span> <span class="py">payload</span> <span class="p">=</span> <span class="nc">Bundle</span><span class="p">()</span>
<span class="n">payload</span><span class="p">.</span><span class="nf">putString</span><span class="p">(</span><span class="nc">PAYLOAD_KEY_MESSAGE</span><span class="p">,</span> <span class="n">messageText</span><span class="p">)</span>
<span class="k">return</span> <span class="n">payload</span>
<span class="p">}</span>
<span class="k">fun</span> <span class="nf">parseRequestMessagePayload</span><span class="p">(</span><span class="n">payload</span><span class="p">:</span> <span class="nc">Bundle</span><span class="p">?):</span> <span class="nc">String</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">payload</span> <span class="p">!=</span> <span class="k">null</span> <span class="p">&&</span> <span class="n">payload</span><span class="p">.</span><span class="nf">containsKey</span><span class="p">(</span><span class="nc">PAYLOAD_KEY_MESSAGE</span><span class="p">))</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">payload</span><span class="p">.</span><span class="nf">getString</span><span class="p">(</span><span class="nc">MessengerContract</span><span class="p">.</span><span class="nc">SayHello</span><span class="p">.</span><span class="nc">PAYLOAD_KEY_MESSAGE</span><span class="p">)</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="k">throw</span> <span class="nc">InvalidPayloadException</span><span class="p">(</span><span class="s">"Payload of SayHello request is missing"</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="o">..</span><span class="p">.</span></code></pre></figure>
<p>This class defines constants needed to encode the payload of messages as well convenience methods for building and parsing the Messages sent between clients and the service. In case a service response is required, we can extend this structure a bit by adding a replyTo Messenger, like the following example:</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="o">..</span><span class="p">.</span>
<span class="kd">class</span> <span class="nc">AddTwoIntegers</span> <span class="p">{</span>
<span class="k">companion</span> <span class="k">object</span> <span class="p">{</span>
<span class="k">private</span> <span class="kd">val</span> <span class="py">PAYLOAD_KEY_NUMBERS_CONTAINER</span> <span class="p">=</span> <span class="s">"numbers_container"</span>
<span class="k">private</span> <span class="kd">val</span> <span class="py">PAYLOAD_KEY_NUMBERS_ADDITION_RESULT</span> <span class="p">=</span> <span class="s">"numbers_addition_result"</span>
<span class="k">fun</span> <span class="nf">buildRequestMessage</span><span class="p">(</span><span class="n">twoIntegers</span><span class="p">:</span> <span class="nc">TwoIntegersContainer</span><span class="p">,</span> <span class="n">replyTo</span><span class="p">:</span> <span class="nc">Messenger</span><span class="p">)</span> <span class="p">:</span> <span class="nc">Message</span> <span class="p">{</span>
<span class="kd">val</span> <span class="py">message</span> <span class="p">=</span> <span class="nc">Message</span><span class="p">.</span><span class="nf">obtain</span><span class="p">(</span><span class="k">null</span><span class="p">,</span> <span class="nc">WHAT_ADD_TWO_NUMBERS</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">message</span><span class="p">.</span><span class="n">data</span> <span class="p">=</span> <span class="nf">wrapRequestMessagePayload</span><span class="p">(</span><span class="n">twoIntegers</span><span class="p">)</span>
<span class="n">message</span><span class="p">.</span><span class="n">replyTo</span> <span class="p">=</span> <span class="n">replyTo</span>
<span class="k">return</span> <span class="n">message</span>
<span class="p">}</span>
<span class="k">private</span> <span class="k">fun</span> <span class="nf">wrapRequestMessagePayload</span><span class="p">(</span><span class="n">twoIntegers</span><span class="p">:</span> <span class="nc">TwoIntegersContainer</span><span class="p">):</span> <span class="nc">Bundle</span> <span class="p">{</span>
<span class="kd">val</span> <span class="py">payload</span> <span class="p">=</span> <span class="nc">Bundle</span><span class="p">()</span>
<span class="n">payload</span><span class="p">.</span><span class="nf">putParcelable</span><span class="p">(</span><span class="nc">PAYLOAD_KEY_NUMBERS_CONTAINER</span><span class="p">,</span> <span class="n">twoIntegers</span><span class="p">)</span>
<span class="k">return</span> <span class="n">payload</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="o">..</span><span class="p">.</span></code></pre></figure>
<p>For the full implementation of the contract and all related helper methods and classes, please refer to the source code of the sample app on GitHub and more specifically the <a href="https://github.com/luboganev/testground/tree/master/TestgroundApp/ipc-shared/"><strong>module containing the shared code</strong></a></p>
<h5 id="building-the-service-part">Building the service part</h5>
<p>Building the service part is pretty simple and requires just a few components.</p>
<p><img src="https://luboganev.dev/images/2017-07-30-bound-services-messenger/messenger_service.png" alt="Messenger service structure" /></p>
<p>And here’s the corresponding code snippet to the diagram.</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="kd">class</span> <span class="nc">MessengerService</span> <span class="p">:</span> <span class="nc">Service</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">class</span> <span class="nc">IncomingHandler</span><span class="p">(</span><span class="kd">val</span> <span class="py">applicationContext</span><span class="p">:</span> <span class="nc">Context</span><span class="p">)</span> <span class="p">:</span> <span class="nc">Handler</span><span class="p">()</span> <span class="p">{</span>
<span class="k">override</span> <span class="k">fun</span> <span class="nf">handleMessage</span><span class="p">(</span><span class="n">msg</span><span class="p">:</span> <span class="nc">Message</span><span class="p">?)</span> <span class="p">{</span>
<span class="c1">// handle messages</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kd">val</span> <span class="py">messenger</span> <span class="k">by</span> <span class="nf">lazy</span> <span class="p">{</span> <span class="nc">Messenger</span><span class="p">(</span><span class="nc">IncomingHandler</span><span class="p">(</span><span class="n">applicationContext</span><span class="p">))</span> <span class="p">}</span>
<span class="k">override</span> <span class="k">fun</span> <span class="nf">onBind</span><span class="p">(</span><span class="n">intent</span><span class="p">:</span> <span class="nc">Intent</span><span class="p">):</span> <span class="nc">IBinder</span><span class="p">?</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">messenger</span><span class="p">.</span><span class="n">binder</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<ol>
<li>We declare a Handler and implement the message handling in its <em>handleMessage()</em> method</li>
<li>We extend the Service class and override it’s <em>onBind</em> method.</li>
<li>We wrap the declared Handler into a Messenger implementation and return it from the <em>onBind</em> method. Messenger class implements IBinder, so wo don’t have to do any casting.</li>
</ol>
<p>The following code snippet demonstrates how different types of client messages are handled in the Handler.</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="o">..</span><span class="p">.</span>
<span class="k">override</span> <span class="k">fun</span> <span class="nf">handleMessage</span><span class="p">(</span><span class="n">msg</span><span class="p">:</span> <span class="nc">Message</span><span class="p">?)</span> <span class="p">{</span>
<span class="k">when</span><span class="p">(</span><span class="n">msg</span><span class="o">?.</span><span class="n">what</span><span class="p">)</span> <span class="p">{</span>
<span class="nc">MessengerContract</span><span class="p">.</span><span class="nc">WHAT_SAY_HELLO</span> <span class="p">-></span> <span class="p">{</span>
<span class="kd">val</span> <span class="py">incomingMessage</span> <span class="p">=</span> <span class="nc">MessengerContract</span><span class="p">.</span><span class="nc">SayHello</span><span class="p">.</span><span class="nf">parseRequestMessagePayload</span><span class="p">(</span><span class="n">msg</span><span class="p">.</span><span class="n">data</span><span class="p">)</span>
<span class="c1">// show message to user</span>
<span class="p">}</span>
<span class="nc">MessengerContract</span><span class="p">.</span><span class="nc">WHAT_ADD_TWO_NUMBERS</span> <span class="p">-></span> <span class="p">{</span>
<span class="k">try</span> <span class="p">{</span>
<span class="kd">val</span> <span class="py">twoIntegersContainer</span> <span class="p">=</span> <span class="nc">MessengerContract</span><span class="p">.</span><span class="nc">AddTwoIntegers</span><span class="p">.</span><span class="nf">parseRequestMessagePayload</span><span class="p">(</span><span class="n">msg</span><span class="p">.</span><span class="n">data</span><span class="p">)</span>
<span class="c1">// calculate result and wrap it into a result</span>
<span class="kd">val</span> <span class="py">resultMessage</span> <span class="p">=</span> <span class="nc">MessengerContract</span><span class="p">.</span><span class="nc">AddTwoIntegers</span><span class="p">.</span><span class="nf">buildResponseMessage</span><span class="p">(</span>
<span class="n">twoIntegersContainer</span><span class="p">.</span><span class="n">first</span> <span class="p">+</span> <span class="n">twoIntegersContainer</span><span class="p">.</span><span class="n">second</span><span class="p">)</span>
<span class="c1">// use the replyTo to send back result to client messenger</span>
<span class="n">msg</span><span class="p">.</span><span class="n">replyTo</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="n">resultMessage</span><span class="p">)</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">e</span><span class="p">:</span> <span class="nc">MessengerContract</span><span class="p">.</span><span class="nc">InvalidPayloadException</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// show invalid payload error to user</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">-></span> <span class="p">{</span>
<span class="c1">// show unknown message type error to user</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="o">..</span><span class="p">.</span></code></pre></figure>
<h5 id="building-the-client-part">Building the client part</h5>
<p>Building the client is also very easy an includes just a few components.</p>
<p><img src="https://luboganev.dev/images/2017-07-30-bound-services-messenger/client_connection.png" alt="Client connection structure" /></p>
<p>And here’s the corresponding code snippet to the diagram.</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="o">..</span><span class="p">.</span>
<span class="k">private</span> <span class="k">fun</span> <span class="nf">bindToService</span><span class="p">()</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(!</span><span class="n">boundToService</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">bindService</span><span class="p">(</span><span class="nc">MessengerContract</span><span class="p">.</span><span class="n">serviceBindIntent</span><span class="p">,</span> <span class="n">messengerServiceConnection</span><span class="p">,</span> <span class="nc">BIND_AUTO_CREATE</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">private</span> <span class="k">fun</span> <span class="nf">unbindFromService</span><span class="p">()</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">boundToService</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">unbindService</span><span class="p">(</span><span class="n">messengerServiceConnection</span><span class="p">)</span>
<span class="n">boundToService</span> <span class="p">=</span> <span class="k">false</span>
<span class="n">serviceCallsMessenger</span> <span class="p">=</span> <span class="k">null</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">private</span> <span class="kd">var</span> <span class="py">serviceCallsMessenger</span><span class="p">:</span> <span class="nc">Messenger</span><span class="p">?</span> <span class="p">=</span> <span class="k">null</span>
<span class="k">private</span> <span class="kd">val</span> <span class="py">messengerServiceConnection</span> <span class="p">=</span> <span class="kd">object</span> <span class="err">: </span><span class="nc">ServiceConnection</span> <span class="p">{</span>
<span class="k">override</span> <span class="k">fun</span> <span class="nf">onServiceDisconnected</span><span class="p">(</span><span class="n">name</span><span class="p">:</span> <span class="nc">ComponentName</span><span class="p">?)</span> <span class="p">{</span>
<span class="n">boundToService</span> <span class="p">=</span> <span class="k">false</span>
<span class="n">serviceCallsMessenger</span> <span class="p">=</span> <span class="k">null</span>
<span class="p">}</span>
<span class="k">override</span> <span class="k">fun</span> <span class="nf">onServiceConnected</span><span class="p">(</span><span class="n">name</span><span class="p">:</span> <span class="nc">ComponentName</span><span class="p">?,</span> <span class="n">service</span><span class="p">:</span> <span class="nc">IBinder</span><span class="p">?)</span> <span class="p">{</span>
<span class="n">serviceCallsMessenger</span> <span class="p">=</span> <span class="nc">Messenger</span><span class="p">(</span><span class="n">service</span><span class="p">)</span>
<span class="n">boundToService</span> <span class="p">=</span> <span class="k">true</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="o">..</span><span class="p">.</span></code></pre></figure>
<ol>
<li>We implement a ServiceConnection interface, which receives callbacks when connection is established or lost.</li>
<li>We call <em>context.bindService()</em> method and pass the ServiceConnection in it.</li>
<li>We wrap the received IBinder into a Messenger, which basically represents the service Messenger we have defined in the Service implementation above.</li>
<li>We call the <em>send()</em> method of the messenger to send messages to the service.</li>
</ol>
<h3 id="time-to-play---try-out-the-different-options-in-the-companion-app">Time to play - try out the different options in the companion app</h3>
<p>I have included a demo in the blog’s companion app where you can test the <em>Messenger IPC</em>, including two types of remote service calls:</p>
<ul>
<li>Fire-and-forget - Call, which sends a <em>String</em> message to the service and expects no response</li>
<li>Request-Response - A call to the service sending two integers, which expects a response with the result of their addition. In addition, the integers are packed into a custom data class, in order to demonstrate the ability to send <em>Parcelable</em> payload through the Messenger API.</li>
</ul>
<p>You can find the source code on <a href="https://github.com/luboganev/testground"><strong>GitHub</strong></a></p>Lyubomir Ganevluboganev@gmail.comAndroid inter-process communication (IPC) TL;DR; if you want to get a very good understanding into how Android inter-process communication works, check out the following outstanding video about the Android Binder framework internals. It is long, but I really recommend it!Watch your returns in inline functions2017-07-11T00:00:00+00:002017-07-11T00:00:00+00:00https://luboganev.dev/post/kotlin-inline-fun-return<p>Kotlin is a great programming language and I guess all Android developers have already started adopting it in their code base. However, it has a learning curve and numerous language features, which Java does not have. In order to write bug-free code, we need to be extra careful when using these new features, simply because we might make mistakes due to our years of Java coding. The following example mistake might be an extreme corner case, but it still managed to slip through code review.</p>
<h3 id="kotlin-inline-functions-introduction">Kotlin inline functions introduction</h3>
<p>Kotlin supports higher-order functions, but using them imposes certain runtime penalties: each function is an object, and it captures a closure, i.e. those variables that are accessed in the body of the function. Memory allocations (both for function objects and classes) and virtual calls introduce runtime overhead. Inline functions allow that the function call is effectively replaced by the compiler with the function body. This feature could help with performance improvements, and also can reduce your method count in your codebase, which is especially painful topic in Android development. For more information visit the official documentation for <a href="https://kotlinlang.org/docs/reference/inline-functions.html">Kotlin Inline Functions</a>.</p>
<p>So here is an example of a simple inline function:</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="k">inline</span> <span class="k">fun</span> <span class="p"><</span><span class="nc">T</span><span class="p">,</span> <span class="nc">V</span><span class="p">></span> <span class="nf">executeBetweenWork</span><span class="p">(</span><span class="n">param</span><span class="p">:</span> <span class="nc">T</span><span class="p">,</span> <span class="n">action</span><span class="p">:</span> <span class="p">(</span><span class="nc">T</span><span class="p">)</span> <span class="p">-></span> <span class="nc">V</span><span class="p">):</span> <span class="nc">V</span> <span class="p">{</span>
<span class="nf">println</span><span class="p">(</span><span class="s">"Do work before"</span><span class="p">)</span>
<span class="kd">val</span> <span class="py">result</span> <span class="p">=</span> <span class="nf">action</span><span class="p">(</span><span class="n">param</span><span class="p">)</span>
<span class="nf">println</span><span class="p">(</span><span class="s">"Do work after"</span><span class="p">)</span>
<span class="k">return</span> <span class="n">result</span>
<span class="p">}</span></code></pre></figure>
<p>This function simply prints some text to the console, invokes an input lambda expression and returns its result. Pretty simple and awesome.</p>
<h3 id="the-misplaced-return-statement">The misplaced return statement</h3>
<p>The above function is great, but it could cause trouble if you do not invoke it properly, due to its inline nature. Let me explain by giving an example.</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="k">fun</span> <span class="nf">wrongCheckSingleTextCharacterWithLambda</span><span class="p">():</span> <span class="nc">Boolean</span> <span class="p">{</span>
<span class="nf">println</span><span class="p">(</span><span class="s">"Prepare to invoke inline fun with lambda"</span><span class="p">)</span>
<span class="nf">executeBetweenWork</span><span class="p">(</span><span class="s">"Some parameter"</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">println</span><span class="p">(</span><span class="s">"Doing lambda work"</span><span class="p">)</span>
<span class="k">return</span> <span class="n">it</span><span class="p">.</span><span class="n">length</span> <span class="p">></span> <span class="mi">1</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>So what exactly is the problem here? Well, the position of the return statement. You see, as Java developers, we’re used to writing return statement at the end of a function that returns a value. However, Kotlin will actually show you a compile time error if you try to write a return statements in a lambda.</p>
<p>But wait! Why does the example above even compile? Well, it’s due to the fact that the lambda is being passed to an inline function. So when we compile the code, what effectively will happen after the inline function gets replaced is analogous to the following:</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="k">fun</span> <span class="nf">wrongCheckSingleTextCharacterWithLambda</span><span class="p">():</span> <span class="nc">Boolean</span> <span class="p">{</span>
<span class="c1">// replaced inline fun body</span>
<span class="nf">println</span><span class="p">(</span><span class="s">"Prepare to invoke inline fun"</span><span class="p">)</span>
<span class="nf">println</span><span class="p">(</span><span class="s">"Do work before"</span><span class="p">)</span>
<span class="c1">// replaced labda invocation</span>
<span class="nf">println</span><span class="p">(</span><span class="s">"Doing Lambda work"</span><span class="p">)</span>
<span class="k">return</span> <span class="s">"Some parameter"</span><span class="p">.</span><span class="n">length</span> <span class="p">></span> <span class="mi">1</span>
<span class="c1">// remaining inline fun body can never be reached</span>
<span class="c1">// and will be removed by the compiler</span>
<span class="c1">// println("Do work after")</span>
<span class="c1">// return result</span>
<span class="p">}</span></code></pre></figure>
<p>The code above might not be exactly what Kotlin generates in byte code, but please bear with me, I’m just trying to make a point with it. You see, if we write the return statement at the wrong place we will effectively skip the remaining inline function body, which might be a serious bug and a very hard one to spot. The following example shows the correct way to invoke the lambda in an inline function. Notice the position of the return statement. It is not inside the lambda.</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="k">fun</span> <span class="nf">correctCheckSingleTextCharacterWithLambda</span><span class="p">():</span> <span class="nc">Boolean</span> <span class="p">{</span>
<span class="nf">println</span><span class="p">(</span><span class="s">"Prepare to invoke inline fun with lambda"</span><span class="p">)</span>
<span class="k">return</span> <span class="nf">executeBetweenWork</span><span class="p">(</span><span class="s">"Some parameter"</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">println</span><span class="p">(</span><span class="s">"Doing lambda work"</span><span class="p">)</span>
<span class="n">it</span><span class="p">.</span><span class="n">length</span> <span class="p">></span> <span class="mi">1</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>And here is the log in the terminal, showing clearly when the “Do work after” is invoked and when not.</p>
<figure class="highlight"><pre><code class="language-text" data-lang="text">=================================================================
Execute function invoking lambda with return in the WRONG place
=================================================================
Prepare to invoke inline fun with lambda
Do work before lambda
Doing lambda work
=================================================================
Execute function invoking lambda with return in the CORRECT place
=================================================================
Prepare to invoke inline fun with lambda
Do work before lambda
Doing lambda work
Do work after lambda
=================================================================</code></pre></figure>
<h3 id="how-to-not-make-this-mistake">How to not make this mistake</h3>
<p>First, just for testing purposes, remove the <em>inline</em> keyword in front of the <em>executeBetweenWork</em> function. When you do this, the compiler will immediately spot the misplaced return statement and mark it as a compiler error. But please do not give up completely on inline functions! There is another way of fixing this issue. You can mark any of the input parameters with the modifier <em>noinline</em> like this:</p>
<figure class="highlight"><pre><code class="language-kotlin" data-lang="kotlin"><span class="k">inline</span> <span class="k">fun</span> <span class="p"><</span><span class="nc">T</span><span class="p">,</span> <span class="nc">V</span><span class="p">></span> <span class="nf">executeBetweenWork</span><span class="p">(</span><span class="n">param</span><span class="p">:</span> <span class="nc">T</span><span class="p">,</span> <span class="k">noinline</span> <span class="n">action</span><span class="p">:</span> <span class="p">(</span><span class="nc">T</span><span class="p">)</span> <span class="p">-></span> <span class="nc">V</span><span class="p">):</span> <span class="nc">V</span> <span class="p">{</span>
<span class="nf">println</span><span class="p">(</span><span class="s">"Do work before"</span><span class="p">)</span>
<span class="kd">val</span> <span class="py">result</span> <span class="p">=</span> <span class="nf">action</span><span class="p">(</span><span class="n">param</span><span class="p">)</span>
<span class="nf">println</span><span class="p">(</span><span class="s">"Do work after"</span><span class="p">)</span>
<span class="k">return</span> <span class="n">result</span>
<span class="p">}</span></code></pre></figure>
<p>When you do this, the compiler will again spot the misplaced return statement and mark it as a compile time error.</p>
<h3 id="summary">Summary</h3>
<p>Inline functions and lambdas are great features of the Kotlin language. We should definitely learn how to used them and add them to our toolkit for developing apps every day. However, we should be mindful with them and be extra careful to keep our execution flow exactly the way we want it to be.</p>Lyubomir Ganevluboganev@gmail.comKotlin is a great programming language and I guess all Android developers have already started adopting it in their code base. However, it has a learning curve and numerous language features, which Java does not have. In order to write bug-free code, we need to be extra careful when using these new features, simply because we might make mistakes due to our years of Java coding. The following example mistake might be an extreme corner case, but it still managed to slip through code review.Alarms and Pending Intents2016-06-13T00:00:00+00:002016-06-13T00:00:00+00:00https://luboganev.dev/post/alarms-pending-intent<p>The Android SDK offers an API for scheduling one time or recurring events called alarms. This is for example how your alarm clock applications work, or how a reminder for a calendar event is triggered. It’s pretty simple to use but is has some specific behavior, which you need to take in account. In this post I will describe some of the problems I have encountered when not completely understanding how this API works.</p>
<h3 id="how-do-you-schedule-a-simple-one-time-alarm">How do you schedule a simple one time alarm</h3>
<p>Well basically it should look something like this.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">Calendar</span> <span class="n">c</span> <span class="o">=</span> <span class="nc">Calendar</span><span class="o">.</span><span class="na">getInstance</span><span class="o">();</span>
<span class="n">c</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="nc">Calendar</span><span class="o">.</span><span class="na">SECOND</span><span class="o">,</span> <span class="mi">10</span><span class="o">);</span>
<span class="kd">final</span> <span class="kt">long</span> <span class="n">afterTenSeconds</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="na">getTimeInMillis</span><span class="o">();</span>
<span class="kd">final</span> <span class="kt">int</span> <span class="n">requestCode</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
<span class="kd">final</span> <span class="nc">Intent</span> <span class="n">myIntent</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Intent</span><span class="o">(</span><span class="s">"MyIntentAction"</span><span class="o">);</span>
<span class="n">notificationIntent</span><span class="o">.</span><span class="na">addCategory</span><span class="o">(</span><span class="s">"android.intent.category.DEFAULT"</span><span class="o">);</span>
<span class="n">notificationIntent</span><span class="o">.</span><span class="na">putExtra</span><span class="o">(</span><span class="s">"message"</span><span class="o">,</span> <span class="s">"Hello world!"</span><span class="o">);</span>
<span class="nc">AlarmManager</span> <span class="n">alarmManager</span> <span class="o">=</span> <span class="o">(</span><span class="nc">AlarmManager</span><span class="o">)</span> <span class="n">context</span><span class="o">.</span><span class="na">getSystemService</span><span class="o">(</span><span class="nc">Context</span><span class="o">.</span><span class="na">ALARM_SERVICE</span><span class="o">);</span>
<span class="nc">PendingIntent</span> <span class="n">broadcast</span> <span class="o">=</span> <span class="nc">PendingIntent</span><span class="o">.</span><span class="na">getBroadcast</span><span class="o">(</span><span class="n">context</span><span class="o">,</span> <span class="n">requestCode</span><span class="o">,</span>
<span class="n">myIntent</span><span class="o">,</span> <span class="nc">PendingIntent</span><span class="o">.</span><span class="na">FLAG_UPDATE_CURRENT</span><span class="o">);</span>
<span class="n">alarmManager</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="nc">AlarmManager</span><span class="o">.</span><span class="na">RTC_WAKEUP</span><span class="o">,</span> <span class="n">afterTenSeconds</span><span class="o">,</span> <span class="n">broadcast</span><span class="o">);</span></code></pre></figure>
<p>So what you typically do is to wrap an <em>Intent</em> into a <em>PendingIntent</em> of a particular type and then call the <em>AlarmManager</em> to execute this <em>PendingIntent</em> at some point in time in the future. The last part is, you need to have a component such as a <em>BroadcastReceiver</em>, <em>Activity</em> or a <em>Service</em> to receive the wrapped <em>Intent</em> and do something useful with it.</p>
<h3 id="what-is-a-pendingintent">What is a <em>PendingIntent</em></h3>
<p>PendingIntents are a very powerful API in the Android SDK. They allow you to wrap a particular Intent specific to your application in order to give it to another application. The nice thing is, they provide the other application with the required security permissions to actually invoke the Intent you have wrapped. Since Intents are can be broadcasted or used to start an <em>Activity</em> or a <em>Service</em>, there are different methods for building a PendingIntent. In the example above, we have used the <em>getBroadcast()</em> method, but there are also methods <em>getActivity()</em> and <em>getService()</em>.</p>
<p>What is important to understand is that <em>PendingIntents</em> are not exclusively used only for scheduling alarms through the <em>AlarmManager</em>. They are also used for example by the <em>NotificationManager</em> when showing statusbar notifications. Therefore, <em>PendingIntents</em> have a couple of specific properties which you have to understand, before you start using them to schedule alarms.</p>
<h3 id="the-pendingintent-request-code">The <em>PendingIntent</em> request code</h3>
<p>As you have noticed, when building a <em>PendingIntent</em>, you are required to provide an integer called <em>requestCode</em>. The official documentation states that this is a “private request code for the sender”. However, request codes are also a fundamental way to distinguish between <em>PendingIntent</em> instances. You see, the <em>getBroadcast()</em> method is much more than a just a static factory for creating a <em>PendingIntent</em> instance. It internally registers this particular <em>PendingIntent</em> into a kind of global system registry with all <em>PendingIntents</em> from all applications. Remember, the <em>PendingIntents</em> are designed so that other applications could invoke a particular <em>Intent</em> of your application. Therefore a system wide registry makes a lot of sense.</p>
<p>You might wonder, how the single integer for a request code is enough to guarantee that no <em>PendingIntent</em> will be accidentally overwritten by another application? Thankfully, the request code is not solely responsible for determining the uniqueness of a <em>PendingIntent</em>.</p>
<h3 id="pendingintent-disctinction"><em>PendingIntent</em> disctinction</h3>
<p>How do you know if two PendintIntents are the same? It is important to understand that a <em>PendingIntent</em> is just a container with extra functionality, which carries your wrapped <em>Intent</em> inside of it. If you look at the <em>equals()</em> method implementation inside the <em>PendingIntent</em> class, you will find this description:</p>
<blockquote>
<p>Comparison operator on two PendingIntent objects, such that true is returned then they both represent the same operation from the same package. This allows you to use {@link #getActivity}, {@link #getBroadcast}, or {@link #getService} multiple times (even across a process being killed), resulting in different PendingIntent objects but whose equals() method identifies them as being the same operation.</p>
</blockquote>
<p>So what exactly does “represent the same operation” mean? I turns out, this is a combination of the request code and the wrapped <em>Intent</em>. So now we need to know, how two <em>Intents</em> can be compared. To understand this, you need to look at the documentation of the <em>Intent.filterEquals()</em> method. Basically two Intents are considered equal if their action, data, type, class, and categories are the same. However, nothing is mentioned about their extras <em>Bundle</em>. My tests have shown that these extras are completely ignored when comparing <em>Intents</em>.</p>
<p>To sum up, you can be quite sure you refer to the same <em>PendingIntent</em> if you know its request code and the action, data, type, class, and categories of the wrapped <em>Intent</em> inside of it.</p>
<h3 id="pendingintent-cancellation"><em>PendingIntent</em> cancellation</h3>
<p>As I have mentioned above, the <em>PendingIntent</em> is a whole API on its own, completely independent of the <em>AlarmManager</em> or <em>NotificationManager</em>. So if there is global registry with all PendingIntents, it makes sense to have some way of clearing them, right? This functionality is provided by the <em>cancel()</em> method of a <em>PendingIntent</em>.</p>
<p>This method can be called only by the application, which originally created the <em>PendingIntent</em>. The result of this is that even if another application, such as the AlarmManager, already has a scheduled <em>PendintIntent</em>, nothing will happen when it tries to execute it, because it has been cancelled. This is a really powerful functionality to use and I believe that not that many people are actually aware of it.</p>
<h3 id="pendingintent-flags"><em>PendingIntent</em> flags</h3>
<p>You might have also noticed the <em>PendingIntent.FLAG_UPDATE_CURRENT</em> parameter used when calling the <em>getBroadcast()</em> method. The last parameter of the method is an integer containing a bitmask of <em>PendingIntent</em> flags. These flags are also really crucial to understand when you use the PendingIntent API. There are just a few flags you can use:</p>
<ul>
<li>FLAG_ONE_SHOT</li>
<li>FLAG_NO_CREATE</li>
<li>FLAG_CANCEL_CURRENT</li>
<li>FLAG_UPDATE_CURRENT</li>
<li>FLAG_IMMUTABLE</li>
</ul>
<p>I will not go into much detail about all different flags, since their documentation is really self-explanatory. I will focus only on one of them, since it really nicely gives an insight into what acutally happens when you call the <em>getBroadcast()</em>, <em>getService()</em> or <em>getActivity()</em> method of the <em>PendingIntent</em> class</p>
<h4 id="the-flag-flag_no_create">The flag <em>FLAG_NO_CREATE</em>.</h4>
<p>Its documentation states:</p>
<blockquote>
<p>Flag indicating that if the described PendingIntent does not already exist, then simply return null instead of creating it. For use with {@link #getActivity}, {@link #getBroadcast}, and {@link #getService}.</p>
</blockquote>
<p>So when you look at all other flags and this one, you realize that every time you call <em>getBroadcast()</em>, <em>getService()</em> or <em>getActivity()</em>, you put or update a specific <em>PendingIntent</em> into the global registry. <em>FLAG_NO_CREATE</em> is the only way to call any of these methods, without actually registering anything new. So the question is, when would you want to use this? This flag is really useful if you just want to check if a particular <em>PendingIntent</em> exists and is active. The following code snippet illustrates such sample usage.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">final</span> <span class="kt">int</span> <span class="n">requestCode</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
<span class="kd">final</span> <span class="nc">Intent</span> <span class="n">myIntent</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Intent</span><span class="o">(</span><span class="s">"MyIntentAction"</span><span class="o">);</span>
<span class="n">notificationIntent</span><span class="o">.</span><span class="na">addCategory</span><span class="o">(</span><span class="s">"android.intent.category.DEFAULT"</span><span class="o">);</span>
<span class="n">notificationIntent</span><span class="o">.</span><span class="na">putExtra</span><span class="o">(</span><span class="s">"message"</span><span class="o">,</span> <span class="s">"Hello world!"</span><span class="o">);</span>
<span class="nc">PendingIntent</span> <span class="n">broadcast</span> <span class="o">=</span> <span class="nc">PendingIntent</span><span class="o">.</span><span class="na">getBroadcast</span><span class="o">(</span><span class="n">context</span><span class="o">,</span> <span class="n">requestCode</span><span class="o">,</span>
<span class="n">myIntent</span><span class="o">,</span> <span class="nc">PendingIntent</span><span class="o">.</span><span class="na">FLAG_NO_CREATE</span><span class="o">);</span>
<span class="k">if</span> <span class="o">(</span><span class="n">broadcast</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="n">broadcast</span><span class="o">.</span><span class="na">cancel</span><span class="o">();</span>
<span class="o">}</span></code></pre></figure>
<h3 id="cancelling-alarms">Cancelling alarms</h3>
<p>Now that we understand how <em>PendingIntents</em> work, we can actually look at the <em>AlarmManager</em> API again. It provides a method for cancelling scheduled alarms, which expects a <em>PendingIntent</em> instance as a parameter. The documentation of this method is unfortunately not complete. It states the following:</p>
<blockquote>
<p>Remove any alarms with a matching {@link Intent}. Any alarm, of any type, whose Intent matches this one (as defined by {@link Intent#filterEquals}), will be canceled.</p>
</blockquote>
<p>One can assume from it that as long as the wrapped <em>Intent</em> matches, you have cancelled the alarm, right? Unfortunately this is a wrong assumption!</p>
<p>As we know from the <em>PendingIntent</em> matching described above, only if both the request code and the wrapped <em>Intent</em> match, then we can be sure that we are referring to the same <em>PendingIntent</em>. Thus we will cancel exactly the alarm related to the input <em>PendingIntent</em> parameter only if both its request code and wrapped <em>Intent</em> match. The following snippet illustrates this behavior:</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">Calendar</span> <span class="n">c</span> <span class="o">=</span> <span class="nc">Calendar</span><span class="o">.</span><span class="na">getInstance</span><span class="o">();</span>
<span class="n">c</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="nc">Calendar</span><span class="o">.</span><span class="na">SECOND</span><span class="o">,</span> <span class="mi">10</span><span class="o">);</span>
<span class="kd">final</span> <span class="kt">long</span> <span class="n">afterTenSeconds</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="na">getTimeInMillis</span><span class="o">();</span>
<span class="kd">final</span> <span class="kt">int</span> <span class="n">requestCode</span> <span class="o">=</span> <span class="mi">42</span><span class="o">;</span>
<span class="kd">final</span> <span class="kt">int</span> <span class="n">anotherRequestCode</span> <span class="o">=</span> <span class="mi">1337</span><span class="o">;</span>
<span class="kd">final</span> <span class="nc">AlarmManager</span> <span class="n">alarmManager</span> <span class="o">=</span> <span class="o">(</span><span class="nc">AlarmManager</span><span class="o">)</span>
<span class="n">context</span><span class="o">.</span><span class="na">getSystemService</span><span class="o">(</span><span class="nc">Context</span><span class="o">.</span><span class="na">ALARM_SERVICE</span><span class="o">);</span>
<span class="kd">final</span> <span class="nc">Intent</span> <span class="n">sameIntent</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Intent</span><span class="o">(</span><span class="s">"MyIntentAction"</span><span class="o">);</span>
<span class="n">notificationIntent</span><span class="o">.</span><span class="na">addCategory</span><span class="o">(</span><span class="s">"android.intent.category.DEFAULT"</span><span class="o">);</span>
<span class="n">notificationIntent</span><span class="o">.</span><span class="na">putExtra</span><span class="o">(</span><span class="s">"message"</span><span class="o">,</span> <span class="s">"Hello world!"</span><span class="o">);</span>
<span class="kd">final</span> <span class="nc">PendingIntent</span> <span class="n">broadcast</span> <span class="o">=</span> <span class="nc">PendingIntent</span><span class="o">.</span><span class="na">getBroadcast</span><span class="o">(</span><span class="n">context</span><span class="o">,</span>
<span class="n">requestCode</span><span class="o">,</span> <span class="n">sameIntent</span><span class="o">,</span> <span class="nc">PendingIntent</span><span class="o">.</span><span class="na">FLAG_UPDATE_CURRENT</span><span class="o">);</span>
<span class="n">alarmManager</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="nc">AlarmManager</span><span class="o">.</span><span class="na">RTC_WAKEUP</span><span class="o">,</span> <span class="n">afterTenSeconds</span><span class="o">,</span> <span class="n">broadcast</span><span class="o">);</span>
<span class="c1">// Check PendintIntent exists</span>
<span class="n">assertTrue</span><span class="o">(</span><span class="nc">PendingIntent</span><span class="o">.</span><span class="na">getBroadcast</span><span class="o">(</span><span class="n">context</span><span class="o">,</span> <span class="n">requestCode</span><span class="o">,</span>
<span class="n">sameIntent</span><span class="o">,</span> <span class="nc">PendingIntent</span><span class="o">.</span><span class="na">FLAG_NO_CREATE</span><span class="o">)</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">));</span>
<span class="n">alarmManager</span><span class="o">.</span><span class="na">cancel</span><span class="o">(</span><span class="nc">PendingIntent</span><span class="o">.</span><span class="na">getBroadcast</span><span class="o">(</span><span class="n">context</span><span class="o">,</span> <span class="n">anotherRequestCode</span><span class="o">,</span>
<span class="n">sameIntent</span><span class="o">,</span> <span class="nc">PendingIntent</span><span class="o">.</span><span class="na">FLAG_UPDATE_CURRENT</span><span class="o">));</span>
<span class="c1">// Check PendintIntent exists</span>
<span class="k">if</span> <span class="o">(</span><span class="nc">PendingIntent</span><span class="o">.</span><span class="na">getBroadcast</span><span class="o">(</span><span class="n">context</span><span class="o">,</span> <span class="n">requestCode</span><span class="o">,</span>
<span class="n">sameIntent</span><span class="o">,</span> <span class="nc">PendingIntent</span><span class="o">.</span><span class="na">FLAG_NO_CREATE</span><span class="o">)</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">))</span> <span class="o">{</span>
<span class="c1">// We just cancelled the same Intent, WTF?!</span>
<span class="o">}</span>
<span class="c1">// Try cancel with the same request code</span>
<span class="n">alarmManager</span><span class="o">.</span><span class="na">cancel</span><span class="o">(</span><span class="nc">PendingIntent</span><span class="o">.</span><span class="na">getBroadcast</span><span class="o">(</span><span class="n">context</span><span class="o">,</span> <span class="n">requestCode</span><span class="o">,</span>
<span class="n">sameIntent</span><span class="o">,</span> <span class="nc">PendingIntent</span><span class="o">.</span><span class="na">FLAG_UPDATE_CURRENT</span><span class="o">));</span>
<span class="c1">// Check PendintIntent exists</span>
<span class="k">if</span> <span class="o">(</span><span class="nc">PendingIntent</span><span class="o">.</span><span class="na">getBroadcast</span><span class="o">(</span><span class="n">context</span><span class="o">,</span> <span class="n">requestCode</span><span class="o">,</span>
<span class="n">sameIntent</span><span class="o">,</span> <span class="nc">PendingIntent</span><span class="o">.</span><span class="na">FLAG_NO_CREATE</span><span class="o">)</span> <span class="o">==</span> <span class="kc">null</span><span class="o">))</span> <span class="o">{</span>
<span class="c1">// OK, we have successfully cancelled the alarm</span>
<span class="o">}</span></code></pre></figure>
<p>Another important thing to note is that the <em>AlarmManager.cancel()</em> method does not cancel the <em>PendingIntent</em> itself. So even after calling this method, the initial <em>PendingIntent</em> is still active in the registry. However, this should be expected, since as already mentioned, the <em>PendingIntents</em> are not used only by the <em>AlarmManager</em>, but are independent API in the SDK.</p>
<h3 id="alarmmanager-and-pendingintent-lifecycle">AlarmManager and PendingIntent lifecycle</h3>
<p>A very important thing to keep in mind is that alarms and <em>PendingIntents</em> are not always kept by the framework. I have performed some tests to try to find out when exactly are alarms being disabled and when exactly are <em>PendingIntents</em> being cancelled, depending on external influence by the framework or the user. The following results have been consistent on three different devices running three different Android versions.</p>
<ul>
<li>Motorola Nexus 6 running Android 6.0</li>
<li>LG G3S running Android 4.4</li>
<li>Sony Xperia Z1 Compact running Android 5.1</li>
</ul>
<h3 id="pendingintent--alarmmanager-lifecycle-test-results">PendingIntent & AlarmManager lifecycle test results</h3>
<table>
<thead>
<tr>
<th>Performed action</th>
<th> </th>
<th>Cancel PendingIntent</th>
<th> </th>
<th>Clear alarm</th>
</tr>
</thead>
<tbody>
<tr>
<td>Force close from app settings</td>
<td> </td>
<td>no</td>
<td> </td>
<td>yes</td>
</tr>
<tr>
<td>Device restart</td>
<td> </td>
<td>yes</td>
<td> </td>
<td>yes</td>
</tr>
<tr>
<td>Runtime exception</td>
<td> </td>
<td>no</td>
<td> </td>
<td>no</td>
</tr>
<tr>
<td>ANR Force close</td>
<td> </td>
<td>no</td>
<td> </td>
<td>no</td>
</tr>
<tr>
<td>Swipe away from recent apps</td>
<td> </td>
<td>no</td>
<td> </td>
<td>no</td>
</tr>
<tr>
<td>Clear app data from settings</td>
<td> </td>
<td>yes/no</td>
<td> </td>
<td>yes</td>
</tr>
</tbody>
</table>
<p>As you can see, Alarms are not 100% reliable and there are a lot of situations, where you need to take care and reschedule them. The only situation you cannot do anything about it, is when the user Force closes your application from the app settings screen. If this occurs, the Android framework will NOT invoke automatically any <em>Service</em> or <em>BroadcastReceiver</em> of your application unless the user explicitly starts your application again. This might look a little harsh for us developers, but makes perfect sense from a user point of view. Imagine some <em>Service</em>, which crashes immediately every time it gets started. If it is a sticky service, the framework will try to restart it over and over again. Constantly popping an application not responding dialog in front of the user will prevent normal device usage, which is really bad. So this fail-safe functionality is actually a good thing for the whole system and for other apps.</p>
<h3 id="time-to-play---try-out-the-different-options-in-the-companion-app">Time to play - try out the different options in the companion app</h3>
<p>I have included a demo in the blog’s companion app where you can test some <em>PendingIntents</em> and alarm scheduling. You can find the source code on <a href="https://github.com/luboganev/testground"><strong>GitHub</strong></a></p>Lyubomir Ganevluboganev@gmail.comThe Android SDK offers an API for scheduling one time or recurring events called alarms. This is for example how your alarm clock applications work, or how a reminder for a calendar event is triggered. It’s pretty simple to use but is has some specific behavior, which you need to take in account. In this post I will describe some of the problems I have encountered when not completely understanding how this API works.Android clean architecture part 52016-05-15T00:00:00+00:002016-05-15T00:00:00+00:00https://luboganev.dev/post/clean-architecture-pt5<p>Some time has passed since the last clean architecture post. During this time the described architecture implementation has shown some of its drawbacks. In this post I will shortly describe the problems with the current implementation and propose some solutions to these problems. As usual you can find the updated version of the demo application Carbrands in its repository at GitHub - <a href="https://github.com/luboganev/Carbrands">Repository Link</a>.</p>
<h3 id="so-what-are-the-problems">So what are the problems?</h3>
<p>All the problems with the proposed implementation actually originate from a single flawed architectural decision - storing scoped object graphs as field in their corresponding <em>Activity</em>. As a result, each Dagger scoped object graph gets destroyed and recreated together with the <em>Activity</em> each time a UI configuration change occurs. This leads to the folowing drawbacks of the architecture:</p>
<ul>
<li>Potentially a lot of object instantiations due to creating a new scoped graph and all its objects on each configuration change</li>
<li><em>Presenter</em> and <em>Interactor</em> implementations have to rely on the framework’s classes like <em>Bundle</em> and its lifecycle event callbacks in order to save and restore their state.</li>
<li>Having a <em>Presenter</em> and <em>Interactor</em> tightly coupled to the UI lifecycle makes them very hard to test due to tight dependencies to framework classes</li>
<li>Long-running operations which need to be atomic cannot be implemented at all inside these modules due to their instability</li>
</ul>
<p>The following paragraphs provide some more detail for each of the problems above.</p>
<h4 id="too-many-object-allocations">Too many object allocations</h4>
<p>Well, that’s probably obvious. Recreating <em>Presenter</em> and <em>Interactor</em> instances and all their dependencies on each configuration change is not cheap. Allocating them takes some time and might have a negative effect on the performance of the app. In addition, the extra memory allocations mean more work for the garbage collector, which also leads to sloppy UI performance.</p>
<h4 id="presenters-interactors-and-bundles-oh-my">Presenters, Interactors and Bundles. Oh my!</h4>
<p>It might not look like a bad idea at first, but it proved to be really painful in the long term. You see, having to save and restore the state of <em>Presenter</em> and <em>Interactor</em> implementations in <em>Bundle</em> increases their complexity with boilerplate code. The initial idea of the clean architecture is to be, well, clean. So pushing bundles and lifecycle methods as deep as an <em>Interactor</em> is contributing to neither cleaner nor simpler code.</p>
<p>In addition, it can also prove to be error-prone. Since <em>Bundle</em> works with key-value pairs, what happens if two components want to use the same key for different things to store? For example this might lead to an <em>Interactor</em> overwriting value related to the state of a Presenter or some value related to the UI, thus producing errors or even crashes due to wrong types. In order to prevent this, one has to come up with a convention that guarantees unique <em>Bundle</em> keys. This further increases the complexity and introduces even more boilerplate code.</p>
<h4 id="testing-framework-classes-and-lifecycle">Testing, framework classes and lifecycle</h4>
<p>Saving and restoring state of <em>Presenter</em> and <em>Interactor</em> through <em>Bundle</em> and lifecycle callback methods makes testing and especially Unit testing very hard. Having references to framework classes instead of only pure Java inside these components means that you have to use libraries like <em>Roboelectric</em> in order to be able to run Unit tests without an emulator. Don’t get me wrong, Roboelectric is great, but in this case it solves a problem, which would not exist at all in a better architecture.</p>
<p>But let’s say the only framework class we have is <em>Bundle</em>. We can mock it easily with something like <em>Mockito</em>, right? The class itself yes, but which values should it return? Which are relevant to the tested component? It means that you have to go through the code of the whole component and check what keys and values it expects to get from the <em>Bundle</em>. In other words, such components’ dependencies are not clearly visible from their public API. This makes writing good unit tests hard, because the test has to know too much.</p>
<h4 id="long-running-atomic-operations">Long-running atomic operations</h4>
<p>Let’s say that an <em>Interactor</em> needs to perform a network request, which does something important like performing a payment. If a configuration change happens while the request is running, we end up with a brand new <em>Interactor</em> which only knows that a request was sent. But it has no idea if it has reached the server, if it has failed or succeeded. It will also never get back the result of this operation coming from the server.</p>
<p>This problem was already discussed into the previous post, which suggests that such <em>Interactor</em> should live in the Application object graph and not in any of the scoped object graphs. This, however, means that once allocated this Interactor will stay in memory as long as the process lives, which is not that efficient. In addition, scoped graph Interactors have to somehow communicate with this special Interactor, which introduces yet more complexity.</p>
<h3 id="how-can-we-do-better">How can we do better?</h3>
<p>Before we start looking in some aspects of the improved implementation, here’s a link to the actual repository version this post refers to: <a href="https://github.com/luboganev/Carbrands/releases/tag/v2.0">Repository Link for v2.0</a>.</p>
<p>In order to fix the problems described above we need to tackle the main flaw of the current architecture, namely the fact that the instances of the scoped object graphs are stored inside the <em>Activity</em>. So how can we eliminate this?</p>
<h4 id="the-objectgraphholder">The ObjectGraphHolder</h4>
<p>It’s actually pretty simple - we just need to move them to a component which lives longer than the UI. This component is the <em>ObjectGraphHolder</em> - a singleton which has a map containing all scoped object graphs as well as the root object graph. It provides a couple of helpful methods which allow for putting, getting and removing <em>ObjectGraph</em> instances from it. It also contains a helper method for creating a scoped object graph by adding modules to an existing one.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">private</span> <span class="nc">Map</span><span class="o"><</span><span class="nc">Long</span><span class="o">,</span> <span class="nc">ObjectGraph</span><span class="o">></span> <span class="n">objectGraphMap</span><span class="o">;</span>
<span class="kd">private</span> <span class="kt">long</span> <span class="n">objectGraphIdAutoIncrement</span><span class="o">;</span>
<span class="kd">public</span> <span class="nd">@Nullable</span> <span class="nc">ObjectGraph</span> <span class="nf">getObjectGraph</span><span class="o">(</span><span class="kt">long</span> <span class="n">objectGraphId</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">objectGraphMap</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">objectGraphId</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">long</span> <span class="nf">putObjectGraph</span><span class="o">(</span><span class="nd">@NonNull</span> <span class="nc">ObjectGraph</span> <span class="n">objectGraph</span><span class="o">)</span> <span class="o">{</span>
<span class="n">objectGraphMap</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="n">objectGraphIdAutoIncrement</span><span class="o">,</span> <span class="n">objectGraph</span><span class="o">);</span>
<span class="k">return</span> <span class="n">objectGraphIdAutoIncrement</span><span class="o">++;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">removeObjectGraph</span><span class="o">(</span><span class="kt">long</span> <span class="n">objectGraphId</span><span class="o">)</span> <span class="o">{</span>
<span class="n">objectGraphMap</span><span class="o">.</span><span class="na">remove</span><span class="o">(</span><span class="n">objectGraphId</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nd">@NonNull</span> <span class="nc">ObjectGraph</span> <span class="nf">createScopedGraph</span><span class="o">(</span><span class="nd">@NonNull</span> <span class="nc">ObjectGraph</span> <span class="n">parentObjectGraph</span><span class="o">,</span>
<span class="nd">@Nullable</span> <span class="nc">Object</span><span class="o">...</span> <span class="n">modules</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">modules</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&&</span> <span class="n">modules</span><span class="o">.</span><span class="na">length</span> <span class="o">></span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">parentObjectGraph</span><span class="o">.</span><span class="na">plus</span><span class="o">(</span><span class="n">modules</span><span class="o">);</span>
<span class="o">}</span>
<span class="k">return</span> <span class="n">parentObjectGraph</span><span class="o">;</span>
<span class="o">}</span></code></pre></figure>
<p>This implementation maps instances of the <em>ObjectGraph</em> to unique auto-incrementing ids. You might wonder, why not simply use the the <em>Activity.class</em> as a key? You definitely can, but this turns out to be a bad idea, when multiple instances of the same Activity can appear in one or multiple tasks.</p>
<p>Please notice the <em>removeObjectGraph(id)</em> method, which is used to remove object graphs related to an <em>Activity</em> that is finished. In the previous implementation the scoped <em>ObjectGraph</em> was garbage collected each time an <em>Activity</em> was destroyed, but now we have to take care of this ourselves and call this remove method when an <em>Activity</em> is finishing and will not come back.</p>
<h4 id="the-new-basedaggeractivity">The new BaseDaggerActivity</h4>
<p>The second important component we need to look at is the <em>BaseDaggerActivity</em>. It does not contain instance of its scoped ObjectGraph anymore, but calls the methods of the <em>ObjectGraphHolder</em>. The most important functionality can be found in the snippet below</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">private</span> <span class="kt">long</span> <span class="n">objectGraphId</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="o">;</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="nc">String</span> <span class="no">STATE_EXTRA_OBJECT_GRAPH_ID</span> <span class="o">=</span> <span class="s">"objectgraph_id"</span><span class="o">;</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onCreate</span><span class="o">(</span><span class="nd">@Nullable</span> <span class="nc">Bundle</span> <span class="n">savedInstanceState</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onCreate</span><span class="o">(</span><span class="n">savedInstanceState</span><span class="o">);</span>
<span class="c1">// Check for stored id and restore it</span>
<span class="k">if</span> <span class="o">(</span><span class="n">savedInstanceState</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="n">objectGraphId</span> <span class="o">=</span> <span class="n">savedInstanceState</span><span class="o">.</span><span class="na">getLong</span><span class="o">(</span><span class="no">STATE_EXTRA_OBJECT_GRAPH_ID</span><span class="o">,</span> <span class="o">-</span><span class="mi">1</span><span class="o">);</span>
<span class="o">}</span>
<span class="c1">// Check if an object graph already exists for this activity</span>
<span class="nc">ObjectGraph</span> <span class="n">activityObjectGraph</span> <span class="o">=</span> <span class="nc">ObjectGraphsHolder</span><span class="o">.</span><span class="na">getInstance</span><span class="o">().</span><span class="na">getObjectGraph</span><span class="o">(</span><span class="n">objectGraphId</span><span class="o">);</span>
<span class="k">if</span> <span class="o">(</span><span class="n">activityObjectGraph</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">// Create a new object graph, which adds to the root application object graph</span>
<span class="nc">ObjectGraph</span> <span class="n">rootObjectGraph</span> <span class="o">=</span> <span class="nc">ObjectGraphsHolder</span><span class="o">.</span><span class="na">getInstance</span><span class="o">().</span><span class="na">getApplicationObjectGraph</span><span class="o">();</span>
<span class="n">activityObjectGraph</span> <span class="o">=</span> <span class="nc">ObjectGraphsHolder</span><span class="o">.</span><span class="na">createScopedGraph</span><span class="o">(</span><span class="n">rootObjectGraph</span><span class="o">,</span> <span class="n">getActivityModules</span><span class="o">());</span>
<span class="n">objectGraphId</span> <span class="o">=</span> <span class="nc">ObjectGraphsHolder</span><span class="o">.</span><span class="na">getInstance</span><span class="o">().</span><span class="na">putObjectGraph</span><span class="o">(</span><span class="n">activityObjectGraph</span><span class="o">);</span>
<span class="o">}</span>
<span class="c1">// Inject dependencies</span>
<span class="n">activityObjectGraph</span><span class="o">.</span><span class="na">inject</span><span class="o">(</span><span class="k">this</span><span class="o">);</span>
<span class="o">....</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onSaveInstanceState</span><span class="o">(</span><span class="nc">Bundle</span> <span class="n">outState</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onSaveInstanceState</span><span class="o">(</span><span class="n">outState</span><span class="o">);</span>
<span class="c1">// Store the current object graph id to survive configuration change</span>
<span class="n">outState</span><span class="o">.</span><span class="na">putLong</span><span class="o">(</span><span class="no">STATE_EXTRA_OBJECT_GRAPH_ID</span><span class="o">,</span> <span class="n">objectGraphId</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onDestroy</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onDestroy</span><span class="o">();</span>
<span class="c1">// Any other call to this method is due to configuration change or low memory.</span>
<span class="c1">// We want to release the stored object graph only when the activity is truly</span>
<span class="c1">// finishing.</span>
<span class="k">if</span> <span class="o">(</span><span class="n">isFinishing</span><span class="o">())</span> <span class="o">{</span>
<span class="n">onDestroyObjectGraph</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onDestroyObjectGraph</span><span class="o">()</span> <span class="o">{</span>
<span class="c1">// Remove the current object graph from the holder</span>
<span class="nc">ObjectGraphsHolder</span><span class="o">.</span><span class="na">getInstance</span><span class="o">().</span><span class="na">removeObjectGraph</span><span class="o">(</span><span class="n">objectGraphId</span><span class="o">);</span>
<span class="o">}</span></code></pre></figure>
<p>Each time the <em>OnCreate()</em> method is invoked, we check if the <em>ObjectGraphHolder</em> already contains an <em>ObjectGraph</em> with the particular id related to this <em>Activity</em>. If it doesn’t, we create a new scoped graph and put it in the <em>ObjectGraphHolder</em>, which gives us in return a new id for it.</p>
<p>The id, which the <em>ObjectGraphHolder</em> gives us when we put a new <em>ObjectGraph</em> in it, is our only way of accessing it. Therefore, we need to save it through configuration changes. When a configuration change occurs, we first try to restore it and after that we are be able to request the stored <em>ObjectGraph</em> again in the <em>OnCreate()</em> method.</p>
<p>The final piece of the <em>ObjectGraph</em> handling is making sure to remove it from the <em>ObjectGraphHolder</em> when its related <em>Activity</em> finishes. This is performed in the <em>onDestroyObjectGraph()</em> method which is called from the <em>onDestroy()</em> method only if the <em>Activity</em> is finishing.</p>
<h4 id="the-new-navigator">The new Navigator</h4>
<p>The main purpose of the <em>Navigator</em> class is to provide an abstraction around the navigation methods of an <em>Activity</em> such as <em>startActivity()</em> as well as the building of <em>Intent</em> objects. In order to do that, it needs to have an reference to the currently visible <em>Activity</em>. This becomes problematic when the instance of the <em>Navigator</em> is retained through configuration changes, because the Activity it contains gets destroyed. Therefore its implementation has been updated a bit and now it gets the latest <em>Activity</em> through a setter.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">private</span> <span class="nc">Activity</span> <span class="n">mActivity</span><span class="o">;</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setActivity</span><span class="o">(</span><span class="nc">Activity</span> <span class="n">activity</span><span class="o">)</span> <span class="o">{</span>
<span class="n">mActivity</span> <span class="o">=</span> <span class="n">activity</span><span class="o">;</span>
<span class="o">}</span></code></pre></figure>
<p>This setter is being called in the new <em>BaseDaggerActivity</em>, which makes sure it keeps the instance inside the Navigator always fresh. This way, we also prevent leaking a destroyed <em>Activity</em>, because the reference inside the <em>Navigator</em> points always to the newest instance of the currently visible <em>Activity</em>. The following code snippet of <em>BaseDaggerActivity</em> shows how this is performed.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Inject</span> <span class="nc">Navigator</span> <span class="n">navigator</span><span class="o">;</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onCreate</span><span class="o">(</span><span class="nd">@Nullable</span> <span class="nc">Bundle</span> <span class="n">savedInstanceState</span><span class="o">)</span> <span class="o">{</span>
<span class="o">....</span>
<span class="c1">// Make sure to update the navigator's current activity</span>
<span class="n">navigator</span><span class="o">.</span><span class="na">setActivity</span><span class="o">(</span><span class="k">this</span><span class="o">);</span>
<span class="n">onInjected</span><span class="o">(</span><span class="n">savedInstanceState</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onStart</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onStart</span><span class="o">();</span>
<span class="c1">// Make sure to update the navigator's current activity</span>
<span class="n">navigator</span><span class="o">.</span><span class="na">setActivity</span><span class="o">(</span><span class="k">this</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onResume</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onResume</span><span class="o">();</span>
<span class="c1">// Make sure to update the navigator's current activity</span>
<span class="n">navigator</span><span class="o">.</span><span class="na">setActivity</span><span class="o">(</span><span class="k">this</span><span class="o">);</span>
<span class="o">}</span></code></pre></figure>
<h4 id="the-new-presenter-and-interactor-lifecycle">The new Presenter and Interactor lifecycle</h4>
<p>Having the whole scoped object graph survive configuration changes means that we have basically no lifecycle at all. <em>Presenter</em> and <em>Interactor</em> instances simply get instantiated through their constructor and then are garbage collected when the scoped <em>ObjectGraph</em> is removed from the <em>ObjectGraphHolder</em>.</p>
<p>However, references to the Views cannot be injected through the constructor of a <em>Presenter</em> anymore. This is due to the fact that when a cofiguration change occurs, we have a new <em>View</em> instance and we have to update its reference to it inside a <em>Presenter</em>. The following snippets show how this is performed in the <em>CarBrandsActivity</em> and <em>CarBrandsPresenter</em>.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">CarBrandsPresenter</span> <span class="kd">implements</span> <span class="nc">CarBrandsPresenterInput</span><span class="o">,</span> <span class="nc">CarBrandsInteractorOutput</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nc">CarBrandsPresenterOutput</span> <span class="n">mView</span><span class="o">;</span>
<span class="o">....</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setView</span><span class="o">(</span><span class="nd">@NonNull</span> <span class="nc">CarBrandsPresenterOutput</span> <span class="n">view</span><span class="o">)</span> <span class="o">{</span>
<span class="n">mView</span> <span class="o">=</span> <span class="n">view</span><span class="o">;</span>
<span class="o">}</span></code></pre></figure>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">CarBrandsListActivity</span> <span class="kd">extends</span> <span class="nc">BaseDaggerActivity</span> <span class="kd">implements</span> <span class="nc">CarBrandsPresenterOutput</span>
<span class="o">....</span>
<span class="o">{</span>
<span class="nd">@Inject</span> <span class="nc">CarBrandsPresenterInput</span> <span class="n">presenter</span><span class="o">;</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onInjected</span><span class="o">(</span><span class="nc">Bundle</span> <span class="n">savedInstanceState</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onInjected</span><span class="o">(</span><span class="n">savedInstanceState</span><span class="o">);</span>
<span class="n">presenter</span><span class="o">.</span><span class="na">setView</span><span class="o">(</span><span class="k">this</span><span class="o">);</span>
<span class="o">....</span>
<span class="o">}</span></code></pre></figure>
<p>Finally, sometimes we want to get notified when the whole VIPER module is no longer needed, so that we can for example abort any long-running operations inside an <em>Interactor</em>. We can then override the <em>onDestroyObjectGraph()</em> method in our <em>Activity</em> implementation and notify the <em>Presenter</em> and <em>Interactor</em> accordingly. Doing this allows these components to do any required cleaning of resources and should be always performed, so that no memory leaks can occur.</p>
<h3 id="summary">Summary</h3>
<p>The new architecture implementation described in this post have evolved over the last several months. The needed changes have been performed in a couple of steps and have proven to be significant improvement over the existing implementation in terms of code simplicity, testing, flexibility and separation of concerns. It is however far from perfect and can always be improved further.</p>Lyubomir Ganevluboganev@gmail.comSome time has passed since the last clean architecture post. During this time the described architecture implementation has shown some of its drawbacks. In this post I will shortly describe the problems with the current implementation and propose some solutions to these problems. As usual you can find the updated version of the demo application Carbrands in its repository at GitHub - Repository Link.Android clean architecture part 42015-07-29T00:00:00+00:002015-07-29T00:00:00+00:00https://luboganev.dev/post/clean-architecture-pt4<p>Although one could write a detailed description of the concepts and ideas behind an architecture, I believe that the easiest way to understand it is to see an example. Therefore, I have built a simple demo application, which is built with the VIPER architecture in mind. The following sections describe the application and some specifics related to Android.</p>
<h3 id="where-is-the-code">Where is the code?</h3>
<p>The demo app is called Car brands and is an open-source project hosted at GitHub. You can find the repository here: <a href="https://github.com/luboganev/Carbrands">Repository Link</a></p>
<p>(Update 11.05.2016) If you are cloning the repository, please be advised that this particular post refers to an older revision of the code and not the HEAD from the master branch. It is tagged with the tag v1.1. You can find it here: <a href="https://github.com/luboganev/Carbrands/tree/v1.1">Repository Link TAG v1.1</a></p>
<p>If you do not feel like building the app yourself or cloning the repository, you can alternatively download the source and a ready built debug apk file from the release section of the project at GitHub. Please find it here: <a href="https://github.com/luboganev/Carbrands/releases/tag/v1.1">Release Link</a></p>
<h3 id="overview-of-the-app-architecture-with-dagger">Overview of the app architecture with Dagger</h3>
<p>The application’s UI has an extremely simple List/Detail screens structure. The following screenshot shows how the application packages look like in Android Studio.</p>
<p><img src="https://luboganev.dev/images/2015-07-29-clean-architecture-pt4/carbrands_project_structure.png" alt="Demo project structure" /></p>
<p>It has two simple Activities, which represent the two screens of the application. Thus, there are two VIPER modules - <em>carbrands</em>, which contains components related the list, and <em>carbrandDetail</em>, which contains components related to the detail. All instantiating of VIPER components such as <em>Interactors</em> and <em>Presenters</em> and their dependencies is done inside the Dagger’s Module classes. There are in total four Dagger Modules in the project - <em>AppModule</em>, <em>NavigatorModule</em>, <em>CarBrandsListModule</em> and <em>CarBrandDetailModule</em>. Those four modules are used for building up the Dagger’s object graph and all scoped object graphs, but more on this in the following paragraphs. Let’s first start with a diagram, showing the Modules and the different objects graph they form.</p>
<p><img src="https://luboganev.dev/images/2015-07-29-clean-architecture-pt4/dagger_modules_structure.png" alt="Dagger modules structure" /></p>
<p>The root Dagger Object Graph contains the main AppModule. It provides instances of the mock implementations of a data store and location manager to all classes which might need them. The NavigatorModule provides instance of the Navigator class, which contains logic for navigating from the ListActivity to the DetailActivity. The CarBrandsListModule provides instances of the Presenter and Interactor related to the list VIPER module. It and the Navigator module are being added to the Application’s object graph in order to create a scoped graph related only to the list screen of the app. Similarly, the CarBrandDetailModule provides instances of the Presenter and Interactor related to the detail VIPER module, and is added to the Application object graph together with the NavigatorModule in order to create a scoped object graph related only to the detail screen of the app.</p>
<p>So why using scoped graphs at all and make our life harder? Since the UI of the application has a shorter lifecycle in comparison with the application process, we do not need to persist in memory all possible dependencies related to the list and detail VIPER modules all the time. Therefore, we use the <em>scoped graph</em> Dagger functionality and we build an extended version of the Object Graph, containing the main Application Object Graph and the Modules related only to the Activity being shown. After the Activity goes away, its scoped object graph with all its instances is garbage collected, without affecting the instances of dependencies living in the Application object graph.</p>
<p>In the current implementation almost all dependency injection is performed through constructor injection. This all happens in the provider methods of the Dagger Module classes, when instantiating the concrete implementations of the Interactors and Presenters. The only object we cannot create are the Android Activities. Therefore, we need to use field injection there, after these objects have been instantiated by the Android framework. In order to encapsulate the functionality related to creating scoped graphs and field-injecting an instantiated Activity, the demo app includes a BaseDaggerActivity abstract class, which performs these commons tasks. There is also a custom implementation of the Application class, which contains the logic for creating the initial root Application Dagger Object Graph. The following code snippets depict what are possibly the two most important classes in the demo application.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">BaseDaggerActivity</span> <span class="kd">extends</span> <span class="nc">AppCompatActivity</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nd">@Nullable</span> <span class="nc">ObjectGraph</span> <span class="n">mActivityGraph</span><span class="o">;</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onCreate</span><span class="o">(</span><span class="nd">@Nullable</span> <span class="nc">Bundle</span> <span class="n">savedInstanceState</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onCreate</span><span class="o">(</span><span class="n">savedInstanceState</span><span class="o">);</span>
<span class="nc">List</span><span class="o"><</span><span class="nc">Object</span><span class="o">></span> <span class="n">modules</span> <span class="o">=</span> <span class="n">getActivityModules</span><span class="o">();</span>
<span class="k">if</span><span class="o">(</span><span class="n">modules</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&&</span> <span class="n">modules</span><span class="o">.</span><span class="na">size</span><span class="o">()</span> <span class="o">></span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
<span class="n">mActivityGraph</span> <span class="o">=</span> <span class="nc">CarBrandsApplication</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="k">this</span><span class="o">).</span><span class="na">createScopedGraph</span><span class="o">(</span><span class="n">modules</span><span class="o">.</span><span class="na">toArray</span><span class="o">());</span>
<span class="o">}</span>
<span class="k">if</span><span class="o">(</span><span class="n">shouldInjectSelf</span><span class="o">())</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">mActivityGraph</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="n">mActivityGraph</span><span class="o">.</span><span class="na">inject</span><span class="o">(</span><span class="k">this</span><span class="o">);</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
<span class="nc">CarBrandsApplication</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="k">this</span><span class="o">).</span><span class="na">inject</span><span class="o">(</span><span class="k">this</span><span class="o">);</span>
<span class="o">}</span>
<span class="n">onInjected</span><span class="o">(</span><span class="n">savedInstanceState</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onDestroy</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onDestroy</span><span class="o">();</span>
<span class="n">mActivityGraph</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
<span class="o">}</span>
<span class="cm">/**
* This method should return a list of modules to be added as a scoped object graph
* to the Application's object graph. If it does not provide any modules,
* the current Activity does not generate its own scoped object graph and uses the
* Application's object graph instead.
*/</span>
<span class="kd">protected</span> <span class="nd">@Nullable</span> <span class="nc">List</span><span class="o"><</span><span class="nc">Object</span><span class="o">></span> <span class="nf">getActivityModules</span><span class="o">()</span> <span class="o">{</span> <span class="k">return</span> <span class="kc">null</span><span class="o">;</span> <span class="o">}</span>
<span class="cm">/**
* This method returns whether the current Activity itself
* should be injected with dependencies
*/</span>
<span class="kd">protected</span> <span class="kt">boolean</span> <span class="nf">shouldInjectSelf</span><span class="o">()</span> <span class="o">{</span> <span class="k">return</span> <span class="kc">false</span><span class="o">;</span> <span class="o">}</span>
<span class="cm">/**
* A helper method used to inject objects. It uses the Activity's the scoped object
* graph if one exists. In case the Activity does not have its own scoped object graph,
* the Application's object graph is used for the injection.
*
* @param object
* The object to be injected with dependencies
*/</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">inject</span><span class="o">(</span><span class="nd">@NonNull</span> <span class="nc">Object</span> <span class="n">object</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span><span class="o">(</span><span class="n">mActivityGraph</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">CarBrandsApplication</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="k">this</span><span class="o">).</span><span class="na">inject</span><span class="o">(</span><span class="n">object</span><span class="o">);</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
<span class="n">mActivityGraph</span><span class="o">.</span><span class="na">inject</span><span class="o">(</span><span class="n">object</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="cm">/**
* This method gets called once the Activity has been injected.
* It is a hook you can use if you want to do something as early as
* in the onCreate() but still need the injected dependencies
*
* @param savedInstanceState
* The reference to the savedInstanceState from the onCreate method.
*/</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onInjected</span><span class="o">(</span><span class="nd">@Nullable</span> <span class="nc">Bundle</span> <span class="n">savedInstanceState</span><span class="o">)</span> <span class="o">{}</span>
<span class="o">}</span></code></pre></figure>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">CarBrandsApplication</span> <span class="kd">extends</span> <span class="nc">Application</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nc">ObjectGraph</span> <span class="n">objectGraph</span><span class="o">;</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">onCreate</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onCreate</span><span class="o">();</span>
<span class="n">objectGraph</span> <span class="o">=</span> <span class="nc">ObjectGraph</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="k">new</span> <span class="nc">AppModule</span><span class="o">(</span><span class="k">this</span><span class="o">));</span>
<span class="o">}</span>
<span class="cm">/**
* A helper method, which creates a scoped Dagger object graph, by adding the input
* modules to the root Application object graph.
*
* @param modules
* The additional modules which should be included in the scoped object graph.
* @return
* An instance of the created scoped object graph
*/</span>
<span class="kd">public</span> <span class="nc">ObjectGraph</span> <span class="nf">createScopedGraph</span><span class="o">(</span><span class="nc">Object</span><span class="o">...</span> <span class="n">modules</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">objectGraph</span><span class="o">.</span><span class="na">plus</span><span class="o">(</span><span class="n">modules</span><span class="o">);</span>
<span class="o">}</span>
<span class="cm">/**
* A helper method which injects objects with their dependencies from the
* the Application's object graph
*
* @param object
* The object to be injected
*/</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">inject</span><span class="o">(</span><span class="nd">@NonNull</span> <span class="nc">Object</span> <span class="n">object</span><span class="o">)</span> <span class="o">{</span>
<span class="n">objectGraph</span><span class="o">.</span><span class="na">inject</span><span class="o">(</span><span class="n">object</span><span class="o">);</span>
<span class="o">}</span>
<span class="cm">/**
* A helper method which gets a reference to the Application from an input Activity instance
*/</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="nc">CarBrandsApplication</span> <span class="nf">get</span><span class="o">(</span><span class="nd">@NonNull</span> <span class="nc">Activity</span> <span class="n">activity</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="o">(</span><span class="nc">CarBrandsApplication</span><span class="o">)</span> <span class="n">activity</span><span class="o">.</span><span class="na">getApplication</span><span class="o">();</span>
<span class="o">}</span></code></pre></figure>
<p>So when the application is launched, the root object graph is created from the <em>AppModule</em>. Shortly after that, the CarBrandsListActivity is being launched. Since it extends the BaseDaggerActivity, it inherits the functionality implemented inside the <em>onCreate()</em> method. There are two important tasks, which the overridden implementation of this method performs:</p>
<ul>
<li>Create an Activity scoped object graph - this depends on the return value of the method <em>getActivityModules()</em>. If the Activity has any Dagger Modules which it wants to extend the ApplicationObject graph with, it can provide them by overriding this method. In case there are no modules to be added, then no scoped graph is created.</li>
<li>Inject the Activity itself with dependencies - Whether the Activity should attempt to inject itself or not depends on the return value of the method <em>shouldInjectSelf()</em>. While injecting itself, the Activity will try to use the local scoped object graph first. However, if it is not available, it will inject from the Application’s object graph instead.</li>
</ul>
<p>For even more documentation and comments inside these two classes, please refer to the code of the demo app.</p>
<h3 id="building-up-a-viper-module-and-its-components">Building up a VIPER module and its components</h3>
<p>The very basic implementation of a VIPER module in this context consists of a View, a Presenter and an Interactor. To keep the implementation flexible and mockable, dependencies are defined as Java interfaces.</p>
<p><img src="https://luboganev.dev/images/2015-07-29-clean-architecture-pt4/viper_module.png" alt="VIPER Module components" /></p>
<p>For example, the <em>CarBrandsListActivity</em> needs a reference to its presenter, i.e. the <em>CarBrandsPresenter</em>. But instead of reference to the concrete implementation, the CarBrandsListActivity gets injected a <em>CarBrandsPresenterInput</em>. Similarly, the presenter does not get injected a reference to the Activity, but instead an interface called <em>CarBrandsPresenterOutput</em>, implemented by the Activity. Furthermore, the communication between the presenter and the interactor goes through the methods defined inside the <em>CarBrandsInteractorInput</em> and <em>CarBrandsInteractorOutput</em>, while the concrete interactor implementation is defined in the <em>CarBrandsInteractor</em> class.</p>
<p>When a new screen is shown, i.e. an Activity is created, it requires a Presenter. What hapens is that Dagger will find a method, which provides the implementation of the Presenter in the particular Dagger Module, and inject it. In order to create the Presenter, however, an instance of the Interactor is needed as well, since the Presenter has references to both Interactor and View (the Activity). But to create an Interactor, we need to have an instance of the Presenter, since the Interactor has a reference to it. Having such a cyclic relation between two dependencies cannot be implemented with Dagger and injection. After all, that is what Dagger stands for - Directed Acyclic Graph, i.e. (DAG)ger. It does not support cyclic dependencies. So this is a problem.</p>
<p>There is an easy solution - we just need to make one of the injections through a setter method instead of using constructor injection. So we do not provide an instance of the presenter to the interactor through its constructor, but instead through a setter method after it has been instantiated. This is an exception to the rule, we have established, for using constructor injection for objects, which we can instantiate, but a needed one when using Dagger dependency injection and VIPER architecture together. A similar case might have been the relation between Presenter and View, but it is not the case, because we perform field injection there. In addition, the presenters get their View dependency directly from the Dagger Module itself, since it is being instantiated by the Activity in its <em>getActivityModules()</em>, thus this dependency is also not automatically provided by Dagger, but is provided, so to say, <em>by design</em>.</p>
<h3 id="saving-state">Saving state</h3>
<p>The proposed architecture heavily depends on Activities, since they are responsible for creating, keeping and destroying the scoped object graphs and all dependencies living there. So what happens when a configuration change occurs? Naturally, the activity gets destroyed together with all the VIPER components from the module related to this Activity. So one still has to make sure he saves any needed state. Since every component might need to save and restore some kind of state, the provided implementation includes a common Java interface for that purpose.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="cm">/**
* This interface defines some important Activity lifecycle callbacks, which most probably
* every Presenter would care knowing about
*
* Created by Lyubomir Ganev (ganevlyu) on 27.04.2015
*/</span>
<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">ViewLifecycleCallbacks</span> <span class="o">{</span>
<span class="cm">/**
* Called when an activity's onResume method is invoked
*/</span>
<span class="kt">void</span> <span class="nf">onViewShow</span><span class="o">();</span>
<span class="cm">/**
* Called when an activity's onSaveInstanceState method is invoked
*
* @param savedInstanceState
* The bundle to use for saving state
*/</span>
<span class="kt">void</span> <span class="nf">onViewSaveState</span><span class="o">(</span><span class="nc">Bundle</span> <span class="n">savedInstanceState</span><span class="o">);</span>
<span class="cm">/**
* Called when an activity's has just been created.
*
* @param launchingIntentExtras
* This bundle contains the extras from the Activity's launching Intent. It may be null.
* @param savedInstanceState
* This bundle contains the extras of the saved instance state. It may be null;
*/</span>
<span class="kt">void</span> <span class="nf">onViewCreate</span><span class="o">(</span><span class="nd">@Nullable</span> <span class="nc">Bundle</span> <span class="n">launchingIntentExtras</span><span class="o">,</span> <span class="nd">@Nullable</span> <span class="nc">Bundle</span> <span class="n">savedInstanceState</span><span class="o">);</span>
<span class="cm">/**
* Called when an activity's onDestroy is invoked.
*
* @param isExiting
* If the activity's onDestroy is a result of the Activity going away. If this flag is false,
* this probably means that the Activity is being destroyed due to a configuration change or
* a low memory situation and will be re-created again.
*/</span>
<span class="kt">void</span> <span class="nf">onViewDestroy</span><span class="o">(</span><span class="kt">boolean</span> <span class="n">isExiting</span><span class="o">);</span>
<span class="o">}</span></code></pre></figure>
<p>For example, if the Presenter wants to save and restore some state, it needs to implement this interface. In addition, the View, i.e. Activity of this Presenter, needs to call the methods defined in the interface, when it gets the according Activity callbacks. In case the Interactor needs to save and restore state, it and the Presenter both have to implement the methods from the interface. Then the Activity has to call the Presenter, which has call the Interactor, since the Interactor and the View have no direct connection with one another.</p>
<h3 id="long-running-atomic-operations">Long-running atomic operations</h3>
<p>Sometimes saving simple state is not enough. There are long running operations, which occur in another thread in the background. In addition, some of them have to be atomic, e.g. user sends a payment request to server. You probably want to make sure, that only a single payment is sent even when configuration changes occur while request is running, but still be able to retrieve the results of such operation once it is done. So how to do it?</p>
<p>Let’s start by where should the according component making the request be placed in this architecture. Since most if not all of the scoped graphs are tightly coupled with a UI, one cannot put a component with a potentially longer lifecycle than the UI lifecycle inside one of these. This might firstly cause memory leaks, and secondly cannot guarantee that the result of the long-running operation will be shown at all in the UI, since it might no longer be shown. Therefore, such long-lifecycle components should be living in the Application’s object graph, where they live as long as the application’s process itself. There, they can safely keep state and cache results, without being destroyed every time the user rotates the device.</p>
<p>The second part of the solution is how the Interactor of a particular VIPER Module communicates with these components. Well, pretty simple - it gets them as dependecies and attaches and detaches from them when it gets created or destroyed. It also can register to listen to any callbacks from them while attached. Finally, it can also check any cached state or last operation result on attach they might have, in case the operation got complete while the Interactor was destroyed and recreated and was not listening.</p>
<h3 id="summary">Summary</h3>
<p>The presented architecture is still a work in progress and there will certainly be situations when it will present some challenges. That being said, our team has successfully implemented and released a feature-rich Android application with much more complicated UI by following this architecture. We have not identified any huge drawback so far, but you can be assured that if that happens, I will write about it. For now, I hope I have managed to inspire you to try out developing for Android in the spirit of the clean architecture. Cheers.</p>Lyubomir Ganevluboganev@gmail.comAlthough one could write a detailed description of the concepts and ideas behind an architecture, I believe that the easiest way to understand it is to see an example. Therefore, I have built a simple demo application, which is built with the VIPER architecture in mind. The following sections describe the application and some specifics related to Android.Android clean architecture part 32015-07-26T00:00:00+00:002015-07-26T00:00:00+00:00https://luboganev.dev/post/clean-architecture-pt3<h3 id="android-clean-architecture">Android clean architecture</h3>
<p>The first resource I would like to present is a superb blogpost by Fernando Cejas. <a href="http://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/">Link</a></p>
<p>It presents an implementation of the Uncle Bob’s Clean Architecture in its purest form. The demo application is a simple looking list-detail application. Although it might look an overkill for simplicity of the demo, I could imagine that it can scale really easily to become a feature-rich application, without having to worry about a lot of refactoring or planning. Put in another way, like every architecture, it might seem like an overkill at first, but would eventually pay off in the long run.</p>
<p>The whole Android Studio project is divided in 3 main project modules - presentation Layer, domain Layer and data layer.</p>
<p><img src="https://luboganev.dev/images/2015-07-26-clean-architecture-pt3/clean_architecture_android.png" alt="Android clean architecture" /></p>
<p>The first layer includes the UI and the Presenters related to it. It is implemented using an MVP pattern.</p>
<p><img src="https://luboganev.dev/images/2015-07-26-clean-architecture-pt3/clean_architecture_data.png" alt="Data layer" /></p>
<p>The second layer contains the Interactors implementation and the core business logic of the application.</p>
<p><img src="https://luboganev.dev/images/2015-07-26-clean-architecture-pt3/clean_architecture_domain.png" alt="Domain layer" /></p>
<p>The third layer contains the implementation of the data layer. Its implementation is based on the Repository pattern. It encapsulates any reading and writing to cache, disk or network.</p>
<p><img src="https://luboganev.dev/images/2015-07-26-clean-architecture-pt3/clean_architecture_mvp.png" alt="Presentation layer" /></p>
<p>Although this implementation of the Clean Architecture is as close as it can get, it is different from the VIPER architecture. In the demo implementation the author has encapsulated, for example, all UI and presenters into one project, whereas all Interactors into another. This is a major difference with VIPER, where a single module responsible for one screen of the application contains all related UI, presenters, interactors and entities. Since we wanted to keep this structure when implementing our Android app, we decided not to base our implementation on this blogpost. In addition, due to the high abstraction of the concrete implementations, it was extremely hard to follow the data flow in the demo app from the UI in one project in one project, through the interactors in another and finally to the network requests or read from disk in the third project. Nevertheless, the demo is an extremely good example of what can be achieved and has provided a lot of takeaways.</p>
<h3 id="mvp-in-android">MVP in Android</h3>
<p>The second resource I would like to present is from Antonio Leiva. <a href="http://antonioleiva.com/mvp-android/">Link</a></p>
<p>In this relatively short blogpost, the author presents the MVP pattern and how it is different from the MVC. The best part is the demo application he provides: <a href="https://github.com/antoniolg/androidmvp">Link</a></p>
<p>The demo is very simple to grasp and the introduced pattern is easy to spot there and understand. In addition, the demo application has a VIPER-like structure, where all components (ui, models, presenters and interactors) related to a particular screen are all under the same package name. This makes it really easy to understand and follow the whole data flow. The author also referes to Uncle Bob’s clean architecture and how the MVP can be extended to a full implementation of it. He also hints that dependency injection with Dagger could be used for injecting the presenter implementation in the UI instead of the hard-coded instantiating in the demo. This concept grabbed my attention and I have decided to invest some more time into understanding dependency injection as a concept and particularly Dagger. So I focused on what they can contribute to an Android app architecture.</p>
<h3 id="dependecy-injection-with-dagger">Dependecy injection with Dagger</h3>
<p>There are already a lot of resources available on the subject. You can start by visiting the website of the library here: <a href="http://square.github.io/dagger/">Link</a>.</p>
<p>However, since Dagger is a pure Java library and is not available only for Android, the examples there are pretty generic and do not help a lot when you try to use it in the context of Android applications.</p>
<p>To the rescue comes again Antonio Leiva with a great series of three blogpost dedicated to using Dagger in Android. What’s even better, if you have become familiar with the MVP sample application from him from the previous section, it is the very same demo app which he transforms to use dependency injection with Dagger. This is a highly recommended read you can find here: <a href="http://antonioleiva.com/dependency-injection-android-dagger-part-1/">Part 1</a>, <a href="http://antonioleiva.com/dagger-android-part-2/">Part 2</a>, <a href="http://antonioleiva.com/dagger-3/">Part 3</a></p>
<h3 id="the-square-architecture">The “Square” architecture</h3>
<p>Finally, having read a lot about Dagger, originally developed by Square Inc., I bumped into several blogposts in their tech blog with a lot of critique to the Android SDK and particularly Fragments. I am not a great fan of them either, but what the guys there do is on a whole another level - they advocated against using them altogether and in fact, suggest using a single Activity with many thin Views. A team over there has developed two libraries, which make it possible to implement an Android app with only one activity and only views, which get changed. The libraries are called Mortar and Flow and you can find links to them here: <a href="https://github.com/square/mortar">Mortar</a>, <a href="https://github.com/square/flow">Flow</a>.</p>
<p>It looks like they would make your life easiear and free from the complicated lifecycle of the activities and the even more chaotic lifecycle of fragments. I’m not going to discuss further this approach, since we have decided against using it. Although it may be a viable solution for Square, we cannot take the risk to base our product on a third party library. For us it would mean escaping from one framework, namely the Android SDK UI stuff, only to land into another, which is unfortunately not familiar to us. I’m not saying it is bad, probably it is awesome to work with, like most of the open source libraries from these guys. We just did not want to invest time and effort into learning this new and still experimental approach.</p>
<h3 id="further-steps">Further steps</h3>
<p>So after some experimenting, I have finally managed to come up with an “architecture” for our Android application. It is more like a set of rules, which at the end manage to keep a common language across both our iOS and Android apps’ code. This solution is based on the MVP similar to the one in the Antonio Leiva’s blogposts and uses heavily Dagger for dependency injection, for providing and injecting dependencies, especially while initially connecting all components of a single VIPER module. Implementation details and a sample application will be presented in part 4 of this series. Stay tuned.</p>Lyubomir Ganevluboganev@gmail.comAndroid clean architecture The first resource I would like to present is a superb blogpost by Fernando Cejas. LinkAndroid clean architecture part 22015-07-23T00:00:00+00:002015-07-23T00:00:00+00:00https://luboganev.dev/post/clean-architecture-pt2<h3 id="the-drama-we-have-avoided">The drama we have avoided</h3>
<p>I guess every developer has at some point tried to come up with some clean architectural model. Most of the time, however, this happens in a late stage of the project, thus incorporating any particular architecture more often than not requires major refactoring and complete rebuild of many components. This is a pretty high cost, which the product management often does not want to pay, because it will probably not bring any direct benefit or improvement to the product’s users and the project’s stakeholders. Therefore, it never happens and the problems keep deepening until somebody burns out, screams loudly or becomes increasingly unhappy with his job and eventually quits. In order to avoid such dramatic events, our team has looked for some clean architecture from the very start of our project.</p>
<h3 id="uncle-bobs-clean-architecture">Uncle Bob’s clean architecture</h3>
<p>We went a long way back to fundaments of software engineering theory and we have discovered Uncle Bob’s Clean architecture.</p>
<p><img src="https://luboganev.dev/images/2015-07-23-clean-architecture-pt2/CleanArchitecture.jpg" alt="Uncle Bob's clean architecture" /></p>
<p>The original blog post describing in detail this architecture can be found here: <a href="http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html">Link</a>. Although it dates back to 2012, it describes a fundamental approach, which could be used for building flexible and testable software in general. It does not matter if you are building a website, web application, desktop application or mobile app. The basic principles, guaranteeing better separation of concerns and better modularization of your software project, hold all the aforementioned domains. The most important aspect of this architecture is the so called <em>Dependency rule</em>.</p>
<blockquote>
<p>Nothing in an inner circle can know anything at all about something in an outer circle. In particular, the name of something declared in an outer circle must not be mentioned by the code in the an inner circle. That includes, functions, classes. variables, or any other named software entity.</p>
</blockquote>
<p>In addition to this rule, all connections and communication between components from neighboring circles should be abstractly implemented, e.g. by using simple POJOs and Interfaces when building for Android in Java, or using Protocols and standard classes, when building in Objective-C and Swift in iOS. Such an architecture is extremely flexible and testable. Practically, the implementation of every single component from a particular circle could be completely changed or mocked, without having to make any changes in other parts of the code.</p>
<p>This all looks pretty nice, but is also very vague and abstract. You might ask, how would one go on with implementing it in a mobile app? Luckily some smart people have already done the hard work and have come up with a version of the clean architecture matches very well the domain of iOS mobile apps. It is called VIPER architecture for iOS.</p>
<h3 id="viper-architecture-for-ios">V.I.P.E.R architecture for iOS</h3>
<p>The original blog post describing in detail this architecture can be found here: <a href="http://mutualmobile.github.io/blog/2013/12/04/viper-introduction/">Link</a>. Further high quality read is the objc.io article on this topic which can be found here: <a href="http://www.objc.io/issues/13-architecture/viper/">Link</a>.</p>
<p><img src="https://luboganev.dev/images/2015-07-23-clean-architecture-pt2/viper_diagram.jpg" alt="Anatomy of a VIPER" /></p>
<p>VIPER stands for Views, Interactors, Presenters, Entities and Routing. The combination of all these components lives inside the so called <em>Module</em>. The main motivation behind this architecture is to provide a solution to a problem in iOS known as <em>Massive View Controllers</em>. The traditional MVC architecture used to develop iOS application simply does not provide enough modularity and separation of concerns. The View and the Model parts remain more or less clean, but all complexity ends up in the ViewControllers, which have to manage simply too much stuff. Over 1000 lines of code is not that uncommon for a relatively feature-rich ViewController. VIPER tries to follow the <em>single responsibility principle</em> and splits all these responsibilities among a couple of classes in order to provide a better modularity and separation of concerns.</p>
<p>Looking in more detail into VIPER and the sample project on the website reveals slightly different naming and some extra components.</p>
<p><img src="https://luboganev.dev/images/2015-07-23-clean-architecture-pt2/viper_impl_diagram.png" alt="VIPER components" /></p>
<p>I will not go into too much detail about the particular implementation or discuss every single component, because it is already superbly presented in the articles described above. The one thing I would like to put more focus on is the communication taking place between the Presenter and the Interactor. The Interactor works with the Entities and never passed them to the Presenter. Instead the so called <em>DisplayData</em> objects are being built from the Entities. These objects contain only the data requred by the Presenter to be shown in the View. Think of a typical List/Detail application. You probably have models with a lot of fields, but only a subset of these fields is presented in the list. In that case, the ListDisplayData and DetailDisplayData would both be created from the same model, but will contain different number of fields and may even contain some transformed versions of the original fields.</p>
<p>There are a couple of things one has to keep an eye on, when using the VIPER architecture in iOS. The first thing is that one has to instantiate all the components with their dependencies and do all the wiring between them in a module. This can feel like writing a lot of the same boilerplate code, every time when a new module is created, but there is no way around it. We have tried to automate a little bit this process by writing custom code snippets and code generation scripts, but many times the results prove to be too general for specific module we are currently building.</p>
<p>Another tricky thing to look for comes as a result of the manual wiring mentioned above - cyclic strong references. Since some of the components need their cyclic references in order to work, e.g. Presenter<->Interactor, one can really quickly produce serious memory leaks if not being careful, which references can be strong and which should be weak. This task becomes more complicated the more components and modules there are in the application. Additional hidden memory leaks might happen when using cool language features such as Swift’s closures, so be extra careful when calling Presenter methods from a closure located inside the Interactor.</p>
<p>Finally, this strict separation of concerns sometimes leads to having a really simple Presenters, which just <em>redirect</em> some data flow from the View to the Interactors. This happens when the architecture is applied to a relatively simple screens, which do not have a lot of stuff for the Presenter to do.</p>
<p>Apart from these “problems”, we as a team are really happy with our decision to give this architecture a try. It has not only proven to make sure we code better, but also allowed us to be faster in our development. I believe two main factors are the simpler and shorter components we have developed and the common architectural language, that we have acquired. The former ensures that we can understand what happens in a particular component faster and make code reviews faster due to its and simplicity. The latter helps us to talk the same language, when we plan how to implement new features and ensures no crazy styles of programming is going on, which is can be a problem when more than a couple of different developers work on the same project.</p>
<h3 id="one-does-not-simply-use-viper-in-android">One does not simply use VIPER in Android</h3>
<p>Once we got pretty comfortable with the VIPER architecture in iOS, we wanted to have something similar when building our Android app. However, there are some significant differences in the way the SDKs work in iOS and Android. The following paragraphs describe some of these differences, which make it tricky to directly apply the VIPER architecture to Android.</p>
<p>Android has Activities, which are more or less the equivalent of the iOS’s ViewControllers. A big difference is that one cannot instantiate these objects. One can just ask the Framework to start an Activity and then can override its lifecycle methods in order to do any necessary work. So when implementing VIPER modules, one cannot do the whole wiring in a Wireframe class when the Activity is instantiated. Instead all the initial VIPER module wiring has to take place when an Activity is initialized and started by the Framework itself. The Android SDK also provides Fragments, which can indeed we can be instantiated by us, but there is so much magic related to Fragment creation, which the framework does automatically, that you can never be sure that you have full control over your Fragments. Therefore, I don’t consider using Fragments as the VIPER Views and explicitly instantiating them in a Wireframe as a stable solution. Fighting against the framework is always a bad idea.</p>
<p>Another specific thing in Android are the configuration changes, which normally destroy the whole UI and recreate it. That includes Activities, Fragments and Views. That can prove to be catastrophic, because the whole VIPER Module will be garbage collected and recreated again. So one has to make sure that the state of Module components is saved in some way. In addition, one has to be careful with long-living objects and operations keeping references to the Module components, because they might cause big memory leaks. A typical example is a network request operation, which has a strong reference to the Module’s Interactor as its callback. Since the Interactor holds reference to the Presenter and it hold reference to the View, which holds reference to all UI stuff, this might result in a big memory leak. So one needs to take care of cleaning up such references when a whole Module is being destroyed and recreated. An extremely useful tool for hunting for such memory leaks was recently open-sourced by the guys from Square Inc. and is called Leak Canary and you should be using it even if you are not planning doing any VIPER stuff. Check it out here: <a href="https://github.com/square/leakcanary">Link</a></p>
<h3 id="android-app-architecture-is-a-hot-topic">Android app architecture is a hot topic</h3>
<p>Fortunately, app architecture is a really hot topic lately, and there are more than enough articles and blog posts describing different approaches for building different architectures in Android - classical concepts such as MVP, MVVM, MVC and some pretty radical new approaches like the <em>Square way</em> with Mortar and Flow. The next part of this series will present briefly some of the sources I have found and used while makeing a concept on how to migrate the VIPER architecture to Android. Stay tuned for part 3.</p>Lyubomir Ganevluboganev@gmail.comThe drama we have avoided I guess every developer has at some point tried to come up with some clean architectural model. Most of the time, however, this happens in a late stage of the project, thus incorporating any particular architecture more often than not requires major refactoring and complete rebuild of many components. This is a pretty high cost, which the product management often does not want to pay, because it will probably not bring any direct benefit or improvement to the product’s users and the project’s stakeholders. Therefore, it never happens and the problems keep deepening until somebody burns out, screams loudly or becomes increasingly unhappy with his job and eventually quits. In order to avoid such dramatic events, our team has looked for some clean architecture from the very start of our project.Android clean architecture part 12015-07-21T00:00:00+00:002015-07-21T00:00:00+00:00https://luboganev.dev/blog/clean-architecture-pt1<h3 id="y-u-no-post">Y U NO POST</h3>
<p>Lately I have been pretty busy visiting different meetups, having some proper social life, working on my private projects and building apps at my work, thus this huge delay since the last post I have written. I want to talk about something I am particularly proud of. At the beginning of the year I have done a whole week of experiments and have put a lot of thought in order to come up with an Android version of the architecture, which our team used while building our iOS application. The main goal was to use the same familiar “architectural language”, which we have developped in our iOS application. This way we do not have to pay too high cost when switching between developing for iOS and Android. We have tried to establish a common language understood by all mobile developers, and I believe that we have succeeded. We have managed to build a pretty complex Android application with a lots of moving parts, which still feels quite right and does not bring us a lot of headaches. I have noticed that we tend to write almost the same subtasks for both platforms when implementing new features into our apps. I consider this a vital sign, showing that we have managed to achieve a harmony between our native implementations for iOS and Android. Therefore, I have decided to share some of the know-how and experience, which we have collected throughout the last months.</p>
<h3 id="why-to-invest-into-architecture">Why to invest into architecture</h3>
<p>I would like to start by talking why I think that apps architecture is an important topic to discuss and why it is worth to invest time and resources into building one. I guess all experienced Android engineers know how complex building and Android application can be. Well guess what? Building and iOS app is also pretty complex and developing for the iOS platform has its own major pains. One cannot just start buidling using a naíve approach, because sooner or later one will end up with a lot of god objects, no flexibility and dependencies flying everywhere. To sum up, at some point it will become a total mayhem and adding new functionality will be either extremely hard and needing major refactoring or completely impossible. Let us not underestimate the complexity of an app. Let’s not even call it app, let’s talk about a project or a system, because let’s face it, a mobile application with a lot of functionality can be seen as complex system with front-end, back-end and storage.</p>
<p>It is sometimes pretty easy to start quickly hacking together a working application, but this approach cannot scale. It does not work well, when you first build a minimum viable product and then incrementally add a lot of extra features to it. It does not work well with product development in the agile software development world. And please do not tell me that planning a basic architecture is not an agile approach, because if you completely ignore this step, pretty soon you won’t be able to be agile at all.</p>
<h3 id="lets-face-it---building-apps-is-complex">Let’s face it - building apps is complex</h3>
<p><img src="https://luboganev.dev/images/2015-07-21-clean-architecture-pt1/android_anatomy.jpg" alt="Anatomy of an Android" />
Let’s look at some common Android framework stuff that one has to implement, work around or just manage when building applications. It probably does not have anything to do in particular with the main business logic of the applications, but one has to do it in order to have a working Android app at all.</p>
<ul>
<li>backwards compatibility</li>
<li>configuration changes (orientation), UI state and threading</li>
<li>local storage, data synchronisation with remote API</li>
<li>fragile environment (spotty internet connection, and other apis)</li>
<li>efficient usage of restricted resources (memory, bandwidth, cpu)</li>
<li>beautiful UI with proper Material design and good performance</li>
</ul>
<p>Managing the above stuff is not trivial, but you probably have to do all of it in your app as well. The SDK itself is also not really trivial so let’s stop underestimating it. There are so many components, patterns and functinality, some of which work only with particular other componets. Just think about the following list of components and patterns you probably use on daily basis:</p>
<ul>
<li>Activities, Services, Broadcast Receivers, Content Providers, Bundles, Intents</li>
<li>Fragments, Views, Notifications, Resources</li>
<li>Databases, IPC, Threads, Storage</li>
<li>Thousands of APIs related to services and specific hardware features of devices</li>
<li>Support libraries and external third party libraries</li>
</ul>
<p>And this whole complexity is there, even before you start implementing the stuff that your app should do. So the question is, where to add the code which defines what your application does. Should you put it inside and Activity maybe? Let’s see what is a common functionality, which an activity code will manage:</p>
<ul>
<li>lifecycle, state save and restore (Bundles, Parcelables)</li>
<li>multiple entry points (Intents, Share, Notifications deep links)</li>
<li>non-trivial navigation (back, up, backstack, processes, Intent flags)</li>
<li>Views and Fragments inside and their communication (interfaces, callbacks, fragment transactions, inflation)</li>
<li>transitions, shared hero elements, alternative layouts and resources for devices, orientation etc.</li>
</ul>
<p>That’s a lot of code already there, which handles a lot of stuff still having nothing to do you with your code business logic. Programming the whole business logic there will make the code really unreadable, and you will probably not be able to keep track of what is going on, due to the huge bloated class. We need a better separation of concerns and a set of common patterns, which will put some order into our code. It should also provide enought flexibility, make the code more testable and reduce code duplication and all other bad software development practices, which normally sprout when one hacks together quickly something.</p>
<h3 id="ok-i-get-it-show-me-the-solution">OK, I get it, show me the solution</h3>
<p>Unfortunately it is not that easy. We need to first look at what already exists out there in order to come up with some ideas and proper architectural design. In the next post I will review some information sources I have found related app architecture. They provide different approaches and present various concepts on how one should build an application architecture. Stay tuned for part 2.</p>Lyubomir Ganevluboganev@gmail.comY U NO POST Lately I have been pretty busy visiting different meetups, having some proper social life, working on my private projects and building apps at my work, thus this huge delay since the last post I have written. I want to talk about something I am particularly proud of. At the beginning of the year I have done a whole week of experiments and have put a lot of thought in order to come up with an Android version of the architecture, which our team used while building our iOS application. The main goal was to use the same familiar “architectural language”, which we have developped in our iOS application. This way we do not have to pay too high cost when switching between developing for iOS and Android. We have tried to establish a common language understood by all mobile developers, and I believe that we have succeeded. We have managed to build a pretty complex Android application with a lots of moving parts, which still feels quite right and does not bring us a lot of headaches. I have noticed that we tend to write almost the same subtasks for both platforms when implementing new features into our apps. I consider this a vital sign, showing that we have managed to achieve a harmony between our native implementations for iOS and Android. Therefore, I have decided to share some of the know-how and experience, which we have collected throughout the last months.