Coder Thoughts on software, technology and programming.

Piotr Mionskowski

  • Handling different user types in android application

    12 July 2015 android

    In the previous post you can read how to use Session object to maintain current user information through the application lifecycle. Now we’ll explore different options of implementing varying behavior depending on user type.

    When an app has only one user type

    I find it neat when an application allows me to use it before I’m forced to create an account or sign in. In such a case there will be a, potentially very long, time where we have no way of identifying the user. At the same time we’ll want to provide as much features of an identified user as possible. There will however be cases where application behavior will be different depending on whether the user is logged in or not.

    A simple if will not do any harm, or will it?

    Let’s assume that our application allows changing preferences for both anonymous and authenticated users. When saving or reading user dependent application settings we can write a simple if statement to decide which preferences to use.

    Notice how in line 23 we do a check to decide the name of SharedPreferences to use. There’s nothing wrong with doing such a check in 1 or 2 places however this type of logic will typically spread over dozens and more places in the various parts of the code base.

    The Null Object pattern to the rescue

    Instead of relying on null checks we can use a simple pattern described in detail by Martin Fowler. Here’s how it would look like in our case:

    Now all places where we require an easily substitutable information about the user can be handled with plain old polymorphism.

    The above approach will work whenever we need a default value for the anonymous user - no so much when we need different behavior. It’s tempting to embed various actions into UserReference interface implementations (AnonymousUserReference and RegularUserReference) however this will make the mentioned interface depend on UI concepts which I would like to avoid.

    When an app has more than one user type

    Before I show how to avoid putting too much weight onto UserReference interface, let’s make our situation a bit more complicated. Let’s assume that our app can be used by three types of users: anonymous, regular and premium. A very common approach is to use an enum to handle that i.e.:

    In fact because case supports default the above implementation works well as long as we have a small number of user types and there’s little shared behavior.

    A slightly different approach is to hide the decision making and expose method(s) that accept different behaviors. The following code is an example of how we can approach encapsulating differences between user types in by explicitly declaring a behavior:

    Note that the above uses double dispatch but it could easily be replaced with a switch statement. Using separate class to encapsulate differences should make it easier to keep unnecessary logic out of Activity.

    A curious reader might notice that if we would like to change how we handle only one user type we’re still forced to override all methods. There’s a fairly simple way to improve the above though:

    Now we can implement custom actions as well as indicate a default. As usual whether to go with a simple if statement, a switch or a double dispatch depends on a use case. However it’s useful to know the different ways of tackling the same problem.

    This article is cross-posted with my company blog

  • Maintaining current user information in Android

    30 June 2015 android

    Every but trivial android application needs to maintain information about current user - regardless if he has authenticated or not. While this may sound easy there are still at least handful of ways one can do it - in this article I’m going to explore couple of them.

    Keeping state in custom Application class

    This technique boils down to having custom application class like so:

    While the above is both easy to write and understand there are several problems with it. First and foremost if you would like to get some user property you’ll need to reference MyApplication i.e.:

    Since data about current user will be used in several places spread through the code each of those places will now be coupled to MyApplication. This on the other hand will jeopardize any attempt to break the code base into modules. Furthermore this approach may encourage sharing other global application state through static variables defined on custom Application class. In short don’t do this.

    Keeping global state in User class

    A slightly better idea is to move static variables from Application class into User class itself:

    Now our Application class has one less responsibility and we don’t need smelly references spread around the codebase. We may also be able to split the project into modules - as long as we’re not too inclined to separating concerns. Problems arise as soon as you start unit testing though. Remember that good unit test should be as isolated as possible. Using global state through static methods on User class forces us to properly setUp() and tearDown() its state in every test. It would be much easier if we could properly inject information about current user through tested component(s) constructor(s).

    I mentioned separation of concerns - does a user class have any reason to know whether a user has signed in? I don’t think so.

    Separating concerns with User Session

    I find it helpful to think about objects lifetimes when designing components. In every application that allows users to sign in there will be a time where we don’t have a user object to work with. To express that property I usually store the information about current user in a Session object. There is only one user session whenever an application is running. After user signs in the session is updated to represent it. After signing out it’s usually a good idea to reset session state. Consider following example:

    Couple of things to note here. First and foremost the Session class is not public it’s local to package responsible for maintaining it’s state. Typically it’s a package dealing with user registration, sign in and keeping remote services auth tokens fresh. Secondly Session public interface only covers methods defined in CurrentUserInfo exposing methods that come handy when getting current user name. The Session object is not limited to one interface. Quite opposite it may implement more interfaces depending on different clients (components requesting various details about current user) needs.

    Since Session embraces Interface Segregation Principle it’s much easier to test code that requests information about current user i.e AppBeahvior. A reusable fake can be coded with no effort - it only has to implement very limited set of methods.

    Notice that I’ve not used static methods nor variables in above example. Instead I’ve simply marked the class with @Singleton annotation to ensure that there will only be single instance ever created, injected and used. I highly encourage using Dependency Injection frameworks (a.k.a IoC containers) with Dagger (and Dagger 2) taking the lead in Android space.

    In the next article I’m going to show a way to deal with application behavior changing depending on user being logged in or not.

    This article is cross-posted with my company blog

  • Anchor child element click

    25 January 2015 html and javascript

    I had to solve a seemingly trivial bug in an angularjs based application that turned out to be more interesting than usual.

    The bug

    The bug report stated that “Clicking on a label causes page reload”. That should be an easy one I thought to myself and openeded chrome inspector to see a structure of DOM. Here’s a simplified version of markup:

    <a  href="" ng-click="anchorAction($event)" ng-controller="ActionCtrl">
      Anchor
      <span ng-click="childAction($event)">
      A child
      </span>
    </a>
    
    module.controller('ActionCtrl', function($scope){
      $scope.anchorAction = function($event){
        console.log('anchorAction');
      };
      $scope.childAction = function($event){
        $event.stopPropagation();
        console.log('childAction');
      };
    });
    

    My intention was to have different behaviour when an anchor or a span element is clicked. Just as in the example above when a is clicked anchorAction should be printed whereas the same event triggered on span should only print childAction. Interestingly the actual behaviour is different.

    When the anchor is clicked indeed a function attached by ng-click is executed properly. Note that even though we did not call $event.preventDefault() a page reload is not triggered. This is due to htmlAnchorDirective provided by angularjs which effectively prevents empty href attribute from taking action.

    A click on span element will stop event from bubbling up document tree - thus preventing anchorAction from executing. In addition it will obviously print childAction and to my surprise it will cause a page reload.

    Wait a second didn’t we just prevent the event from traveling up to the anchor element? Yes. So why does the page reload anyway?

    Searching for a root cause.

    Almost immediately I’ve verified that calling $event.preventDefault() inside childAction fixes the problem. The fix got checked in and will be deployed soon - case closed. I was unhappy though because I didn’t understand this behaviour at all.

    At first I naively thought that it might be a Chrome bug - a quick check in FF and IE diminished this stupid idea.

    Then I thought that it may be related to angularjs in some strange manner so I’ve prepared an example fiddle that demonstrates the issue. I’ve searched for and read many answers on Stack Overflow and other forums but none of them gave an in-depth explanation.

    The HTML spec

    Since the example fiddle demonstrated same behaviour in all major desktop browsers I realised that it must be part of HTML spec - after an hour or so it turned out that it was a good hunch.

    Up until now I thought that an event (and a click event in particular) default action is dependent on an element it visits when it is dispatched through a DOM tree. In the above example it would mean that since I’ve stopped click from bubbling up it should not reach a element and because of that it should not execute its default action - in our case a page reload.

    It turned out that my assumptions about events dispatching and elements default actions were wrong.

    The relevant part of the specification describes activation behavior with an explanation of what I’ve experienced:

    1. Let target be the element designated by the user (the target of event).
    2. If target is a canvas element, run the canvas MouseEvent rerouting steps. If this changes event’s target, then let target be the new target.
    3. Set the click in progress flag on target to true.
    4. Let e be the nearest activatable element of target (defined below), if any.
    5. If there is an element e, run pre-click activation steps on it.
    6. Dispatch event (the required click event) at target. If there is an element e and the click event is not canceled, run post-click activation steps on element e. If there is an element e and the event is canceled, run canceled activation steps on element e.
    7. Set the click in progress flag on target to false.

    The most relevant steps are 4. and 6. as they clearly indicate that target and nearest activatable element that triggers default action can be separate. What’s left to have a complete understanding is how nearest activatable element is defined:

    Given an element target, the nearest activatable element is the element returned by the following algorithm:

    1. If target has a defined activation behavior, then return target and abort these steps.
    2. If target has a parent element, then set target to that parent element and return to the first step.
    3. Otherwise, there is no nearest activatable element.

    Now it is obvious why a default action of an anchor is executed even though a click event did not bubble up from its child.

    This article is cross-posted with my company blog

  • Lazy Apk - a simple TeamCity artifact downloader

    06 January 2015 android and TeamCity

    At Bright Inventions we use TeamCity as a continuous integration server. Apart from building, running tests and uploading artifacts we sometimes use it to quickly distribute an android application to clients and test team. However we found using TeamCity UI on a mobile device isn’t as pleasing as it could be. That’s why we usually recommend downloading updates through a dedicated application such as TeamCity Downloader.

    While TeamCity Downloader is really easy to use I found it lacks a couple of features I need. First of all I would like to be able to use multiple TeamCity servers at once. Moreover it would be nice to see commit messages related to particular build to streamline change communication.

    Lazy Apk - a simple apk downloader

    Since I wanted to test some of new APIs available in Lollipop I thought it would be a good idea to try them out in an application that could actually be useful. That’s why I’ve build another artifacts downloader - Lazy Apk.

    The tool allows you to configure multiple TeamCity build servers:

    Multiple sources

    As I mentioned the commit messages are visible next to each build:

    Commit messages

    Downloaded APKs are stored inside android “Downloads” so there is no need to pull the same package twice:

    Downloads

    Source available on Github

    Lazy Apk source code is available on github. I’ve tried couple of different techniques to extract code from Activity classes - I’m not yet sure if I like the results though…

    This article is cross-posted with my company blog

  • Google Play Services is no longer a giant monolith

    09 December 2014 android

    Nowadays it’s getting harder and harder to build a meaningful app and not rely on Google Play Services to aid us in some commonly required features such as maps, better location provider, geo fencing and so much more. Unfortunately up until now the library shipped as a giant monolith ripping us from one third of dex method limit. For curious reader here’s are method counts in couple of versions:

    Version Method Count
    3.2.65 6330
    4.4.52 16933
    5.0.89 20312
    6.1.71 23641

    and a full breakdown.

    Google Play Services 6.5 granular dependency management

    Today Google has made the awaited, more than usual, version of their SDK available. With the update apart from new features you can finally depend only on a subset of enormous API. Here’s a table from documentation along with dex method counts:

    API Name Gradle depdenency Dex method count
    Google Play Services com.google.android.gms:play-services:6.5.87 24525
    Google+ com.google.android.gms:play-services-plus:6.5.87 1525
    Google Account Login com.google.android.gms:play-services-identity:6.5.87 181
    Google Activity Recognition com.google.android.gms:play-services-location:6.5.87 857
    Google App Indexing com.google.android.gms:play-services-appindexing:6.5.87 482
    Google Cast com.google.android.gms:play-services-cast:6.5.87 976
    Google Drive com.google.android.gms:play-services-drive:6.5.87 2328
    Google Fit com.google.android.gms:play-services-fitness:6.5.87 1895
    Google Maps com.google.android.gms:play-services-maps:6.5.87 2568
    Google Mobile Ads com.google.android.gms:play-services-ads:6.5.87 3278
    Google Panorama Viewer com.google.android.gms:play-services-panorama:6.5.87 94
    Google Play Game services com.google.android.gms:play-services-games:6.5.87 5046
    Google Wallet com.google.android.gms:play-services-wallet:6.5.87 1116
    Android Wear com.google.android.gms:play-services-wearable:6.5.87 1187
    Google Actions
    Google Analytics
    Google Cloud Messaging
    com.google.android.gms:play-services-base:6.5.87 5212

    A small change to improve build time

    For me the biggest win is that in one of the apps we are actively developing granular dependency declaration means with a simple change from

    compile 'com.google.android.gms:play-services:6.1.71'
    

    to

    compile 'com.google.android.gms:play-services-maps:6.5.87'
    compile 'com.google.android.gms:play-services-location:6.5.87'
    compile 'com.google.android.gms:play-services-base:6.5.87'
    

    I no longer have to run Proguard during development. No wonder my build time just improved by 15 seconds.

    This article is cross-posted with my company blog