<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Mike Nakhimovich on Medium]]></title>
        <description><![CDATA[Stories by Mike Nakhimovich on Medium]]></description>
        <link>https://medium.com/@theMikhail?source=rss-6ebfb5fe99f9------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*POSNiElhIrFMIYFFBUdvrQ.jpeg</url>
            <title>Stories by Mike Nakhimovich on Medium</title>
            <link>https://medium.com/@theMikhail?source=rss-6ebfb5fe99f9------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 00:18:12 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@theMikhail/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Store is joining Mobile Native Foundation]]></title>
            <link>https://medium.com/@theMikhail/store-is-joining-mobile-native-foundation-b72736c7c83b?source=rss-6ebfb5fe99f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/b72736c7c83b</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[mobilenativefoundation]]></category>
            <category><![CDATA[foss]]></category>
            <dc:creator><![CDATA[Mike Nakhimovich]]></dc:creator>
            <pubDate>Thu, 26 May 2022 18:48:56 GMT</pubDate>
            <atom:updated>2022-05-26T19:02:20.965Z</atom:updated>
            <content:encoded><![CDATA[<p>TLDR: Store is joining the Mobile Native Foundation and needs your help.</p><p>Seven years ago, I was working at the New York Times and helped create a library called <a href="https://github.com/nytimes/Store">Store</a>. It was a small library that fit the use case of reactively loading data from network and local storage. Originally, we built Store using <a href="https://github.com/ReactiveX/RxJava">RxJava</a> and patterns adopted from <a href="https://github.com/google/guava/wiki/CachesExplained">Guava’s Cache implementation</a>. A few year’s later I was working at Dropbox and (with the help of some community members including Yigit Boyar &amp; Fabio Collini ) created a new <a href="https://github.com/dropbox/Store">fork</a> of Store which was rebuilt from the ground up using Coroutines. Eventually this became the main Store repo and New York Times archived their copy. Store has continued to grow (74 contributors and counting!) and so has my career. As of a few months ago I am no longer working at Dropbox and wanted to once again re-evaluate where Store should live. My first goal was to find a new home for the project that would be permanent. My second goal was for that new home to allow the project to grow in size and contributors.</p><p>Today I am happy to announce that Dropbox has agreed to donate Store to the <a href="https://mobilenativefoundation.org/">Mobile Native Foundation</a> making it MNF’s first Android library project (The incredible Flank beat me to it for first project). Store will now have a permanent home that is decoupled from my career choices.</p><p>This decision was driven by a few factors.</p><ul><li>Mostly importantly, I believe in the MNF mission, I love the ability for many companies to come together and iterate on a solution. I want to walk the walk and take the most popular project I have and move it to MNF. I hope this sets a precident for others to follow. I believe dropping corporate ownership from Android open source projects is important for the health of the community.</li><li>I’m tired of convincing my employers that open source is important. Store can live on whether my day job wants to contribute to it or not.</li><li>I am hoping to broaden the reach of this project to users that only add libraries from completely FOSS orgs.</li><li>I am getting little long in the tooth and my clan has expanded, over time I’d love to find others that would want to shepherd this project.</li></ul><p>Over the next few months, I will be cleaning up older issues/prs and giving the project a fresh coat of paint, no major changes are planned as I’ll also be juggling a day job and a one year old.</p><p>If you are a contributor/user that wants to get more involved please reach out to me on twitter:<a href="https://twitter.com/friendlymikhail">@FriendlyMikhail.</a> I would love more help with this project.</p><p>If you are a maintainer of an open source repo, consider joining me in moving your code under the Mobile Native Foundation.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b72736c7c83b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Dagger Component Dependencies for Library Development]]></title>
            <link>https://proandroiddev.com/dagger-component-dependencies-for-library-development-e2df7ce68233?source=rss-6ebfb5fe99f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/e2df7ce68233</guid>
            <category><![CDATA[dagger]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[gde]]></category>
            <category><![CDATA[kotlin]]></category>
            <dc:creator><![CDATA[Mike Nakhimovich]]></dc:creator>
            <pubDate>Sat, 09 Mar 2019 16:50:51 GMT</pubDate>
            <atom:updated>2019-03-09T23:39:11.991Z</atom:updated>
            <content:encoded><![CDATA[<p>Android developers are all app developers. A growing portion of us are also library developers. When building apps, I am a strong advocate for dependency injection (DI). DI gives us advantages such as the ability to externalize our dependencies, ease in testing, and most importantly, reusability. Lately I’ve been writing more and more libraries rather than client apps which has made me rethink how I use Dagger.</p><p>Normally my apps have an app component, an activity subcomponent and a view/screen subcomponent. Each subcomponent has access to all the dependencies of its parent component.</p><p>Unfortunately, that setup breaks down if, for example, activities live anywhere except inside the app module because there is a coupling between the parent and its subcomponents (<a href="https://google.github.io/dagger/android.html">Dagger-Android</a> has a solution for this that we will not be covering in this article). Instead, using the concept of component dependencies, I settled on the following workflow that allows any host app to pass dependencies into libraries, regardless of whether they use Dagger or not.</p><p>Let’s pretend we are all working at Kittn, an up-and-coming cat photo app. Our app started as a single feed of cat photos, but Kittn has been growing by 20% monthly (take that, Zuch!). All the Kittn code was previously in a single module, but now that we have funding, and a team of 100+ devs, we can’t realistically have everyone work in the same Gradle module.</p><p>My team in particular was tasked with creating a comments module that can be integrated into the app. (For consistency, we’ll call this module Commentr, in case we decide to spin it off and sell it as its own service in the future). The host app would call a function that is exposed from my library</p><pre><strong>CommentNavigator.goTo(CommentWithId(5), this)</strong></pre><p>which will launch a Comment Activity. So far, so good. The app module has a module dependency on comment module and we are off and running.</p><p>Next, product comes back to our team and says that they have no idea how well comments are doing because we don’t have any analytics. Well…that’s not the full story. The Kittn app is using Firebase Analytics but that implementation lives inside the app and not inside the comments module.</p><p>Additionally, the company is spiraling up a new app Puppr which, as you guessed, will also want to use my team’s Commentr library. Puppr, however, is using another analytics provider.</p><p>Luckily for both apps, our module was already using Dagger and will have no problem working with many implementations of a common interface. Let’s get down to it.</p><p>Within Commentr we have a comment activity which contains a presenter <strong>CommentPresenter</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/594/1*2h_v5E5wu4GYEDa9t9s9iA.png" /></figure><p>We also define within Commentr the following interfaces to allow us to log analytics:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/864/1*A-OEC7NQW8kd_LvEeLj0pQ.png" /></figure><p>RealCommentPresenter is our implementation and will be provided by a <strong>DaggerCommentComponent</strong> along with any dependencies that it has:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*ZAWTt4qQhnyCRfQR6u4fiQ.png" /></figure><p>Notice that <strong>RealCommentPresenter </strong>depends on the interface not the implementation of <strong>HostAnalytics</strong>. So how do we actually get the implementation? Component dependencies, that’s how!</p><p>First we create our CommentComponent</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1008/1*1ni2qUKVpkJLKgLAFBvvcQ.png" /></figure><p>This is the component that will know how to provide dependencies that live within our Commentr module — things like our database or API. Normally, we would create an instance of this component, retain it somewhere and then perform injection with it. But we still have the issue of a circular dependency — somehow needing to depend on the host’s analytics implementation without creating a circular dependency between the comment and app module. The Kittn app module depends on the Commentr module; we can’t also set the Commentr module to depend on the app module. Instead we will set up a component dependency and only have a dependency on an interface. Per the Dagger javadoc:</p><p>While subcomponents are the simplest way to compose subgraphs of bindings, subcomponents are tightly coupled with the parents; they may use any binding defined by their ancestor component and subcomponents. As an alternative, components can use bindings only from another <em>component interface</em> by declaring a <a href="https://google.github.io/dagger/api/2.14/dagger/Component.html#dependencies--">component dependency</a>.</p><p>Our Kittn app module already has an implementation for Analytics that looks to be really perfect for what we need within Commentr:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BzQBY4EIwS5gmatBGuQQaQ.png" /></figure><p>How about we add our Comments <strong>HostAnalytics </strong>interface here</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DQAUR14S8eZZG3gqTSI_1w.png" /></figure><p>Now <strong>KittnFirebaseAnalytics</strong> will be an implementation of HostAnalytics. Unfortunately, it’s still in the wrong module (Commr can’t depend on the Kittn app module because the app module depends on Commentr). Wouldn’t it be nice if we can somehow pass this implementation directly into <strong>CommentComponent </strong>during its construction?</p><p>First, we are going to add a component dependency on the interface <strong>HostComponent. </strong>Remember that <strong>HostComponent</strong> is nothing more than an interface that can provide an implementation of HostAnalytics:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1008/1*KUSNmi9GqdxpDOkJ6uHGzQ.png" /></figure><p>When we run our build, Dagger will generate an additional builder method <strong>hostComponent </strong>that will allow us to pass and set an instance of the HostComponent:</p><p>Within Commentr:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*g9Nwl9mj2Tn53vkx0Z2pww.png" /></figure><p>Within Kittn Application Class or wherever you inititialize the Commentr library:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*L2cVNid4_taCxF8DpmbASg.png" /></figure><p>Let’s unpack the above a bit… by passing in an implementation of <strong>HostComponent</strong> into our <strong>CommentComponent builder, CommentComponent’s </strong>object graph will now contain every object that was provided from the HostComponent’s implementation. Provided just means that some function within the passed in implementation returns a certain type. In our case the type that <strong>HostComponent </strong>provides is <strong>HostAnalytics.</strong> Since we have a function that was returning <strong>HostAnalytics</strong>, <strong>CommentComponent’s </strong>graph will now be able to provide <strong>HostAnalytics </strong>in the same way that it can provide anything that lives in a dagger <strong>CommentModule.</strong></p><p>One of the things I absolutely love about this setup is that I can test my <strong>Commentr</strong> module<strong> </strong>in isolation by just passing fakes/stubs through the <strong>HostComponent</strong> interface. Another advantage is that <strong>CommentComponent </strong>does not care what implements <strong>HostComponent</strong>. This means that if I have an app with the following app component:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*blEE-00zAQ_WT3s1EratDw.png" /></figure><p>As long as AppComponent has an instance of <strong>HostAnalytics </strong>in its object graph, We can have <strong>AppComponent</strong> extend <strong>HostComponent</strong> and, it will fulfill our interface’s requirement.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/812/1*rlhWdIk20MZNnU9Poc19Uw.png" /></figure><p>If I get a new requirement and now need to pass an Image Loader from our app to our library we can add an additional providesMethod within our <strong>HostComponent </strong>interface like</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/740/1*3aBATsLD5j-PXL5b4DeSLA.png" /></figure><p>Now my AppComponent will need to also satisfy providing an <strong>ImageLoader </strong>implementation. If it doesn’t dagger will not let me compile. Yay for failing fast</p><h3>Wrapping up:</h3><p>While subcomponents work well when you have a single module or want to have every subcomponent to have every dependency from the parent component, component dependencies work well if you want to set a relationship that defines exactly what a parent component exposes to the child. I have used the above pattern to solve challenges like saving data to the app’s db, delegating click handling back to a host, pulling configuration from the host app &amp; even passing a view container to a library module within a SingleActivityApplication.</p><p>Happy Daggering</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e2df7ce68233" width="1" height="1" alt=""><hr><p><a href="https://proandroiddev.com/dagger-component-dependencies-for-library-development-e2df7ce68233">Dagger Component Dependencies for Library Development</a> was originally published in <a href="https://proandroiddev.com/">ProAndroidDev</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Room with a View]]></title>
            <link>https://medium.com/s23nyc-tech/room-with-a-view-8cc759b312cb?source=rss-6ebfb5fe99f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/8cc759b312cb</guid>
            <category><![CDATA[database]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[gde]]></category>
            <dc:creator><![CDATA[Mike Nakhimovich]]></dc:creator>
            <pubDate>Fri, 09 Nov 2018 18:57:22 GMT</pubDate>
            <atom:updated>2018-11-09T18:57:22.606Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_7g2yTqIWDE0QiARZb9DSQ.jpeg" /><figcaption>View from the S23NYC office</figcaption></figure><p>Recently, our Android team started going through tech debt and spiking on how we can continue to have a best in class SNKRS experience for our users. While the app is beloved, as evident by our 4.5 rating on Play Store, we still felt that it was necessary to update our architecture to the latest and greatest that Android has to offer. In this post I’ll be going over the work we are doing to take the old persistence model, which stored flattened feed objects into Sqlite directly, and convert it to a relation schema using Google’s fantastic <a href="https://developer.android.com/topic/libraries/architecture/room">Room</a> ORM. I’ll be going over the good, the bad, and the ugly of using Room.</p><h3>The Good</h3><h4>Kotlin Support</h4><p>Room works with Kotlin out of the box, you never have to write a line of java to work with Room. Your data models, DAOs, &amp; database can all be written in Kotlin.</p><h4>API Done Right</h4><p>It takes all of ten minutes to be up and running with Room:</p><p>First, create Kotlin data class and annotate them as room entities</p><pre>@Entity<br>data class Sneaker(<br>        @PrimaryKey val id: String,<br>        ...<br>)</pre><p>Next, create a BaseDAO (Thanks <a href="https://medium.com/androiddevelopers/7-pro-tips-for-room-fbadea4bfbd1">Florina for the tip!</a>)</p><pre>interface BaseDao&lt;T&gt; {<br>    @Insert(onConflict = OnConflictStrategy.<em>REPLACE</em>)<br>    fun insert(vararg obj: T)<br><br>    @Delete<br>    fun delete(vararg obj: T)<br>}</pre><p>Now, you can create abstract DAOs like the one below. You will only have to define query functions. Insert/Delete functionality will be inherited from your base DAO. Overall, find the syntax to feel familiar for those that use retrofit</p><pre>@Dao<br>abstract class SneakerDAO : BaseDao&lt;Sneaker&gt; {<br>    @Query(&quot;Select * from Sneaker where id like :id&quot;)<br>    abstract fun getSneakerById(id: String): Sneaker<br>}</pre><p>Once you have your DAOs, you create an abstract class with your DAOs and entities:</p><pre>@Database(<br>        entities = [Sneaker::class, ...],<br>        version = 1)<br>abstract class SnkrsDB : RoomDatabase() {<br>    abstract fun sneakerDAO(): SneakerDAO<br>    ...<br>}</pre><p>Finally, you create an instance of your DB:</p><pre>@Singleton fun provideRoomDB(context: Context): SnkrsDB =<br> Room.databaseBuilder(context, SnkrsDB::class.<em>java</em>, &quot;coredb&quot;)<br>            .build()<br></pre><p>Anytime you want to access your data you only need to call the function made above:</p><pre>val sneaker = snkrsDB<br>.sneakersDAO<br>.getSneakerById(5)</pre><h4>Code Generation</h4><p>Room is great because it allows you to access your DAOs which will have auto-generated implementations of all your db operations (no more cursors/content values necessary). Developers can now focus on writing beautiful features rather than binding parameters to sql statements or handwriting all the content values boilerplate that was previously required.</p><h4>Native RxJava Support (It’s Reactive!)</h4><p>Let’s go back to our query. The way we currently have it written we would only be able to access the data on a background thread (in a blocking fashion). Rarely would you want data on a background thread. Instead, it would be nice to have all database calls be observables similar to how retrofit allows observable call adapters.</p><p>The function can now be changed to return a Flowable&lt;Sneakers&gt; rather than just a Sneaker scalar value</p><pre>    @Query(&quot;Select * from Sneaker where id like :id&quot;)<br>    abstract fun getSneakerById(id: String): Flowable&lt;Sneaker&gt;</pre><p>Now the data can be accessed with all the power of RxJava</p><pre>snkrsDB<br>.sneakersDAO<br>.getSneakerById(5)<br>.toObservable<br>.observeOn(Schedulers.io())<br>.subscribeOn(AndroidSchedulers.mainThread())<br>.subscribe({updateScreen(it)},{logError{it})</pre><p>The biggest advantage of exposing queries as “endless streams” is that an update to the database will trigger a new emission to the emission above.</p><p>Anytime another insert/delete/update is run that will update the Sneaker color, my getSneakerByID backed observable will emit a new value. Additionally, schedulers can be used to allow database access on a background thread and responses to be delivered on the main thread.</p><h4>Paging Support</h4><p>So far there has been only a single record from the Sneaker table. What if instead all Sneakers need to be shown in a feed? Room allows writing a query like the one below to return all Sneakers:</p><pre>@Query(&quot;Select * from Sneaker&quot;)<br>    abstract fun getSneakerById(id: String): Flowable&lt;List&lt;Sneaker&gt;&gt;</pre><p>This doesn’t scale very well since the table could have thousands of records in it. Luckily the architecture components team integrated the <a href="https://developer.android.com/topic/libraries/architecture/paging/">Paging Library</a> with Room.</p><p>Now a pagedList can be built that will bind to a RecyclerView rather than returning all records:</p><p>First, return a DataSource.Factory:</p><pre>@Query(&quot;Select * from Sneaker&quot;)<br>    abstract fun getSneakerById(id: String): DataSource.Factory&lt;Int, Sneaker&gt;</pre><p>Then build up your PagedList, in our case we return 10 items per page:</p><pre> val config = PagedList<br>        .Config.Builder()<br>        .setPageSize(10)<br>        .setInitialLoadSizeHint(20)<br>        .build()<br> <br>val dataSourceFactory = snkrsDB<br>        .sneakerDAO()<br>        .getPage()<br>       <strong><br></strong>val pages = RxPagedListBuilder(<br>        dataSourceFactory, config)<br>        .buildObservable()</pre><h4>Testing Support(!!!!)</h4><p>One of the most exciting features of room is that it provides a straightforward API for writing connected JUnit tests. While you can’t do unit testing due to differences in sqlite on android/jvm, you can write connected junit tests that work flawlessly with Room. Here’s an example:</p><p>First you create an instance of your DB as an in memory database:</p><pre>val snkrsDB = Room.inMemoryDatabaseBuilder(InstrumentationRegistry.getTargetContext(), SnkrsDB::class.<em>java</em>).build()</pre><p>Next, you work with your DB same as you would in your production app</p><pre>val model=testSneaker(id=5,...)<br>snkrsDB.sneakerDAO.insert(model)<br>asssertThat(snkrsDB.sneakerDAO.getByID(5)).isEqualTo(model)</pre><p>TDD with SQL is now a reality and dramatically sped up my development time.</p><h4>Type Converters:</h4><p>Want to save a date to the db as a long? You can write a type converter for how that works:</p><pre>object MyConverters {<br>    <br>    @TypeConverter<br>    @JvmStatic<br>    fun toDate(value: Long?): Date? {<br>        return if (value == null) null else Date(value)<br>    }<br><br>    @TypeConverter<br>    @JvmStatic<br>    fun toLong(value: Date?): Long? {<br>        return value?.<em>time<br>    </em>}<br><br>}</pre><p>Similar you can have type converters for saving a list of strings to a single column:</p><pre>fun stringAdapter(): JsonAdapter&lt;List&lt;String&gt;&gt; {<br>    val listOfStringsType = Types.newParameterizedType(List::class.<em>java</em>, String::class.<em>java</em>)<br>    val adapter: JsonAdapter&lt;List&lt;String&gt;&gt; = <em>moshi</em>.adapter(listOfStringsType)<br>    return adapter<br>}<br><br>@TypeConverter<br>@JvmStatic<br>fun toJSON(list: List&lt;String&gt;?): String? = stringAdapter().toJson(list)<br><br>@TypeConverter<br>@JvmStatic<br>fun fromJson(list: String): List&lt;String&gt;? = stringAdapter().fromJson(list)</pre><p>Notice that we used Moshi to marshal/unmarshal the String</p><p>We can now add the Type Converter to our data class which will tell Room how to save/read the field from db</p><pre>@Entity<br>@TypeConverters(value = [MyConverters::class])<br>data class Sneaker(<br>        @PrimaryKey val id: String,<br>        val sizes: List&lt;String&gt;<br>)</pre><p>It’s really nice to be able to encode the type converter logic and never have to worry about it again.</p><h4>1:1 relationships with Embedded</h4><p>Let’s say our Sneaker needs has a 1:1 relationship with a barcode, we can leverage an Embedded annotation which will save the barcode to the same table as the Sneaker:</p><pre>data class Sneaker(<br>        @PrimaryKey val id: String,<br>        @Embedded val barcode:Barcode<br>)</pre><p>Anytime we insert or query a Sneaker from Room, it will properly set the Barcode field with any scalar values the Barcode contains. Think of it as flattening and unflattening the two objects. The only caveat is that Barcode &amp; Sneaker cannot have any fields that are named the same (more on that in the Bad/Ugly part)</p><h3>The Bad</h3><h4>No support for saving nested objects</h4><p>Most annoyingly, there is no support for saving nested objects. Even if we define the relations and embedded objects above, we still will need to iterate through our network models and save each object separately. Hopefully, the arch component team can improve on this process.</p><h4>Embedded fields need unique names</h4><p>Back to our embedded example above. If Barcode contains a field called name and Sneakers contains a field called name you will get an error on compile. Since Embedded fields are saved to the same table you need to have unique names for each field. One workaround is to manually rename the column in one object or another like the following:</p><pre>@ColumnInfo(name = &quot;barcodeName&quot;) val name: String?,</pre><p>Another way is:</p><pre>@Embedded(prefix = barcode)</pre><p>which will then prefix all columns pertaining to barcode to barcode<strong>*FIELDNAME*</strong></p><h4>No support for recursive relations</h4><p>Even if we go through the trouble of creating the above “view” of data, we still cannot load recursive relationships. For example, if a FeedItem contains images and barcodes, Room’s compilation will fail if each barcode contains an image as well.. This lead us to have to lazy load a Barcode’s images on our own.</p><h3>The Ugly</h3><h4>1 to many relations are pretty messy</h4><p>As mentioned at the top of the post, we are migrated from a data schema where we saved each Feed Item in a single table where all nested objects are serialized to json strings. Unless we rewrote every caller of the old sqlite db, we need to support callers that expect to get “fat models” back from room. Unfortunately this is not easy. Below are steps we needed to take to return a FeedItem which contained 1:1 &amp; 1:many relationships 4 levels deep:</p><p>Need to make views</p><ol><li>views should contain all 1:1 as embedded &amp; all 1:many as relations</li><li>all relations need to be nullable since they get selected after embeddeds</li><li>entities need to have a second constructor for nullable fields</li><li>relation fields need to be marked as @ignore and nullable</li></ol><p>Below is an example of a data schema that is similar to what we have in our app. Below are the additional objects and annotations you’d need to create if you wanted to load the following FeedItem with:</p><ul><li>1:1 relationship with a Barcode</li><li>1:many relationship with Other linked items</li><li>1:many relationship with properties</li><li>Properties that have a 1:many relationship with Images</li></ul><pre>data class FeedItemFull(<br>        @Embedded var thread: FeedItem,<br>        @Embedded var barcode: BarcodeFull?<br>) {<br>    @Relation(entity = LinkedItem::class, parentColumn = &quot;itemId&quot;, entityColumn = &quot;itemId&quot;)<br>    lateinit var relations: List&lt;LinkedItem&gt;<br>    @Relation(entity = Property::class, parentColumn = &quot;itemId&quot;, entityColumn = &quot;itemId&quot;)<br>    lateinit var properties: List&lt;PropertFull&gt;<br>}<br><br>class BarcodeFull(@Embedded<br>                  var barcode: Barcode? = null) {<br><br>    @Relation(entity = Barcode::class, parentColumn = &quot;ItemId&quot;, entityColumn = &quot;itemId&quot;)<br>    var barcode: List&lt;Barcode&gt;? = null<br>}<br><br>data class PropertyFull(@Embedded val property: Property) {<br><br>    @Relation(parentColumn = &quot;propertyId&quot;, entityColumn = &quot;propertyId&quot;)<br>    var images: List&lt;Image&gt;? = null<br>}</pre><p>We were hoping that Room would “just work” when it comes to relationships and be able to save/load nested objects without all the ceremony above. Hopefully someday we can get to a better place with this. We considered writing an annotation processor to save FeedItems which would, in turn, save all nested complex objects to their own table.</p><h4>Conclusion</h4><p>After using Room for the first time we can definitely say that the good far outweigh the bad. The biggest pain point is how relationships are handled, otherwise doing sql on android is dramatically easier than its ever been. We will continue to migrate more and more of our data layer to Room and hope that the always amazing Architecture Component team will continue to make improvements</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8cc759b312cb" width="1" height="1" alt=""><hr><p><a href="https://medium.com/s23nyc-tech/room-with-a-view-8cc759b312cb">Room with a View</a> was originally published in <a href="https://medium.com/s23nyc-tech">S23NYC: Engineering</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Store+Room — A Reactive Repository]]></title>
            <link>https://medium.com/s23nyc-tech/storeroom-a8d6391bccb7?source=rss-6ebfb5fe99f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/a8d6391bccb7</guid>
            <category><![CDATA[room]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[open-source]]></category>
            <category><![CDATA[repository-pattern]]></category>
            <dc:creator><![CDATA[Mike Nakhimovich]]></dc:creator>
            <pubDate>Wed, 30 May 2018 16:59:37 GMT</pubDate>
            <atom:updated>2018-05-30T18:29:17.072Z</atom:updated>
            <content:encoded><![CDATA[<h3>Store: a brief history</h3><p>One of the first libraries I open sourced was <a href="https://github.com/NYTimes/Store">Store</a> which was an implementation of the Repository pattern wrapped in RxJava. Store abstracted away the common pattern of<a href="https://github.com/NYTimes/Store/blob/feature/rx2/Images/store-5.jpg"> <em>load from memory, if not present load from disk parse the data, if not present load from network</em></a>. This was all done with minimal setup by a user:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b8002bffa3ca31ee068f4084ba096133/href">https://medium.com/media/b8002bffa3ca31ee068f4084ba096133/href</a></iframe><p>Initially Store was something I developed based on my use cases. While everything was interface based, I shipped a few implementations of parsers for <a href="https://github.com/NYTimes/Store/tree/feature/rx2/middleware">Gson</a>, <a href="https://github.com/NYTimes/Store/tree/feature/rx2/middleware-moshi">Moshi</a>, <a href="https://github.com/NYTimes/Store/tree/feature/rx2/middleware-jackson">Jackson</a>) and a <a href="https://github.com/NYTimes/Store/blob/feature/rx2/filesystem/src/main/java/com/nytimes/android/external/fs3/FileSystemPersister.java">FilePersister</a> which eased in streaming data from a network to disk.</p><p>Fast forward 18 months and Store is up to 3000+ stars &amp; 37 contributors mostly from folks I’ve never met (Thank you all!). In that time the community has helped implement:</p><ul><li><a href="https://github.com/NYTimes/Store/blob/feature/rx2/store/src/main/java/com/nytimes/android/external/store3/base/impl/MemoryPolicy.java">Memory</a> &amp; <a href="https://github.com/NYTimes/Store/blob/feature/rx2/store/src/main/java/com/nytimes/android/external/store3/base/impl/StalePolicy.java">disk caching</a> policies</li><li><a href="https://github.com/NYTimes/Store/blob/feature/rx2/middleware-moshi/src/main/java/com/nytimes/android/external/store3/middleware/moshi/MoshiTransformerFactory.java">Wrappers for fetchers that return full objects rather than streams</a></li><li><a href="https://github.com/NYTimes/Store/blob/ed378585c20b8f1c53986d6a2c9875a6fafb58b6/store/src/main/java/com/nytimes/android/external/store3/base/impl/Store.java#L34">Result abstractions to determine which source data is coming from</a></li><li><a href="https://github.com/NYTimes/Store/blob/feature/rx2/store/src/main/java/com/nytimes/android/external/store3/base/impl/Store.java#L42">New API for refreshing get calls on clearing data</a></li><li><a href="https://github.com/NYTimes/Store/blob/feature/rx2/store-kotlin/README.md">A fluent Kotlin DSL</a></li><li><a href="https://github.com/NYTimes/Store/wiki">Documentation including translations to Russian &amp; Spanish</a></li><li><a href="https://github.com/NYTimes/Store/pull/155">An update to RxJava2</a></li><li><a href="https://github.com/NYTimes/Store/pulls?q=is%3Apr+is%3Aclosed">Many other PRs full of performance improvements and bug fixes</a>.</li></ul><p>Store as it stands today is a full fledged data solution that both helps prevent extraneous data calls to your network and helps write apps that exhibit proper separation of concerns. Since moving on from the New York Times, I’ve had a chance to rethink how Store can better suit the needs of users in the modern Android ecosystem. I’m not just the primary maintainer of Store, I also use it in every project I have built since.</p><h3>Time to get a Room</h3><p>One of the most <a href="https://github.com/NYTimes/Store/issues/215">popular open source requests Store had</a> was integration with <a href="https://developer.android.com/topic/libraries/architecture/room">Room</a>. I was hesitant to integrate Room because I had never used it before and I wasn’t really sure how the integration would work. Now that I’m working at Nike’s s23NYC studio, we explored what data solution best fits into our re-architecting of the SNKRS Android app that we maintain. After exploring various solutions we decided that Room was by far the most robust and easy to use persistence solution. While Room was great at working with a database, it was still missing key features like request de-duping, memory caching, stale/refresh policies and all the other great features mentioned above. We still needed a repository abstraction that would wrap Room to implement these features. So, my team set out to fuse all the great features of Room with all the things we loved from Store.</p><p>Since most of Store was based on interfaces, we were able to integrate Room into Store by building a RoomPersister and StoreRoom, which is a specialized type of store. The StoreRoom includes the familiar features from Store while taking advantage of the reactive nature of Room &amp; Flowables.</p><h3>Room: Remind me what that is?</h3><p>Room is a persistence library that is part of Google’s Architecture Components. Room is an ORM and does a fantastic job of giving you all the power of working with a database without any of the messiness of cursors, database connectors or having to map data yourself. Room is built on top of SQLite and takes care of a lot of the boilerplate associated with saving to or reading from a database.</p><p>Additionally, Room’s reactive API through its first class RxJava support transforms simple SQL queries into auto updating Flowables. Room queries exposed as RxJava Flowables is what I’ve always imagined as the perfect persistence layer to Store. It helped me get rid of messy code like the old stream &amp; getRefreshing functions we previously used to fake endless streams. Using a Room backed persister allows Store subscriptions to update anytime the underlying data changes.</p><h3>Store+Room a match made in Android heaven</h3><p>Using the new StoreRoom is every bit as easy as using a regular Store.</p><p>First, create a Room DAO as you always do with Room. Within your DAO, expose an Insert &amp; a Query function. The types do not need to be the same.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6e6de1c3fa8fea65130c3ab6da474d98/href">https://medium.com/media/6e6de1c3fa8fea65130c3ab6da474d98/href</a></iframe><p>Next, implement Store’s Fetcher to tell StoreRoom how to get new network data. Below is an example that would use an API (Retrofit is recommended) to return a Single&lt;User&gt; based on a passed in user id.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8e95e7b8fa2ebfc918e131b9675a441c/href">https://medium.com/media/8e95e7b8fa2ebfc918e131b9675a441c/href</a></iframe><p>Since both Retrofit &amp; Room work with objects, there’s no reason to implement a parser anymore. We will let Retrofit take care of the parsing when a new network request comes in.</p><p>Next, we need to make an implementation of our RoomPersister. Notice how the read function returns a List&lt;User&gt; while the write function is only writing a single user each time.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/967502621fc90ffdbffd01adc2406130/href">https://medium.com/media/967502621fc90ffdbffd01adc2406130/href</a></iframe><p>You can of course change what the read and write functions return. As another example, you might want to write a collection or return a single item — the choice is up to you.</p><p>Now that we have our Fetcher &amp; Persister, we can create an implementation of a StoreRoom:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/26f3b5feeadd404430445fe72bbe7cbe/href">https://medium.com/media/26f3b5feeadd404430445fe72bbe7cbe/href</a></iframe><p>Voila! All the functionality we always had with Stores but rather than being backed by a file persister we are now backed by a Room DAO.</p><p>Want to get data but don’t care about the source? Call store.get(). Need to bust through your cache and call network only? Call store.fresh()</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0502796e7e698bb8dbb7f37eda175429/href">https://medium.com/media/0502796e7e698bb8dbb7f37eda175429/href</a></iframe><p>So far this feels just like a normal Store. What do we gain by using Room besides ability to query &amp; have different read/write types? Reactive reads, that’s what!</p><p>Since Room can expose data as Flowables, StoreRoom will expose endless reactive streams from your get and fetch calls. For example, if you call store.get() and subscribe to the results, anytime another call is made to your stores’ get or fetch method, your subscriber receive an updated value.</p><p>With StoreRoom we not only have disk and memory caching but we now have endless observables that will auto update subscribers if the underlying data we are querying for changes. Particularly in the above example every new user that gets fetched from the network and saved to the DB will cause an emission of all the users to any current subscribers.</p><p>Store and Room are a match made in heaven, Room is inherently reactive as the use case above demonstrates while Store gives you memory that sits on top of those DB requests and missing features like request throttling when you request the same data in parallel from various parts of your app (Think of reading the same config value N times on app start without having to hit your network or db more than once). As always with Store, new subscribers to Store.get() don’t need to go all the way to your DB if your memory cache has not expired. This leads to my ideal data workflow of fast reads from memory and reactive reads from disk all backed by a network source.</p><h3>What’s next</h3><p>I hope you enjoy using our new StoreRoom and RoomPersisterthat our s23NYC team is contributing back to Store. Next, we hope to work towards an annotation processor that would auto generate the above Store code from a Room DAO. As always community help is appreciated!</p><p>Resources:</p><p><a href="https://github.com/NYTimes/Store">NYTimes/Store</a></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FTvsOsgd0--c%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DTvsOsgd0--c&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FTvsOsgd0--c%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/27beb34e1b6bc5d934414d3f1905e28c/href">https://medium.com/media/27beb34e1b6bc5d934414d3f1905e28c/href</a></iframe><ul><li><a href="https://medium.com/androiddevelopers/7-steps-to-room-27a5fe5f99b2">7 Steps To Room</a></li><li><a href="https://medium.com/google-developers/room-rxjava-acb0cd4f3757">Room 🔗 RxJava</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a8d6391bccb7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/s23nyc-tech/storeroom-a8d6391bccb7">Store+Room — A Reactive Repository</a> was originally published in <a href="https://medium.com/s23nyc-tech">S23NYC: Engineering</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[MVP & Lifecycles & Dispatchers Oh My!]]></title>
            <link>https://medium.com/s23nyc-tech/mvp-lifecycles-dispatchers-oh-my-19eda37a1a52?source=rss-6ebfb5fe99f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/19eda37a1a52</guid>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[nike]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[rxjava]]></category>
            <dc:creator><![CDATA[Mike Nakhimovich]]></dc:creator>
            <pubDate>Wed, 13 Dec 2017 20:06:19 GMT</pubDate>
            <atom:updated>2017-12-13T20:06:19.949Z</atom:updated>
            <content:encoded><![CDATA[<p>Recently Brian Plummer and I started working at Nike. After a chance to settle in, we were tasked with creating a library that would be used across a variety of Nike’s Android apps, particularly my favorite Nike app <strong>SNKRS</strong>.</p><p>At a high level, the task was to create a flow that a user can navigate through. <strong>We chose to go with a single Activity architecture backed by MVP with lifecycle-aware presenters and a reactive dispatcher of state changes. We wrote our library completely in Kotlin. </strong>In this article we will explain how we did it.</p><p>Like all architectures, this one is still a work in progress but nonetheless we wanted to share our thought process. This architecture allowed us to build an augmented reality flow encapsulated in a single activity with six screens and presenters . In the past we have always ended up with a tightly coupled mess with presenters injected into each other or views nested in an unscalable way. This time we were able to build a reactive architecture where each presenter and view reacts to new state from a centralized dispatcher. As a result, we achieved our goal by decoupling our views and presenters.</p><p>We have always been big fans of MVP. It is the architecture that always seemed easiest to explain to a new dev:</p><ul><li>When a view inflates, it creates an instance of a presenter and attaches to it.</li><li>Whenever the view needs to interact with anything but its own layout it calls a function on the presenter and then waits for a response through a view interface.</li><li>Presenters don’t have any Android framework code in them and can be easily tested in the JVM using a test implementation of the view interface.</li></ul><p>Here’s an example of a non lifecycle-aware view and presenter:</p><p><strong>View Interface</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/806319244e3b3d8b3fb0c8838db49d32/href">https://medium.com/media/806319244e3b3d8b3fb0c8838db49d32/href</a></iframe><p><strong>View implements our interface and attaches to our presenter</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6704dfa9eaae801cf878bdf069829504/href">https://medium.com/media/6704dfa9eaae801cf878bdf069829504/href</a></iframe><p><strong>Presenter</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9fb68a5bc35d39b0c73b4c78c0598ed8/href">https://medium.com/media/9fb68a5bc35d39b0c73b4c78c0598ed8/href</a></iframe><p>Since presenters are in non Android land, we need to call presenter.attachView and presenter.detachView as the presenter has no idea when the view is inflated or deflated. If we do not call detach we risk leaking memory when a presenter is bound to a long running operation.</p><p>Our mvpView can be an activity, fragment or view. Its main purpose is to implement an interface that the presenter will use to tell the view what to render. If I were <a href="https://hackernoon.com/presenters-are-not-for-persisting-f537a2cc7962">writing this a year ago</a>, I’d say, “We have a nice presenter here!” but this is the year 2017 (almost 2018!) and we now live in a world where lifecycle-aware components are a thing, most importantly SupportActivity implementing LifeCycleOwner. Since Activities are a LifecycleOwner and views are able to get a reference to their containing activity, we made the decision to have our presenter attachView function take in a lifecycle and register with it.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2934077de9905214791cdd3c7f8b1622/href">https://medium.com/media/2934077de9905214791cdd3c7f8b1622/href</a></iframe><p>This was made possible by having our Presenter implement LifecycleObserver.</p><p>Now that our Presenter is listening to the activity’s lifecycle, we can have our detachView listen for our activity’s ON_PAUSE lifecycle which means we never have to call it explicitly. It is nice to have this auto detachthat we won’t need to remember to call from a view.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/91a548146e45c475719f0a94488f3a94/href">https://medium.com/media/91a548146e45c475719f0a94488f3a94/href</a></iframe><p>Now, our views no longer need onDetachFromWindow as our presenter can detach the view from themselves. The general flow of our UI will be:</p><ul><li>Activity is created</li><li>Activity inflates its views</li><li>Each view creates a presenter and attaches itself.</li><li>The presenter requests any necessary data and passes it to the view.</li><li>When our activity is paused our presenter will detach the view from itself preventing memory leaks.</li></ul><p>We now have a NoNetworkView that — you guessed it! — we want to show anytime we have problems with network connectivity. We will need to show our NoNetworkView anytime someone loses connectivity, regardless of which screen they are on. What we did NOT want to do is inject the NoNetworkPresenter into any other view/presenter that can show noNetwork since we felt that this will eventually lead to a circular dependency if, for example, the SuccessPresenter needs to be able to call the NoNetworkPresenter, which in turn needs to be able to call something on the SuccessPresenter. Instead, we want to leverage RxJava and have each of our presenters react to a state change that will tell them whether to render or hide their UI. What we did was make a reactive dispatcher for our presenters to listen to. Here’s what the API from our presenter looks like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8f43d8a902ba7e8a5defe14980e2c349/href">https://medium.com/media/8f43d8a902ba7e8a5defe14980e2c349/href</a></iframe><p>In the example above, our presenter is listening to a stream called noNetwork . When an event is emitted, it tells its view to render itself.</p><p>Similarly, the presenter listens for the inverse of our event, which is really any other showing event, and hides its view.</p><p>Let’s take a look at our dispatcher next.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d34f97d602a52f406ca45d105ed7d553/href">https://medium.com/media/d34f97d602a52f406ca45d105ed7d553/href</a></iframe><p>Our dispatcher has a few functionalities:</p><ul><li>We can use it to dispatch a new state which tells a screen to do something. For example, dispatcher.dispatch(State.ArTargetFound) will tell our AR presenter to display a found button.</li><li>We can use it to dispatch a new state that needs to show a new Screen. dispatcher.dispatchShowing(Showing.NoNetwork) sends a new showing state to anyone observing the dispatcher. This state change is also added to our showEvents stack. (We’ll come back to this in a minute).</li><li>Presenters can then listen for a particular state change (with an associated payload) and react accordingly. For example the no network view can be listening to dispatcher.noNetwork()</li></ul><p>The landing view can be listening to dispatcher.showingLanding.subscribe()</p><p>We used Kotlin sealed classes to represent the different states that we can dispatch. Using sealed classes allowed us to represent some states as objects while others can be data classes that carry a payload.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3b4be597be594d0c1650187691c6c750/href">https://medium.com/media/3b4be597be594d0c1650187691c6c750/href</a></iframe><p>Using a state dispatcher allowed us to decouple our presenters from each other, which meant we did not need to nest presenters into each other or have complicated logic that defines when views should be shown or hidden. Each presenter will listen for events that they need and also listen for the ones that they should be closing on. Take a look at what happens when our ARCamera attaches to its presenter:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ad1846c15251707dea1f726ac4d54e9e/href">https://medium.com/media/ad1846c15251707dea1f726ac4d54e9e/href</a></iframe><p>At the same time that the ARView is visible, we might want to show an overlay or some additional controls. We can accomplish this with an OverlayPresenter that listens for similar events:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4111a3607650b866a7250fb324544d2e/href">https://medium.com/media/4111a3607650b866a7250fb324544d2e/href</a></iframe><p>The overlay presenter might also care about other states, so it can react to those as well:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d7bb2784e6667ff6f59af7c1b51b4aa7/href">https://medium.com/media/d7bb2784e6667ff6f59af7c1b51b4aa7/href</a></iframe><p>The last part of our architecture is to add all our various views to a single layout with visibility:invisible so that they can all be inflated when our activity starts. This in turn calls each presenter’s attachView function which will then subscribe to any events that the view needs to react to. As a user flows through our AR Activity we show and hide views based on states changes that are dispatched. When one of our lucky users finds an AR target in the wild, we can resolve their location and then dispatch a State change that will drive which screen is shown next:</p><p><a href="https://gist.github.com/digitalbuddha/48a7758f68ef4b4a323d18f1d03dfe2d">https://gist.github.com/digitalbuddha/48a7758f68ef4b4a323d18f1d03dfe2d</a></p><p>Check out how simple our Success and Failure Presenters are:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/43bdb93ce8bc0341aefdeb86aa17d77b/href">https://medium.com/media/43bdb93ce8bc0341aefdeb86aa17d77b/href</a></iframe><p>The only remaining piece is dealing with backstack. Any view/activity/presenter can call dispatcher.goBack() which will dispatch the last showingState prior to the current one, which should both make your view disappear and another view appear. If there are no more showing states on our backstack we dispatch a State.BackStackEmpty which our activity listens for:</p><p><a href="https://gist.github.com/digitalbuddha/973cfe4edd5052e76cfc9572b36b201b">https://gist.github.com/digitalbuddha/973cfe4edd5052e76cfc9572b36b201b</a></p><p><strong>ContainingActivity:</strong></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/51a0d16c24055d19c48bae2efe3990e5/href">https://medium.com/media/51a0d16c24055d19c48bae2efe3990e5/href</a></iframe><p>Just like the regular Android backstack, our dispatcher backstack is abstracted away from our views. No view should know what happens when it is finished — all it knows is that it gets shown or hidden. What’s nice about this is that we record each state change along with its payload into a single Stack structure called showEvents. A view doesn’t need to know if it’s being displayed for the first time, or being resumed by a backstack traversal. Incidentally, our state changes are Kotlin data classes with payloads that will be pushed with each state when you go back in reverse.</p><p>So that’s our new Friendly MVP! It works for us and we hope it works for you as well. Next post we will dive into how we implemented Augmented Reality with targeting and 3D models in under a month with the help of….a JavaScript library (gasp!)</p><p>Here’s a gist of some base classes to get you started. We hope to roll this into a library once it is more ironed out.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2fc0168a41e72b7df9c4bca28912aaaa/href">https://medium.com/media/2fc0168a41e72b7df9c4bca28912aaaa/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9ea1cdd6acc5e31fb72cde98700d7910/href">https://medium.com/media/9ea1cdd6acc5e31fb72cde98700d7910/href</a></iframe><p>Like solving interesting problems in novel ways? We’re hiring at Nike’s Digital Innovation Lab located in the heart of the flatiron district. contact me at <a href="/service/mailto:mike.nakhimovich@nike.com">mike.nakhimovich@nike.com</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=19eda37a1a52" width="1" height="1" alt=""><hr><p><a href="https://medium.com/s23nyc-tech/mvp-lifecycles-dispatchers-oh-my-19eda37a1a52">MVP &amp; Lifecycles &amp; Dispatchers Oh My!</a> was originally published in <a href="https://medium.com/s23nyc-tech">S23NYC: Engineering</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A11y & Android Things: Easy as Raspberry Pi]]></title>
            <link>https://medium.com/@theMikhail/a11y-android-things-easy-as-raspberry-pi-b943812a3098?source=rss-6ebfb5fe99f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/b943812a3098</guid>
            <category><![CDATA[hackathons]]></category>
            <category><![CDATA[raspberry-pi]]></category>
            <category><![CDATA[accessibility]]></category>
            <category><![CDATA[android-things]]></category>
            <category><![CDATA[gdg]]></category>
            <dc:creator><![CDATA[Mike Nakhimovich]]></dc:creator>
            <pubDate>Sat, 24 Jun 2017 22:44:12 GMT</pubDate>
            <atom:updated>2017-06-25T01:14:02.979Z</atom:updated>
            <content:encoded><![CDATA[<p>On June 3 and 4, we teamed up with the <a href="https://www.meetup.com/gdgnyc/">NY Chapter of the Google Developer Group</a> to host a <a href="http://a11y-hack-2017.splashthat.com/">hackathon</a> at Google’s Chelsea Market location focused on accessibility and IoT. Ten teams comprised of forty hardware and software hackers came out to try their hands at hacking on a Raspberry Pi running <a href="https://developer.android.com/things/hardware/raspberrypi.html">Android Things.</a> The main goals of the event were to:</p><ul><li>Give developers with little hardware experience a chance to check out the new Android Things platform, including Android engineers with little hardware experience (i.e. the organizers) and hardware engineers new to Android</li><li>Get creators thinking about some of the possibilities offered by IoT for less able bodied individuals</li><li>Contribute to building the NYC developer community</li></ul><p>The event brought people with a range of experience levels together to experiment with the Android Things platform. Participants included professionals with 20 years of experience as well as current bootcamp students and recent grads. Several teams came from the Android program at <a href="http://www.c4q.nyc/">Coalition for Queens</a>.</p><p>Teams were tasked with coming up with an IoT product that would address a real-world accessibility problem and were given two days to code a solution. Teams each received a Raspberry Pi with Android Things, a Rainbow HAT, and an accessory kit with a breadboard. Having both the Rainbow HAT and the accessory kit was great because it gave hardware newbies a chance to build something impressive with the HAT, and the more seasoned techies could tackle more custom projects with the breadboard. Thank you Dave Smith and the rest of the IoT team for the generous donations of 15 kits!</p><h3><strong>Preparation</strong></h3><p>Because the teams would have a limited amount of time to get familiar with the platform and then code something, we wanted to get some setup done in advance. Two days before the event, we flashed the Android Things OS onto the SD cards of all the Raspberry Pis following these instructions: <a href="https://developer.android.com/things/preview/index.html">https://developer.android.com/things/preview/index.html</a>.</p><p>We used a program called <a href="https://etcher.io/">Etcher</a>, which gave us a drag and drop interface for moving the ROM onto the device. We also deployed a sample app to make sure we’d be able to help the teams. We deployed Mike Wolfson’s <a href="https://github.com/mwolfson/AndroidThings_RainbowHatDemo">sample app</a> which was great because it hit all of the lights on the HAT, so it also confirmed that all the peripherals were working. Word of warning if you’re doing this yourself: When deploying a sample make sure you change the version number of anything Android Things related to the version of the things SDK you are using. So in our case we needed to change lines like following to use version 0.4</p><h3>Kickoff</h3><p>The event kicked off with a keynote presentation from Mark Murphy, author of the <a href="https://commonsware.com/Android/">Busy Coder’s Guide to Android Development</a>, who served up some sage advice on how to think about a good project idea.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LIAm50dSiCeKqdyZpWfncg.jpeg" /><figcaption>Mark Murphy Sharing Project Ideas</figcaption></figure><p>We divided teams into groups of 4 and gave an hour for brainstorming then teams got down to business for a 2 day hackathon.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KMi__4q-Mu6oYU2YTgm7_A.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jW2a4NnJqgyZond5dNXWsw.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8Rb-w--X1INz5AEH1wUJsA.jpeg" /></figure><h3>Take Aways:</h3><p>What Went Great:</p><p>The Rainbow HAT is a really fantastic addition to the Pi. We had developers who had never coded before up and running in under an hour.</p><p>Raspberry Pi kit <a href="https://shop.pimoroni.com/products/pibow-for-raspberry-pi-3">cases</a> were also amazing. They were easy to put together the right way, forgiving if put together the “wrong” way, and good to put together as a team building exercise.</p><p>The available sample apps in Google’s documentation were easy to follow and gave a great starting point.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/768/1*WS8ngKdT_mfCkaQZCKMZdg.jpeg" /></figure><p>Lessons Learned:</p><p>Setting up WiFi on-site was a bust. We’re not sure if it was the network type or that the network was public, but we could not get any Pi’s connected to the WiFi. Fortunately we had backup ethernet cables to connect the Pi’s directly to computers and were able to share WiFi over ethernet. For future events we’ll plan to do a test run on-site to confirm everything works as expected.</p><p>While fine for prototyping the temperature sensor does not give an accurate reading due to being located on top of the Pi (which gives off heat).</p><p>Apps needed to be uninstalled or crashes happened. We noticed that if you install sample A and then install sample B without stopping sample A, the Pi will crash with a “sensor already in use” error. This meant we needed to make sure to press the stop button or kill each running app from ADB prior to installing a different one.</p><h3>The Results</h3><p>By 4pm on Sunday we had 8 teams ready to present their projects to our panel of 4 judges:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3DzXnD8CALyzdJAqEHjBGA.jpeg" /></figure><p>And the winners were:</p><p>First places — <a href="https://docs.google.com/presentation/d/1E0xOKvbLxBUG_1BxYdTZu76V_ZdHDloPBBgw0t8-WmE/edit#slide=id.p">Emotionalize</a>:</p><p>Emotionalize aims to make it easier for nonverbal individuals to communicate how they’re feeling to others. It consists of an emoji-based Android app that the nonverbal person can use to identify their current emotional state, plus a wearable Pi that displays their current emotion on their person using associated colored lights or text. There are currently tools that facilitate communication between nonverbal individuals and others, but they rely on talkback or both individuals looking at the same screen. Emotionalize improves this process by providing an instant visual indicator of how the person is feeling that is wearable and easy to see.</p><p>Second place — Smart MTA Elevator</p><p>Based on the recent NYTimes op-ed, “<a href="https://www.nytimes.com/2017/03/29/opinion/new-york-has-a-great-subway-if-youre-not-in-a-wheelchair.html?mcubz=0">New York Has a Great Subway, if You’re Not in a Wheelchair</a>” by Sasha Blair-Goldensohn, the team worked on building a system to collect the real-time status of station elevators. The solution consisted of an Android Things device to retrofit the MTA’s existing elevators with “smart” capabilities, a real-time monitoring dashboard for the MTA, and an elevator status API for transit apps. The Android Things device detects every time the elevator travels between different levels and sends a notification of that event to a Firebase database. Using the dashboard, the MTA could spot lower than normal usage of an elevator, which could indicate a problem, and send a technician to investigate before the elevator completely breaks down. The team chose to provide an API so transit apps could include up-to-date elevator status information in their trip planner results, because this information is very much a part of trip planning and shouldn’t require a separate app to find it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ju2JGlODghnZk-J9oR0Xmw.jpeg" /><figcaption>The Two Winning Teams</figcaption></figure><p>The winners and runners-up each took home a digital copy of the Busy Coder’s Guide to Android Development. Two lucky raffle winners also each took home a copy of the Big Nerd Ranch Guide to Android Development.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/688/1*BIIuSVizOB0F50a_hDWL_w.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*78BmwmvA3E13QQ5vJDhX7g.jpeg" /></figure><h3>Thank Yous</h3><p>Thank you to our sponsors Google, NY Times, Friendly Robot, Commonsware &amp; Big Nerd Ranch and co-host the <a href="https://www.meetup.com/gdgnyc/">Google Developer Group</a>, NYC.</p><p>And to our wonderful volunteers (not all pictured)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/972/1*lulIUFf1canZHtxWX5JHdQ.gif" /></figure><p>Check out the rest of the photos of a wonderful weekend! <a href="https://goo.gl/photos/9re98sgCckSxQ2Mx7">https://goo.gl/photos/9re98sgCckSxQ2Mx7</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b943812a3098" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing the Apollo Android GraphQL client]]></title>
            <link>https://medium.com/apollo-stack/launching-apollo-graphql-on-android-40ee0b5789bd?source=rss-6ebfb5fe99f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/40ee0b5789bd</guid>
            <category><![CDATA[apollo-client]]></category>
            <category><![CDATA[graphql]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[rxjava]]></category>
            <category><![CDATA[google-developer-expert]]></category>
            <dc:creator><![CDATA[Mike Nakhimovich]]></dc:creator>
            <pubDate>Mon, 17 Apr 2017 00:05:19 GMT</pubDate>
            <atom:updated>2017-04-18T18:42:46.929Z</atom:updated>
            <content:encoded><![CDATA[<h4>Version 0.3 just released: Try it out!</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-IFErNUtG6-6e_Fb2u0teA.png" /></figure><p>The entirety of my Android career has been spent hitting RESTful APIs. No matter the app, the general setup was the same: Using get/post/delete with a predefined set of endpoints in a RESTful api. Recently, The New York Times started looking at other ways to transfer data between our servers and clients. One of our current problems is that we have a team dedicated to creating templates and endpoints for all of our mobile clients on Android and iOS. As a result, we had quite a few permutations of data feeds to manage, including: Android tablet, Android phone, iOS phone, etc. This meant that any time we wanted to request a different set of data, like new language for an article, we had to wait for one of our teams to make another template and endpoint. As you can imagine, this became <strong>inefficient</strong>.</p><p>Ideally, we needed a way for each client to request or <strong>query</strong> the data that they need without having to change anything on the server. If one Android phone needs small crops of images while another Android phone needs large crops, we should be able to use the same article API to fulfill the request. Of course, a single variation between different requests can be accomplished with request params but that didn’t quite fit our use case. We request up to 200 fields for any given article. 90% of the fields are not required for all articles, and a third of them have some special configuration. It would be nice to get only the necessary fields on a per request basis.</p><h4>Choosing GraphQL</h4><p>It became clear that REST is not the right tool for the job. We dug around for other options and landed on the GraphQL spec created by Facebook. For those that are unfamiliar, GraphQL is a query language for domain driven requests from a client to a server. Here’s a simple example from the front page of <a href="http://graphql.org/">graphql.org</a>:</p><p>Describe your data by making a schema:</p><pre>type Project {<br>  name: String<br>  tagline: String<br>  contributors: [User]<br>}</pre><p>Ask for what you want by writing a query:</p><pre>{<br>  project(name: &quot;GraphQL&quot;) {<br>    tagline<br>  }<br>}</pre><p>Get predictable results:</p><pre>{<br>  &quot;project&quot;: {<br>    &quot;tagline&quot;: &quot;A query language for APIs&quot;<br>  }<br>}</pre><p>The way that GraphQL works is that you have a pre-defined schema of all the things a client can request. Then, clients can make a query which asks for only the fields that they need. The query is posted to a server which executes that query, pulling from any backends or databases to retrieve exactly the data the client asked for.</p><p>So a query like {a, b, c} returns {a: 1, b: 2, c: 3}. Or, you can query {a, c} and get back only {a: 1, c: 3}. This seemed perfect for us, and there was only one problem - there didn’t seem to be any clients for Android. After trying to create our own implementation internally, we realized why one didn’t exist yet: The GraphQL specification has a lot of things to implement, including fragments, union types, mutations, custom fields, nullable types, etc. Working in a statically typed language where reflection is expensive did not make anything easier.</p><h4>Working with the community</h4><p>Rather than creating something internally, we felt that the community as a whole would benefit from an open source GraphQL client. So we looked around for anyone else that might have the same needs. Through an Android Slack, I was connected with Felipe Lima from Airbnb who told me about Apollo GraphQL, a rather robust client implementation, first in <a href="http://dev.apollodata.com/react/">JavaScript</a> and recently also in <a href="http://dev.apollodata.com/ios/">Swift for iOS</a>. He said that he had worked a bit with them trying to bootstrap an Android version together. We ended up taking a call, and tried to figure out what direction to go to start working on a GraphQL client for Android. After looking around a bit more we found another partner, Shopify, who had a developer also interested in creating an Apollo Android client. The base contributor team had been formed.</p><p>Five months, 200+ commits, and 13 contributors later, we have released <strong>version 0.30</strong>, which is the first version ready for public consumption. While there might be a few minor API changes we are feature complete for 1.0.</p><h4>What is Apollo Android?</h4><p>Apollo Android is a GraphQL compliant client library that generates Java models from standard GraphQL queries. These models give you a typesafe API to work with GraphQL servers. Apollo will help you keep your GraphQL query statements together, organized, and easy to access from Java. Here are some of the features you get:</p><p><strong>Code generation: </strong>You can just change a query and recompile your project, and Apollo codegen will rebuild your data model. Code generation also allows Apollo to read and unmarshal responses from the network without the need of any reflection (<a href="https://github.com/apollographql/apollo-android">see the README for an example</a>).</p><p><strong>Network calls and caching:</strong> Apollo-Android also includes a runtime to execute queries and cache the results. The client can be configured with three levels of caching:</p><ol><li>HTTP response cache: This stores raw HTTP responses.</li><li>Normalized disk cache: This does per-node caching of results in SQL.</li><li>Normalized in memory: This is an optimized Guava in-memory cache.</li></ol><p><strong>RxJava: </strong>We have included RxJava wrappers to work with RxJava 1 and RxJava 2.</p><p><strong>Optionals: </strong>Optional support is here as well. We work with Guava Optionals, Java optionals or our own shaded version. We are 100% ProGuard compatible with no configuration.</p><h4>Trying Apollo Android in your app</h4><p>Check out the <a href="https://github.com/apollographql/apollo-android/blob/master/README.md">example in the README</a>. The majority of your interactions will look something like:</p><p><strong>Step 1:</strong> Add a query to your project:</p><pre>query FeedQuery($type: FeedType!, $limit: Int!) {<br>  feed(type: $type, limit: $limit) {<br>    comments {<br>      id<br>    }<br>    postedBy {<br>      login<br>    }<br>  }<br>}</pre><p><strong>Step 2:</strong> Compile your project to get generated code for the query.</p><p><strong>Step 3:</strong> Interact with the generated type safe QueryBuilder and response:</p><pre>apolloClient.newCall(FeedQuery.builder()<br>    .limit(10)<br>    .type(FeedType.HOT)<br>    .build())<br>    .enqueue(new ApolloCall.Callback&lt;FeedQuery.Data&gt;(){<br>        public void onResponse(Response&lt;FeedQuery.Data&gt; response) {}<br>        public void onFailure(@Nonnull Throwable t) {}<br>     });</pre><p>or the RxJava version</p><pre>Rx2Apollo.from(apolloClient<br>                  .newCall(FeedQuery<br>                  .builder()<br>                  .limit(10)<br>                  .type(FeedType.HOT)                 <br>                  .build()))<br>         .subscribe()</pre><p>You can also find a sample project in the <a href="https://github.com/apollographql/apollo-android/tree/master/apollo-sample">repository on GitHub</a>.</p><h4>Conclusion and thanks</h4><p>We believe we made this library simple yet powerful. A developer can go from writing a GraphQL query to being up and running in a manner of minutes. We’d love to hear from you on how to make Apollo-Android better, and we’re currently working on a roadmap of features for the coming months.</p><p>It was incredible to work with talented developers from various companies to create an open source project. I’d like to recognize the main contributors on the project:</p><ul><li><a href="https://github.com/sav007"><strong>Ivan Savytskyi</strong></a>, who was by far the top contributor, main developer of the code generation through a few rewrites, and generally an awesome guy. This project would not be a reality without the insane amounts of time he put in.</li><li><a href="https://github.com/felipecsl"><strong>Felipe Lima</strong></a> for getting the project off the ground.</li><li><a href="https://github.com/BenSchwab"><strong>Ben Schwab</strong></a> for implementing the caching layer and countless other things.</li><li><a href="https://github.com/martijnwalraven"><strong>Martijn Walraven</strong></a> from the Apollo team for offering us guidance, check out his iOS library <a href="https://github.com/apollographql/apollo-ios">here</a>.</li><li><a href="https://github.com/marwanad"><strong>Marwan Ahmed</strong></a> for creating the Gradle plugin to run our code generation.</li><li><a href="https://github.com/VisheshVadhera"><strong>Vishesh Vadhera</strong></a> for giving a big helping hand in documentation.</li></ul><p>Learn more about the project and contribute on our <a href="https://github.com/apollographql/apollo-android">GitHub repository</a>!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=40ee0b5789bd" width="1" height="1" alt=""><hr><p><a href="https://medium.com/apollo-stack/launching-apollo-graphql-on-android-40ee0b5789bd">Introducing the Apollo Android GraphQL client</a> was originally published in <a href="https://medium.com/apollo-stack">Apollo GraphQL</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Presenters are not for persisting]]></title>
            <link>https://medium.com/@theMikhail/presenters-are-not-for-persisting-f537a2cc7962?source=rss-6ebfb5fe99f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/f537a2cc7962</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[android-app-development]]></category>
            <dc:creator><![CDATA[Mike Nakhimovich]]></dc:creator>
            <pubDate>Sun, 22 Jan 2017 01:33:22 GMT</pubDate>
            <atom:updated>2017-07-14T22:05:27.948Z</atom:updated>
            <content:encoded><![CDATA[<p>Yesterday I tweeted something that lead to quite a bit of confusion:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*d9SGfydk8F2xI0_hj5dslg.png" /></figure><p>100 replies later ranging from questions to anger and I figured I owe a blog post. The statement above came out of an ASG discussion about how everyone seems to use Presenters differently, particularly when it comes to configuration changes during or after a data fetch. It seems like we all are trying to solve the same problems but in different ways:</p><ul><li>Activity/Fragment/View needs to be able to request data</li><li>There needs to be a mechanism to cache the data so that on rotation you do not need to hit the network again</li><li>Similarly, you should be able to maintain your state after rotation, such as scroll position.</li></ul><p>In this article I’ll be going over my preferred way to structure a data driven application.</p><p>Some shocking points I’ll be making and explaining along the way:</p><ul><li>Presenters should be owned by the Activity/Fragment/View and destroyed/recreated on rotate</li><li>Singleton data providers request and own your data</li><li>State should be kept minimal and saved/restored on rotation</li></ul><p>Let’s setup a common use case that something like a Reddit client would have: MainActivity allows a user to enter a subreddit name. It then calls the Reddit API and shows a list of posts for the particular subreddit. If a particular post in the results is selected, you will go to a CommentActivity which will hit another endpoint and show the comments for the post. To make the example a little more complicated we will have the CommentActivity contain a fragment that shows comments. Some pain points that we should all be aware of:</p><ul><li>If a user submits a request for a subreddit and then rotates mid request, you need to be able to keep the request going rather than making a new one, especially if it is an expensive network call like getting 100 posts.</li><li>We need to be able to pass data between the 2 Activities. Because our CommentsActivity contains a CommentsFragment, we need to be able to pass data between the activity and fragment or allow the fragment to request its own data.</li><li>If we are on the CommentActivity and rotate, we need to be able to restore the proper comments (and maybe the scroll position as well)</li></ul><p>Here’s how I would approach the above (with explanations of design decisions)</p><p>User enters a subreddit name and then clicks on search:</p><p>Activity has an injected Presenter and will call</p><pre>presenter.getPostsFor(subredditName)</pre><p>The Presenter has 2 jobs: requesting new data from a data provider/repository/store and then passing that data back to the View (an Activity in this case). Using the simplest approach possible we can inject a network client like Retrofit to our presenter which will act as a data provider and request data from it.</p><pre>public void getPostsFor(String subredditName) { <br>subscription = redditApi.getPosts(subredditName)<br>.subscribe(posts -&gt; getMvpView().showPosts(posts), <br>           throwable -&gt; getMvpView().showError()); }</pre><p>The activity then implements these:</p><pre>void showError();    <br>void showPosts(List&lt;Post&gt; posts);</pre><p>Something that I do that may be different from others is that I make my View own my Presenter. By that I mean the Presenter dies any time an Activity dies. New Activity after rotation means we will have a new Presenter for that instance of the Activity. Think of the Presenter as having the same scope as an instance of an Activity.</p><p>What we currently have is a Presenter that acts as the go between our View and our data, the View doesn’t know or care where the posts come from. All it knows is that it needs to request Posts and have callbacks to properly handle when those posts (or an error) are returned. Views (Activity in our case) only care about requesting or showing data while request and subscription implementations live in a Presenter.</p><p>Next we need to discuss how we can have a request survive a configuration change. To recap: when a user rotates their device while fetching a new subreddit, we want to show the response after rotation without having to make a second request to the network. There seem to be two schools of thought about how this should work.</p><ol><li>The first approach is that we can make our Presenter a singleton which will make it live on a higher scope; or</li><li>We make a singleton data provider that lives on a higher scope and caches our data</li></ol><p>Let’s start by examining the first option. Some suggest that you should make your Presenters singleton or app scoped. This way when you rotate and have a new instance of an activity, you rebind to the same singleton Presenter. The presenter can then own the data and pass it back to the view rather than going to the network a second time.</p><p>This adds a bit of complexity, as the Presenter now needs logic for checking if “a request is in flight” before making another request. To me this feels like too much responsibility for a Presenter. In my opinion, Presenters are the middlemen. They request data, they hand it of,f but they shouldn’t be fat or keep data. Another disadvantage to this approach is that many presenters can be holding/retaining the same exact data. What if the MainPresenter and CommentPresenter both want to request a list of Posts, will there be duplicated data within their Singleton Presenters?</p><p>I think we can do better. It sounds like all we need to do is cache our data and in-flight requests somewhere that is not scoped to a single Activity. If we can have an abstraction that survives configuration changes, we can recreate our Presenter and then request the same data a second time.</p><p>Instead, I’d propose using data stores which abstract away data loading. Rather than the presenter needing to cache the data, we can leverage the Repository pattern and create Data Providers/Stores that can get data from the network and cache it for when we need it. For one thing, this approach makes it easier to persist your data. Another advantage is that we have a single source of truth for our data. Finally, wew can eliminate things like Interactors and just have your Presenter subscribe to your Stores whenever they need something for a view.</p><p>so</p><pre>redditApi.get(subredditName)</pre><p>becomes</p><pre>redditStore.get(subredditName)</pre><p>where the store is a singleton (preferably managed by Dagger) and takes care of requesting new data, caching that data and dealing with in flight request management.</p><p>Now when you rotate, the Presenter can simply inject the same singleton Store and re-request data which can piggyback on an inflight request or get the cached data from the Store. From the Views/Presenters perspective it shouldn’t matter if the data is being requested for the first time or coming from a cache; all it needs is the data to pass to the view.</p><p>As for an implementation of this pattern, I suggest wrapping your network calls in Stores that take care of caching and in flight logic. We just open sourced our implementation of a library using this pattern at NY Times <a href="https://github.com/NYTimes/Store">https://github.com/NYTimes/Store</a>.</p><p>Let’s examine this a bit more. Views get recreated, Presenters get recreated too. The only reason I’ve seen to not recreate Presenters is because they contain data that need to survive rotation. I believe that as long as you have an identifier for your data you only need to persist/retain/maintain a singleton provider of your data rather than the entire Presenter. Having a singleton Store that can provide pre and post rotation data gives you all of the advantages of a singleton Presenter without the added weight. Thin views and presenters which talk to single responsibility stores is my preferred setup for MVP. As mentioned above, Presenters now can worry about what the View needs and getting access to it rather than worrying about things like caching and request management (let your store do that).</p><p>Rotation logic works like this:</p><ul><li>OnSaveInstanceState will save the request params if there are any.</li><li>OnCreate will inflate a layout, create a presenter and checks if there are any request params in the saved bundle. If there are, it will request data from the Presenter which will request from the Store. Since data has already been cached by the Store, you should be receiving a cached representation.</li></ul><p>If an Application gets backgrounded for a long time and needs to recreate, it will work exactly the same as in a rotation. There’s no need to save your entire presenter or data model in save/restore instance state eliminating parcel too large exceptions. Since the Store owns the data, you can use much better persistence techniques like flat files or sql lite which are not available at the UI level. Both of these storage techniques have less size constraints than an activities save restore bundle mechanism.</p><p>OK, back to our example which is now powered by a Presenter and a Store. The user enters a subreddit name, clicks on search which delegates the call to the Presenter who made a Subscription to the Store and passed back the results to the Activity. Now that the user sees posts, he clicks on one to see the comments.</p><p>We then open CommentActivity and pass it a postID within an Intent. Activity B creates a Fragment and passes the Intent Extra to it. Fragment inflates a Layout, creates/injects a CommentsPresenter and asks the Presenter for the comments for a particular post. Similar to our last Activity/Presenter, the CommentPresenter will get a reference to a singleton CommentStore which it will pass the postID to and ask for a list of comments. As in our MainActivity example if a rotation occurs the fragment will save the current PostID and restore it when the fragment gets recreated.</p><p>The CommentFragment has 2 starting states: frag args containing postID or saved state contains postID, in either case the Fragment creates a Presenter and passes the postID to it for retrieval of a list of comments. As you can see by having a Store abstraction we can keep our logic for fetching pre or post rotation exactly the same. If any other state needs to be maintained it should be minimal and saved/restored same as the request params. Since you are only ever saving/restoring states that should be just a few flags.</p><p>In conclusion I feel that the simplest way to work with data is to have an Activity/Fragment/View which owns a Presenter. That Presenter can request data from an app scoped Store which can either fetch new data or return cached data. This setup works for me and I hope it will work for you too.</p><p>Feedback is loved and appreciated.</p><figure><a href="http://bit.ly/HackernoonFB"><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0hqOaABQ7XGPT-OYNgiUBg.png" /></a></figure><figure><a href="https://goo.gl/k7XYbx"><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Vgw1jkA6hgnvwzTsfMlnpg.png" /></a></figure><figure><a href="https://goo.gl/4ofytp"><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gKBpq1ruUi0FVK2UM_I4tQ.png" /></a></figure><blockquote><a href="http://bit.ly/Hackernoon">Hacker Noon</a> is how hackers start their afternoons. We’re a part of the <a href="http://bit.ly/atAMIatAMI">@AMI</a> family. We are now <a href="http://bit.ly/hackernoonsubmission">accepting submissions</a> and happy to <a href="/service/mailto:partners@amipublications.com">discuss advertising &amp; sponsorship</a> opportunities.</blockquote><blockquote>If you enjoyed this story, we recommend reading our <a href="http://bit.ly/hackernoonlatestt">latest tech stories</a> and <a href="https://hackernoon.com/trending">trending tech stories</a>. Until next time, don’t take the realities of the world for granted!</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*35tCjoPcvq6LbB3I6Wegqw.jpeg" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f537a2cc7962" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[System Services are not just for the system]]></title>
            <link>https://medium.com/@theMikhail/system-services-are-not-just-for-the-system-ce33aab4594a?source=rss-6ebfb5fe99f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/ce33aab4594a</guid>
            <category><![CDATA[dagger-2]]></category>
            <category><![CDATA[dagger]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[gde]]></category>
            <dc:creator><![CDATA[Mike Nakhimovich]]></dc:creator>
            <pubDate>Tue, 01 Nov 2016 12:40:45 GMT</pubDate>
            <atom:updated>2016-11-01T14:41:33.529Z</atom:updated>
            <content:encoded><![CDATA[<p>I came across an interesting behavior when using Dagger and Custom Views. In most cases, my apps have 2 components. There is a top level AppComponent for Singletons and an Activity Component for anything that should be “one per activity”. Within my activities there is the normal dagger boilerplate:</p><pre>activityComponent = application.getAppComponent()<br>        .plusActivityComponent(new ActivityModule(this));</pre><p>Additionally I like to expose the activity component in a getter so that views can have access to the activity scoped objects:</p><pre>public interface ActivityComponentProvider {<br>    Activitycomponent getActivityComponent();<br>}</pre><p>within views I can then do:</p><pre>public VrView(Context context, AttributeSet attrs, int defStyleAttr) {<br>    super(context, attrs, defStyleAttr);<br>    <em>inflate</em>(getContext(), R.layout.vr_view_contents, this);<br>    ((ActivityComponentProvider) context).getActivityComponent().inject(this);</pre><p>In most cases this works but yesterday was not most case. The story started with me creating an xml layout that contains a <em>&lt;android.support.design.widget.AppBarLayout&gt;</em> tag. Inside of that I put a custom view <em>&lt;com.sample.myview&gt;</em>. Similar to the above example I added the injection code to the views constructor and ran my code and Crash. To my surprise I started getting “java.lang.ClassCastException: android.view.ContextThemeWrapper cannot be cast to android.app.Activity” errors. After a bit of digging, I was able to deduce that the problem is due to how AppCompat inflates views. Unlike regular widgets/layout groups, &lt;<em>AppBarLayout</em>&gt; children use a <em>ContextWrapper</em> to inflate child views rather than the containing Activity’s context.</p><p>The brute force solution was to call getBaseContext() on the view’s context over and over again until you get to the activity but this seemed hacky and strange. Instead I was pointed to an interesting solution on how to pass a Dagger Component from an activity to a view (Thanks Jake Wharton!)</p><p>The novel approach was to leverage an activity’s getSystemService override. Let’s go through a example.</p><p>The first thing you’ll want to do is override getSystemService in your activity.</p><pre>@Override<br>public Object getSystemService(String name) {<br>    return super.getSystemService(name);<br>}</pre><p>The context.getSystemService call normally is used to get a reference to things like the LayoutInflator. By overriding the method in your activity, you’ll now be able to return an instance of anything you want for a particular key. In our case we’d like to return the Activity component</p><pre>@Override<br>public Object getSystemService(String name) {<br>    if(&quot;Dagger&quot;.equals(name)){<br>        return activityComponent;<br>    }<br>    return super.getSystemService(name);<br>}</pre><p>Notice that we still want to call through to super if it is not the key that we are interested it.</p><p>Now within our view’s constructor we can access the activity component by calling getContext().getSystemService(key). The nice thing about this setup is that you don’t have to unwrap the context to find the activity, the system service call will do that for you.</p><pre>public VrView(Context context, AttributeSet attrs, int defStyleAttr) {<br>    super(context, attrs, defStyleAttr);<br>    <em>inflate</em>(getContext(), R.layout.vr_view_contents, this);<br>    ActivityComponent activityComponent = (ActivityComponent) getContext().getSystemService(&quot;Dagger&quot;);<br>activitycomponent.inject(this);</pre><p>Rather than making the dangerous cast from getContext to your activity, we can leverage androids system service architecture.</p><p>Finally to make Android Studio lint checker happy, add</p><pre>//noinspection ResourceType</pre><p>above</p><pre>ActivityComponent activityComponent = (ActivityComponent) getContext().getSystemService(&quot;Dagger&quot;);</pre><p>And thats it! You can now get a reference to your activity component from a view. Bonus: In a similar manner you can override getSystemService in your Application class and pass the app component from there. This would allow you to do something like</p><pre>AppComponent component = (AppComponent) getAppplicationContext().getSystemService(&quot;AppComponent&quot;);</pre><p>from your activities.</p><p>Thanks again to those that helped me grok this yesterday.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ce33aab4594a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[RxJava2: An Early Preview]]></title>
            <link>https://medium.com/@theMikhail/rxjava2-an-early-preview-5b05de46b07?source=rss-6ebfb5fe99f9------2</link>
            <guid isPermaLink="false">https://medium.com/p/5b05de46b07</guid>
            <category><![CDATA[rxjava]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[androiddev]]></category>
            <category><![CDATA[gde]]></category>
            <dc:creator><![CDATA[Mike Nakhimovich]]></dc:creator>
            <pubDate>Sat, 17 Sep 2016 15:49:51 GMT</pubDate>
            <atom:updated>2016-09-17T15:49:51.784Z</atom:updated>
            <content:encoded><![CDATA[<p>As an avid RxJava user I’ve been following the development of RxJava2 which just hit its first Release Candidate. Here are some of the most interesting updates and additions to the library and what they mean for the developer community.</p><h4><strong>New Dependency</strong></h4><p>Before going into the API differences, I want to make a note about RxJava2 having a dependency on <a href="http://www.reactive-streams.org/">ReactiveStreams</a> which is a standard for asynchronous stream processing with non-blocking backpressure. Think of ReactiveStreams as a spec for Reactive libraries to build on top of. Adhering to this standard adds the ability for interpolation with other Reactive Libraries.</p><h4>Imports</h4><p>RxJava2 is available in a different package than RxJava1:</p><p>RxJava1:</p><pre>compile ‘io.reactivex:rxjava:1.0.y-SNAPSHOT’</pre><p>RxJava2:</p><pre>compile ‘io.reactivex.rxjava2:rxjava:x.y.z’</pre><p>This means that you can start using RxJava2 while still using RxJava1 rather than having to fix your code to work with the breaking changes between versions. This style of packaging is similar to the versioning strategy used by Square Libraries (Retrofit2, OKHTTP3, etc.) and is great if you’re trying to run both versions. That said, if you’re instead migrating at once, this means that you will now need to change all your imports to the new package. Android Studio find/replace should mitigate most of the pain.</p><h4>Null Emissions No Longer Permitted</h4><p>RxJava2 no longer permits emitting a null value from a producer. Emitting a null value from an observable, flowable, or subject will throw a NullPointerException:</p><pre>Observable.just(null); //don’t do this</pre><pre>subject.onNext(null); //don’t do this either</pre><p>I’m personally a big fan of this change and believe that null should not exist in an API. I’ve always appreciated that Dagger throws exceptions if returning a null from a provides and am glad that RxJava is now enforcing clean code practices. There are plenty of alternatives to passing null through a stream such as: Enums, Constants, and Guava/Java8 Optional types (my favorite).</p><h4>Under (Back) Pressure</h4><p>RxJava 2 introduces a new base type called Flowable which is an Observable with backpressure support. Backpressure is when an Observable emits values faster than an Observer is able to handle. With RxJava2, Observables do not support backpressure while Flowables will support backpressure (with different strategies).</p><p>Flowables seem to have the same operators as Observables plus hooks for defining/handling backpressure. The good news is that you’ll still have all your favorite operators like map/filter, etc. The bad news is that organizing imports might now grab the wrong one. Here’s an example of creating a Flowable from the wiki:</p><pre>Flowable.create((FlowableEmitter&lt;Integer&gt; emitter) -&gt; {<br>emitter.onNext(1);<br>emitter.onNext(2);<br>emitter.onComplete();<br>}, BackpressureStrategy.BUFFER);</pre><p>This looks very similar to the current Observable.create but with the added param of how to handle Backpressure. Hopefully, making Flowable its own type will help developers consider Backpressure when designing reactive flows rather than learning about it for the first time they see it in crash logs.</p><p>The Reactive-Streams spec also mandates that all operators support backpressure (within Flowable in our case). What this means is that Operators can’t emit faster than a downstream Consumer can consume. It’s important to note that this does not mean that operators can’t have backpressure problems — it just means that they will now throw the MissingBackpressureException exception themselves rather than pushing too much through onNext. The exception will be thrown from the Operator rather than the Consumer/Subscriber.</p><h4>Single Old and New</h4><p>Single has been reengineered from the ground up and is now built on the ReactiveStreams spec. Subscribing to a Single is now done with a SingleObserver&lt;T&gt; which is an interface defining:</p><pre>void onSubscribe(Disposable d);</pre><pre>void onSuccess(T value);</pre><pre>void onError(Throwable error);</pre><pre>Subscribing to a single is done in the same way:</pre><pre>single.subscribe(onSuccess,onError);</pre><h4>Hit Me Maybe One More Type</h4><p>RxJava 2 introduces a new base reactive type called Maybe. Maybe is essentially a hybrid between Single and Completable. You can use Maybe when you have a provider that can emit 0 or 1 items. You don’t need to worry about handling backpressure because Maybe emits at most 1 item.</p><p>Maybe will offer only a subset of operators available in Flowable/Observable.</p><p>Example:</p><pre>Maybe.just(1)<br>.map(v -&gt; v + 1)<br>.filter(v -&gt; v == 1)<br>.defaultIfEmpty(2)<br>.test()<br>.assertResult(2);</pre><h4>New BackPressured Subject: Processor</h4><p>RxJava 2 introduces a new type, Processor, which is a Subject with backpressure support. AsyncSubject, BehaviorSubject, PublishSubject, ReplaySubject, UnicastSubject maintain their existing functionality from RxJava 1 and do not support backpressure. Their Processor counterparts do: AsyncProcessor, BehaviorProcessor, PublishProcessor, ReplayProcessor, and UnicastProcessor.</p><h4>New Names for Function and Action</h4><p>RxJava 2 brings new names for function interfaces: Func1 is now Function, Func2 is BiFunction and all other function interfaces in favor of Function&lt;Object[],R&gt;. Similar to Guava there will be a Predicate&lt;T&gt; for the common use case of Func1&lt;T, Boolean&gt;. Actions follow suit: Action0 becomes Consumer, Action1 is BiConsumer and ActionN becomes Consumer&lt;Object[]&gt;. (These two changes will lead to the largest amount of refactoring/migration in my apps.)</p><h4>Subscriber is Now Disposable</h4><p>Due to naming conflicts with Reactive-Streams, Subscriber has been renamed to Disposable. Disposables have a .dispose() method that’s similar to the .unsubscribe() method of Subscription:</p><pre>ResourceSubscriber&lt;Integer&gt; subscriber = new ResourceSubscriber&lt;Integer&gt;() {</pre><pre>@Override<br>public void onStart() {<br>request(Long.MAX_VALUE);<br>}</pre><pre>@Override</pre><pre>public void onNext(Integer t) {<br>System.out.println(t);<br>}</pre><pre>@Override<br>public void onError(Throwable t) {<br>t.printStackTrace();<br>}</pre><pre>@Override<br>public void onComplete() {<br>System.out.println(“Done”);<br>}<br>};</pre><pre>Flowable.range(1, 10).delay(1, TimeUnit.SECONDS).subscribe(subscriber);</pre><pre>subscriber.dispose();</pre><p>In the example above we see one more renaming change: onCompleted will now be onComplete. Yay for find/replace.</p><h4>Composite Subscriptions Changes</h4><p>Composite Subscriptions have been replaced with CompositeDisposable and a new subscribeWith method.</p><p>RxJava1:</p><pre>CompositeSubscription composite = new CompositeSubscription();</pre><pre>composite.add(Observable.range(1, 5).subscribe(new TestSubscriber&lt;Integer&gt;()));</pre><p>RxJava2:</p><pre>CompositeDisposable composite = new CompositeDisposable();</pre><pre>composite.add(Flowable.range(1, 5).subscribeWith(subscriber));</pre><p>The API change is due to Reactive-Streams .subscribe now being a void method.</p><h4>Blocking Calls</h4><p>RxJava2 provides several new operators to help with transforming asynchronous Observables into BlockingObservables. Particularly observable.blockingFirst() as a convenience observable.toBlocking.first(). Yay for less code and better performance.</p><h4>Better Hooks for Plugins</h4><p>One of my favorite changes is a rewrite of the plugin system. Now you’ll be able to override the values returned by the built in schedulers. This could be useful for overriding Schedulers.io() to return synchronous values during testing or even for making debug Schedulers that wrap the current ones inside of more logging. Way to go guys! I know this was a much clamored after and difficult-to-implement feature.</p><h4>Summary</h4><p>Overall I’m excited about the direction that RxJava is going. My favorite feature of the release is the new not null checks, which will surely lead to fewer elusive bugs. I’m also excited about the standardization with Reactive-Streams and the new Maybe and Flowable types.</p><p>With the stable release targeted for October 29, I hope everyone’s upgrades will be quick and painless. It seems like <a href="https://github.com/JakeWharton/retrofit2-rxjava2-adapter">Retrofit already has support for RxJava2</a> for those that want to be on the bleeding edge. There’s also a nice <a href="https://github.com/akarnokd/RxJava2Interop">library</a> that helps convert from RxJava1 to RxJava2 types.</p><p>A big kudos goes to David Karnok, the lead contributor of RxJava, for his work on this release. While he might not be a name that many Android devs are familiar with, he’s been a leader in pushing reactive patterns into the community.</p><h4>Sources:</h4><p><a href="http://reactivex.io/RxJava/2.x/javadoc/">http://reactivex.io/RxJava/2.x/javadoc/</a></p><p><a href="https://github.com/ReactiveX/RxJava/wiki/What%27s-different-in-2.0">https://github.com/ReactiveX/RxJava/wiki/What&#39;s-different-in-2.0</a></p><p><a href="http://stackoverflow.com/questions/38423079/differences-between-rxjava1-and-rxjava2">http://stackoverflow.com/questions/38423079/differences-between-rxjava1-and-rxjava2</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5b05de46b07" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>