RX-Java, Spock, Groovy, Android-bindings… Android might now be testable! say what?

Along with our friends at Nordstrom we have some fundamental values we believe in. These include paired style of approaches to development, TDD/BDD, etc. Some of which up until recently have been a bit tough to get in on with Android. Now I’m not going argue the merits of TDD/BDD, you can look that up. I’ll go through some of what we’ve been looking at to help testability and simplicity in Android.

As most of you know testing in Android has been a pretty hostile Environment.  The next three posts will cover the following.

  1. Setting up Android-bindings – (This post ;))
  2. Using RX for the events from the UI and the rest of the system.
  3. Using Spock and Groovy to test our POJOs.

If you want to check out an app that is experimenting with some of these designs check out https://play.google.com/store/apps/details?id=com.liffft.iwanna (it is just a sample and not our “large scale implementations”  :))

Now lets gets started.

  1. DATA-BINDING

Per https://developer.android.com/tools/data-binding/guide.html data-binding is still in beta. However, with the rc1 release and my experience with it thus far it’s production ready.  I mean still test your app but it’s pretty solid at this point.  There is still a lag in the documentation so I’ll give you the current configuration I’m using

You’ll need to make the following updates to gradle.

buildscript.dependencies add

classpath “com.android.tools.build:gradle:2.0.0-aplha5

classpath “com.android.databinding:dataBinder:1.0-rc4

apply the plugins

 apply plugin: ‘com.android.application’

 apply plugin: ‘com.android.databinding

— you’ll also need to add

android { dataBinding { enabled = true }}

Now we wrap our normal xml layouts with a new <layout> tag.  Inside of this define <data> tags. Here’s the example of what my layout looks like.

<layout xmlns:android="http://schemas.android.com/apk/res/android">
  <data>
    <variable name="createEventViewModel" type="com.liffft.iwanna.activities.create.CreateEventViewModel"/>
  </data>
  <LinearLayout...
    //At some point in time a text view has
    <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/event_name_edit_text" android:layout_weight="1" android:text="@{createEventViewModel.eventName}" android:hint="Play Soccer" />
    //And many more based on the properties of the viewModel
  </LinearLayout>
</Layout>

Now the CreateEventViewModel extends BaseObservable and has @Bindable annotations for the getters for properties like

@Bindable public String getEventName() { return eventName; }
//and the setter looks like
public void setEventName(String eventName) {
  this.eventName = eventName;
  this.notifyPropertyChanged(BR.eventName);
}

Notice the notifyPropertyChanged. This is what notifies the UI to update from the model. This doesn’t need to be in the setter of the property. It can be anywhere where the side effect to the value takes place. In the Activity we can use

  CreateEventViewBinding createEventViewBinding = DataBindingUtil.setContentView(this, R.layout.create_event_view);
  createEventViewBinding.setCreateEventViewModel(mCreateEventViewModel);

CreateEventViewBinding is auto generated for us from the R.layout.create_event_view file name. It cases it and adds binding. At this point we’re ready to go. We have a great starting point to move much of the business objectives in the ViewModel. Notice there shouldn’t be any android stuff in the viewModel. This makes a nice and easy POJO to test with Spock and no need for the emulator.

Now for a few more advanced tips we’ll cover the following.

  • Fragments
  • The new NavigationView from the Design lib
  • RecyclerView
  • custom bindings

 

  1. Fragments – This is actually pretty simple.  The following code snippet should give you an example of the onCreateView and onViewCreated
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
  return inflater.inflate(R.layout.create_event_view, container, false);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
  super.onViewCreated(view, savedInstanceState);
  CreateEventViewBinding createEventViewBinding = DataBindingUtil.bind(view);
  createEventViewBinding.setCreateEventViewModel(mCreateEventViewModel);
}

Notice I’m injecting the ViewModel so you’ll need to make sure to instantiate it somewhere.

  1. NavigationView – Unfortunately we can only bind the drawer header .  The list of items is actually a menu which I don’t believe can be used with bindings yet. If someone knows better let me know. – Again a code snippet from my Activity that is using the NavigationDawer

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  DrawerHeaderBinding drawerHeaderBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.drawer_header, mNavigationView, true);
  drawerHeaderBinding.setHeader(mHeaderViewModel);
}

I think it’s pretty evident but make sure to include the correct layout for the header and give it the parent mNvaigationView.  This will now bind anything you want in the header to the mHeaderViewModel.

  1. RecyclerView – This is the one that’s a bit more tricky. I’ll post the code sample and then speak to it.

public class EventListAdapter extends RecyclerView.Adapter<EventListAdapter.BindingHolder>{

private ArrayList<EventInterface> events;
private ProjectRouter mProjectRouter;
@Inject
public EventListAdapter(ProjectRouter projectRouter){
  mProjectRouter = projectRouter;
  events = new ArrayList<>();
}

public void addAll(List<EventInterface> eventInterfaces){
  events.clear();
  events.addAll(eventInterfaces);
  notifyDataSetChanged();
}

@Override
public BindingHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  ViewDataBinding dataBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.single_item, parent, false);
  return new BindingHolder((SingleItemBinding)dataBinding);
}

@Override
public void onBindViewHolder(BindingHolder holder, int position) {
  final EventViewModel eventViewModel = new EventViewModel(events.get(position),mProjectRouter);
  SingleItemBinding itemBinding = (SingleItemBinding)holder.mViewDataBinding;
  itemBinding.setEvent(eventViewModel);
}

@Override
public int getItemCount() {
  return events.size();
}

@Override
public void onViewRecycled(BindingHolder holder) {
  holder.mViewDataBinding.getEvent().unsubscribe();
  super.onViewRecycled(holder);
}

public static class BindingHolder extends RecyclerView.ViewHolder {
  // each data item is just a string in this case
  public SingleItemBinding mViewDataBinding;
  public BindingHolder(SingleItemBinding viewDataBinding) {
    super(viewDataBinding.getRoot());
    mViewDataBinding = viewDataBinding;
  }
}

}

I’m using Roboguice to inject project dependencies right now so ignore that. But, what you need to pay attention to is that our Bindingholder is going to store our viewBinding. The terms here get a little overloaded (sorry!). Don’t confuse the onBindViewHolder with Data Binding.  It’s for the RecyclerView and is where we grab the DataBinding class and set the datamodel. The CreateViewHolder is where we actually create the binding and add it to the holder.

Note for those checking out the onViewRecycled, this is a precursor to some RX binding goodness 🙂

  1. Custom Bindings – so this is something I like. I have more examples coming up in the RX post however here is a quick and dirty example that can get you started

@BindingAdapter("bind:picassoImageUrl")
public static void loadImage(ImageView imageView, String url) {
  if (url !=null && !url.isEmpty()) {
    Picasso.with(imageView.getContext()).load(url).resize(400, 400).into(imageView);
  }
}
@BindingAdapter("bind:imageThumbnailLocalURLString")
public static void loadImageThumbnail(ImageView imageView, String imagePath){
  if(imagePath != null && !imagePath.isEmpty()) {
    Bitmap thumbImage = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(imagePath), 400, 400);
    imageView.setImageBitmap(thumbImage);
  }
}

in the layout use something like

  <ImageView….. app:picassoImageUri="@{settingsViewModel.imageURL}"; />

Here we can now set a model String object to the picassoImageUri. Whenever it’s updated it will go and load that image url to the ImageView. The imageThumbnailLocalURLString is an other example for a local file. You should be getting the idea!

Thanks for reading. If you have any questions or would like to know more about working with us at LIFFFT and the Nordstrom Technology team feel free to shoot us an email!

 

MODERN ANDROID APPLICATION ARCHITECTURE DEVELOPMENT: Part 3 – Dependency Injection, RxJava, DAO’s and more!

In continuation of the series of posts with our friends on the Nordstrom Technology team we’re going to be furthering our development of our Stackoverflow client.

You can access part 3 on GitHub at:

git clone https://github.com/Liffft/StackRX.git
cd StackRX
git checkout stack_rx_1_architecture_basics

Main Activity

Let’s begin by looking at our main activity (StackRXActivity). The activity houses our drawer layout and basic functionality. It’s important to abstract as much out of the main activity as possible as they tend to become large and unwieldy. In the main activity we see our first appearance of dependency injection.

Dependency Injection – First Look

Dependency injection has been common on the Java platform for years. We currently use Roboguice as our injection  framework; there are other viable alternatives out there but Roboguice allows us to inject necessary classes, views, etc. into our client code. The big advantages are:

  • Keeping our code clean of calls to findViewById.  It’s worth while to note that the new data binding framework utilizes the MVVM (model view, view model) pattern and solves the need for this.  It’s currently still in beta however, see: Data Binding Guide
  • Declaring and injecting classes and singletons
  • Allowing testing frameworks such as Mockito easily interact with shared resources

This injection annotation sets our content view within the main layout.

@ContentView(R.layout.stack_rx_activity)

InjectView allows us to take dependencies in our layout and surface them within our Java code

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".StackRXActivity">

Is now injected in our code as:

@InjectView(R.id.drawer_layout)
private DrawerLayout mDrawerLayout;

Our main activity now loads our first fragment and displays a list of StackOverflow questions.

screen-shot-2015-06-10-at-2-18-16-pm1

Question Fragment & RecyclerViews

Let’s take a look at QuestionFragment.  The question fragment is added onto the fragment stack and utilizes a mixture of RXJava and Retrofit to load the content into a RecyclerView.

If you haven’t used Androids new RecyclerViews they were introduced as a new component in Lollipop.  RecyclerView’s are essentially a replacement to the classic ListView but with added functionality (such as being able to scroll horizontally or vertically) and with increased performance.  For more information check out Creating Lists and Cards.  The RecyclerViews enforce the view holder pattern.

// Setup recycler view
mRecyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);  //  Sets the layout orientation
mRecyclerView.setLayoutManager(layoutManager);

Introducing RxJava, DAO’s and Retrofit

RxJava is an excellent way to address many problems associated with Asynchronous tasks and is rapidly being adopted in many Android projects.  We’ll primarily use it to interact with our service layer.  For more information check out the RxJava documentation.  We’ll deep dive Rx in Part 4: More RxJava, Adapters, Unit Testing and More!

First we inject our DAO

@Inject
QuestionsDAO mQuestionsDAO;

But wait, what’s a DAO?  A DAO a is data access object.  The DAO is where all our RESTful calls will be held.  No Android specific logic ever lives in the service layer or DAO’s.  Each call is prepended with it’s RESTful type.  Only 4 types of methods should be in a DAO (GET, POST, PUT, DELETE)  Some example service names:

getQuestions()
getQuestionById(int id)
postQuestion(int userId, String question)
deleteQuestionById(int userId, int questionId)

This is a clean way to separate the UI and data layers.  The DAO calls simply wraps the Retrofit service calls which return a Observable as a result.

Retrofit is a library by SquareUp.  Retrofit easily allows you to do a network call and marshall the data via GSON into objects.

@GET("/2.2/questions?order=desc&sort=activity&site=stackoverflow")
Observable<Questions> getQuestions();

That’s it!  If you want to see the code behind the Retrofit call check out BaseService.java in the services project.

Once executed we receive the response back to our observer that lives in the QuestionFragment class.

As an aside, often I see developers create their model files by hand.  It’s very tedious and error prone.  There are great tools to generate your model objects for you!  Check out jsonschema2pojo  To use this tool simply copy the payload of any service

Ex: https://api.stackexchange.com/2.2/questions?order=desc&sort=activity&site=stackoverflow

Be sure to select ‘JSON’ as the type and GSON as the source type.  Download the jar, unzip, and wha-la add it to your project.

json

These generated files should never be changed, any business logic should live in your view layer.

Let’s take a look at the call and the observer that receives the response.  All responses will be returned to the Observer region in the fragments.   Let’s look at the observer in QuestionFragment

mCompositeSubscription.add(mQuestionsDAO.getQuestions().observeOn(AndroidSchedulers.mainThread()).subscribe(mGetQuestionObserver));

Each call is added to a composite subscriber which lives in the BaseFragment.  When an fragment is destroyed all the RxJava observers are released.

StackRXBaseFragment

protected CompositeSubscription mCompositeSubscription = new CompositeSubscription();

@Override
public void onDestroy() {
    super.onDestroy();
    mCompositeSubscription.unsubscribe(); //  Remove the subscriptions
}

Next we execute the service call.

mQuestionsDAO.getQuestions()

Finally we tell RxJava to observe the call on the main thread and then use our Observer to subscribe to the signal

mQuestionsDAO.getQuestions().observeOn(AndroidSchedulers.mainThread()).subscribe(mGetQuestionObserver)

Note we use AndroidSchedulers this is actually part of the RxAndroid project and should be included in the build gradle.

Finally we receive the result on our Observer method

    //region OBSERVERS -----------------------------------------------------------------------------
    private class GetQuestionObserver implements Observer<Questions> {

        @Override
        public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {
            Toast.makeText(mActivity, mActivity.getString(R.string.service_error), Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onNext(Questions questions) {
            mUserSession.setQuestions(questions);
            mQuestionRecyclerViewAdapter.setItemList(questions.getItems());
            mQuestionRecyclerViewAdapter.notifyDataSetChanged();
        }
    }
    //endregion

Observers have three methods that must be implemented (onCompleted, onNext and onError)

onNext – This is receiving the signal from an Observable. This is essentially our successful call. The question class mirros the JSON response in a series of Question objects. Finally we set our item list in our adapter and update.

onError – This returns out error call. Typically a RetrofitError is returned this contains the server error and any additional information.

onComplete – This is logically called when completed. This is a good place to hide loading indicators etc. Note: If onError is called, Retrofit does not call onComplete.

The UserSession

Finally we have a concept of a user session. The user session is adopted from the web world. The typical way of passing around data in Android is either using the bundle or creating a new instance of a fragment and setting local variables, ugh. Our user session is a singleton that can be used throughout the application.

UserSession.java

@Singleton
public class UserSession {

    private Questions mQuestions;
    private Item mSelectedQuestion;

    public Questions getQuestions() {
        return mQuestions;
    }

    public void setQuestions(Questions questions) {
        mQuestions = questions;
    }

    public Item getSelectedQuestion() {
        return mSelectedQuestion;
    }

    public void setSelectedQuestion(Item selectedQuestion) {
        mSelectedQuestion = selectedQuestion;
    }

}

We then inject the singleton into future fragments that require it. The UserSession object is powerful but be aware of it’s contents may be changed throughout the app. Stay tuned for Part 4: More RxJava, Adapters, Unit Testing and More!

Thanks for reading. If you have any questions or would like to know more about working with the Nordstrom Technology team feel free to shoot us an email!

Modern Android Application Architecture & Development: Part 2 – Architecture Basics, Project Organization and Clean Code

In continuation of the series of posts with our friends on the Nordstrom Technology team we’re going to be creating a simple StackOverflow client utilizing the technologies discussed in Part 1 – Tools & Libraries.

The image to the right is the final screen that will be presented to the user.

You can access part 1 on GitHub at:
Screen Shot 2015-06-10 at 2.18.16 PM

git clone https://github.com/Liffft/StackRX.git
cd StackRX
git checkout stack_rx_1_architecture_basics

Before we jump into code let’s take a look at the anatomy and organization of the project.

StackRX Client Application vs StackRX Services

As mentioned in Part 1 we completely decouple the service layer from the view layer.  Projects that combine these become extremely unwieldy, limit code reusability and are much harder to test.

Android specific logic will never exist within the service layer.  Keep in mind that another team may use the service layer for their project so keep it clean.
Screen Shot 2015-06-10 at 2.24.36 PMTo create the services project simply right click File–>New–>New Module

In the editor be sure to select ‘Android Library’. Also make sure the library is included in your app build.gradle as a dependency

dependencies {
compile project(‘:stackrx-services’)
}

The services build.gradle should include any libraries shared between the application front-end and the services layer.

build.gradle (app)                                                                      build.gradle (services)

Screen Shot 2015-06-10 at 2.26.44 PMScreen Shot 2015-06-10 at 2.26.36 PM

Notice how we have the new Material Design cardview library only in the app dependencies but the services library contains Roboguice which is used both in the services and app.

Package Structure

Android applications are often organized by object type but we organize by feature.

Screen Shot 2015-06-10 at 2.29.52 PM

We do this for the following reasons:

  •  As projects get more complex, standard naming is imperative.  As we progress in the project development you will notice that all packages resemble each other in both the unit tests, client code and service layer.  This prevents problems like a fragment package with 30 fragment files with no context or classes being in packages for no rhyme or reason.
  • Coming into a large Android project can be hell.  As a new developer getting your first commit can be overwhelming.  However if the application is broken into features it’s much easier to get started.  Need to make changes to the shopping page?  Most likely it will be in the shop->fragment package. Some oversight will be needed for shared objects.
  • We will touch on this further, but fragment classes should be as small as possible.  Complex things such as adapters should be moved into their own packages and classes when possible.  This leads to more testable code in general.

Let’s Write Clean Code Together.  Android Code Best Practices.

We’ve spent a lot of time thinking of ways to keep our code base as uniform and readable as possible.  Following good practices from day #1 will reduce code complexity, tech debt and refactoring time.  Many projects race to release but are so disorganized and non-uniform a rewrite is almost necessary afterwards.

Code Grouping and Organization

Android Studio supports regions; a little known feature that really helps organize classes.

Pulling open StackRXActivity (or any other classes in the view layer) you will see our code regions defined:

Screen Shot 2015-06-10 at 2.32.35 PM

Figure 1                                                                       Figure 2

These are just like pragma marks in other languages.  To collapse the regions hit

Command->Shift->Minus

to grow the region

Command->Shift->Plus

The categories above are the same for every fragment, adapter, activity etc.

This won’t be crystal clear initially, but I’ll explain each region and its purpose.

INJECTED CLASSES

This section is for dependency Roboguice injected classes

@Inject UserSession
private UserSession mUserSession;

INJECTED VIEWS

This section is for injected Roboguice views.  There should be no view.findByViewId’s littered throughout the code

@InjectView(R.id.drawer_layout)
private DrawerLayout mDrawerLayout;

LOCAL CONSTANTS

Local constants are immutable constants pertaining to the class.  If they are string constants and used in other classes they should live in an AppConstants

private static final String TAG = QuestionFragment.class.getSimpleName();

CLASS VARIABLES

Local class variables.  We tend to perserve the ‘m’ prefix.

private QuestionFragment mQuestionFragment;

CONSTRUCTOR

Any constructors associated with the class

public StackRXActivity () {}

LIFE CYCLE METHODS

All life cycle methods.  For fragments and activities order matters.  Ex: onCreate should never be after onDestroy

onAttach(Activity)
onCreate(Bundle)
onCreateView(LayoutInflater, ViewGroup, Bundle)
onActivityCreated(Bundle)
onViewStateRestored(Bundle)
onStart()
onResume()
onPause()
onStop()
onDestroyView()
onDestroy()
onDetach()

@Override
protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
}

WIDGET

Widget is used as a catch-all for widgets within the screen.

@Override
public boolean onCreateOptionsMenu(Menu menu) {
}

LISTENERS

Listeners are all component type listeners in the view (OnClickListener, OnTextChangeListener)
Listeners should always be separate classes and never be inline in the life cycle methods.  Also set the listener in the code and never implement or extend on the class level.

private class OnLoginButtonClickListener extends View.OnClickListener {
        @Override
        public void onClick (View v) { }
}

EVENTS

Events are triggered by the EventBus.  All fragment/activity level uses of the event bus are captured here

public void OnButtonSelectEvent(ButtonSelectEvent buttonSelectEvent) { }

LOCAL METHODS

Local methods pertaining to the fragment

public void AddItemToList(String item) {
...
}

OBSERVERS

Observers are listening for observables that have sent down a single typically from network calls

private class GetQuestionObserver implements Obvserver {
…
}

ACCESSORS

Getters and setters the class

public void getItemCount () {
       return itemCount;
}

<b>INNER CLASSES</b>

Inner classes that are not discussed above


private class SomeInnerClass {
}

Variable Naming

Let Android Studio name your variables for you! Rather than using a shorthand like  "adaptor" or "qda" for a “QuestionDetailAdapter” simply start typing the first letter of the class name to have it automatically named that.

We use the m prefix on all class level variables.  While this is always up for debate, you never have any of the time wasting this.variableName on constructors.

Ex:

public QuestionDetailAdapter(Context context) {
       context = context;      // no!
       mContext = context;  // nice!
}

You can configure Android Studio to automatically prepend the ‘m’ right when you type the variable name

Android Studio-->Preferences-->Edit-->Code Style-->Java-->Code Generation-->Field-->Name Prefix-->m

Layout Naming Conventions

Too many projects do not name layouts or layout ids consistently.  Our convention is as follows:

The layout name always matches the class exactly.  This makes it is incredibly clear which layout file is for which class.

Ex: QuestionFragment.java → question_fragment.xml

Variable naming should always match the layout name appended with what it is and its type.

How many times have we seen:

R.id.question or R.id.sign_in

This gives no context.

Instead:

R.id.question_fragment_question_list_view or

R.id.question_fragment_sign_in_button

Do you have any other tips / tricks for keeping your project sane and beautiful?  Drop us a comment!  Stay turned for Part 3:  Dependency Injection, RxJava, DAO’s and more!

Thanks for reading. If you have any questions or would like to know more about working with the Nordstrom Technology team feel free to shoot us an email!

Modern Android Application Architecture & Development: Part 1 – Tools & Libraries

In continuation to our series of posts with our friends on the Nordstrom Technology team we’re going to take a detour from RxJava and start looking at modern application architecture.

Introduction

Android development has changed significantly since we first started developing applications circa 2009.  Typically the build system was Ant, (Maven if you were adventurous and really wanted package management), the IDE was Eclipse and the language was of course Java.  The emulator was, until only recently, laughably bad. Android library support was still evolving. Simple tasks like talking to a JSON backend and presenting data was painful.

public class MainActivity extends Activity {

    private TextView responseText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);
        responseText.findViewBy(R.id.responseText);
        // call AsynTask to perform network operation on separate thread
        new HttpAsyncTask().execute("http://api.stackexchange.com/v2.2/questions?site=stackoverflow");
    }

    public static String GET(String url) {

        InputStream inputStream = null;
        String result = "";

        try {
            // create HttpClient
            HttpClient httpclient = new DefaultHttpClient();

            // make GET request to the given URL
            HttpResponse httpResponse = httpclient.execute(new HttpGet(url));

            // receive response as inputStream
            inputStream = httpResponse.getEntity().getContent();

            // convert inputstream to string
            if (inputStream != null)
                result = convertInputStreamToString(inputStream);
        }
        catch (Exception e) {
            Log.d("InputStream", e.getLocalizedMessage());
        }

        return result;
    }

    private static String convertInputStreamToString(InputStream inputStream) throws IOException {

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String line = "";
        String result = "";

        while ((line = bufferedReader.readLine()) != null)
            result += line;

        inputStream.close();

        return result;

    }

    private class HttpAsyncTask extends AsyncTask&lt;String, Void, String&gt; {
        @Override
        protected String doInBackground(String... urls) {
            return GET(urls[0]);
        }

        // onPostExecute displays the results of the AsyncTask.
        @Override
        protected void onPostExecute(String result) {

            Toast.makeText(getBaseContext(), "Received!", Toast.LENGTH_LONG).show();
            textView.setText(result);
        }
    }
}

Who remembers, and who still does, a GET request like this?

It’s huge and we haven’t even marshalled the data into objects yet!  Fortunately things have been evolving especially after Google introduced Android Studio and Gradle as their defacto environment. Libraries have made our lives infinitely easier and tooling has gotten significantly better. However, a lot of projects are still being built as if it was five years ago. Now I don’t blame developers for this.  Android, unlike iOS, has a ton of options to choose from, and there is often no clear direction from Google.  Even some of Google’s own libraries; Volley, a solution for Async networking, for example; are poorly advertised.

Android often feels it is plagued by JQuery syndrome.  There are  a thousand ways to do something, but what works best?  In this series of blog posts we’ll build a real life application that uses what we feel is the best architecture/technology to achieve robust and well made apps.  We’ll focus on building a pretty typical client server application piece by piece.

In Part 1 we’ll discuss the basics of our Android architecture and the libraries we use to build our applications.  If you’re unfamiliar with what’s out there, or what’s being used, give it a read.  If you want to dive straight into the implementation then start with Part 2: Architecture Basics, Project Organization and Clean Code (Coming soon!)

IDE’s, Languages & Build Systems

As previously mentioned Android Studio and Gradle are now the recommended development environment for Android. If you’re still considering using Eclipse for a new project it’s unsupported. Frankly it’s time to get used to Android Studio.

Java is still the dominant development language on android. Though it’s completely possible to build an app using different JVM languages for example: Groovy, Kotlin etc. The New York Times app for example is based on RxJava and Groovy:

Getting Groovy With Reactive Android

We would still recommend sticking to Java due to the wealth of information currently out there. In our project we’ll slowly migrate to use RetroLambda to reduce the verbosity of our code.

Having a build server such as Jenkins will make managing builds in any environment that much simpler. A good alternative is Travis if you don’t want to spin up your own infrastructure.

Android Versions

What Android versions should you support? It’s pretty safe to no longer support anything Ice Cream Sandwich (4.0) and below. Version statistics are always available on the Android Developers Site.

Android Version Statistics

There were significant changes between 2.x and 4.x SDK levels. Android Studio now provides you with an easy guide on what features are supported on project creation. Google has done a nice job offering backward compatibility libraries to support older devices as well. More on that:

http://developer.android.com/tools/support-library/index.html

Emulators

Having a good emulator is essential for rapid development, reducing build times and testing on different device configurations. Previously the Android default emulator was so poor that most developers just used physical devices. Google has finally released a decent emulator utilizing Intel’s HAXM technology. While it’s gotten better, we currently recommend Genymotion. Genymotion is fast, really fast. It’s free for personal development and simulates the most popular phones on the market today.

Libraries

Play Services

Chances are you will use Google Play Services somewhere within your app. Using Google Play services is an easy way to leverage Google’s other product offerings. The most popular are of course Google Maps and Google Wallet, however it supports a host of others (Wearables, Google Fit, Drive, Places etc). Keep in mind each individual component may be included separately:

Ex: compile ‘com.google.android.gms:play-services:7.0.0’ (All Google services)

or

compile ‘com.google.android.gms:play-services-fitness:7.3.0’ (Google Fit)
compile ‘com.google.android.gms:play-services-wearable:7.3.0’ (Wearables)

Material Design

Material design was introduced with Lollipop last year. It’s an attempt to unify look and feel of apps on the Android platform. The entire design guide can be found here:

http://www.google.com/design/spec/material-design/introduction.html#introduction-principles

It’s worthwhile to get yourself up to speed on Material Design and its principals. Any apps not adhering to the new Material Design will not be getting much love in the Play Store.

Why is this section under libraries? Well, Google, for whatever reason gave us some components and not others. While there is a library for the new card view from Google, something like the floating action button is missing (Update: this is now part of the support libraries). Open source alternatives are needed until Google officially supports its components. We’ll dive into these components more later. Below is a megalist of Android libraries and a lot of material design libraries are highlighted:

https://github.com/snowdream/awesome-android#Material

Networking

Talking with Restful backends is how most apps communicate with servers. The common data retrieval use case

1) User Needs Data
2) Asynchronous Call is Made
3) Data is Requested
4) Return JSON is Marshalled into Objects
5) Data is Presented to the User

Let’s take each individual step:

User Needs Data

Typically triggered by a user action (sign in button, displaying a list) We always break out the service layer apart from the view layer. Projects get ugly quickly when the view layer and service layers are intermixed. We’ll create a separate Android library to accomplish this. When a user needs to perform any action against our Restful backend we’ll call into the service layer.

Asynchronous Call is Made

Not blocking the Android UI thread is critical to prevent Android from killing your app. Some of the major libraries used for this are Volley, Retrofit and Robospice. Each have their strengths and weaknesses. We chose Retrofit for a few reasons. Syntactically it’s very simple and Retrofit also plays well with RxJava which we’ll use to communicate with the view layer and beyond.

Ex: @GET(“/2.2/questions?order=desc&sort=activity&site=stackoverflow”)
Observable getQuestions();

Part 3: Dependency Injection, RxJava, DAO’s and more! will give a full example of this. Much more on this later.

Data is Requested

Once again there are a lot of alternatives for this. Some typical ones are Google HTTP Client and OkHTTP. We use OkHTTP as it’s also by Square and easily integrates with Retrofit. Note: The Apache HTTP libraries have been deprecated for some time now so stay away from them.

Return JSON is Marshalled into Objects

In order to easily work with our data we want it returned as objects. A lot of projects still do this by hand and it’s painful and error prone. Common libraries to do this are Jackson and GSON. We will use GSON in our project.

Data is Presented to the User

In order to present the data to the user we must get back the requested data in a useful form. Once again Volley, Robospice, Retrofit and various others all support this. We are using RxJava. RxJava is a reactive style of programming that is extremely powerful and solves a lot of problems other libraries do not. RxJava was originally developed for the .NET platform but has been ported to seemingly every language known to man. ReactiveCocoa for iOS is extremely popular.

A common use case:

User Logs In -> Server Must Verify Username / Password -> User’s addresses, credit cards, and list of orders are returned from the server. Managing all these interactions is handled with RxJava in an elegant way. Also more on this later.

Event Bus

An event bus is an easy way to communicate between fragments, activities etc. Android has a default event bus but the most popular is Otto by SquareUp. Event busses are a great way to communicate within the app but can be grossly overused. Used sparingly they solve a whole host of issues and reduce callback hell. We’ll use Otto in small doses.

Image Loading

There are a host of image loading frameworks out there. The most popular include Picasso, Volley, Glide, and Universal Image Loader. Recently Facebook released Fresco. Fresco is a robust image library that uses an image pipeline to efficiently manage memory. This solved a host of memory problems in a recent app we were working on as it was extremely image heavy.

Dependency Injection

Dependency injection helps manage inter-dependencies in the application. The most commons ones are Butterknife, Roboguice and Dagger. We use Roboguice as it’s less complex than Dagger and plays well with Mockito for our unit testing. We are currently investigating Dagger as a viable alternative now that it is supported by Google.

Testing

Testing has traditionally been a pain in Android. More projects than not have no tests at all. Tools often don’t play well together and the Android lifecycle and Context often make testing difficult. Things have improved with better testing integration with Android Studio’s recent releases.

Mocking Data

Mock data is important. It allows you to manipulate data to easily perform varying tests. It also allows you to develop without being dependent on the service layer or making live calls. Common mocking frameworks are Mockito, Powermock and Easymock. For our project we’ll use Mockito as it plays well with Roboguice, RxJava and Espresso.

Unit Testing

We’ll test our business logic using straight, and fast, JUnit tests. The app must be structured in a smart way to truly make this achievable. Typically too much logic happens in Android’s lifecycle methods which makes testing extremely fragile. We’ll create helpers to test our business components.

Integration Testing

Numerous libraries allow for on device integration tests. These tests tend to be slower but are able to test both business logic and UI. The most common ones are Espresso, Robolectric (which is a headless JVM and does not require a device), and Robotium. For our project we’ll use Espresso. We chose Espresso as it’s maintained by Google and has good API’s. We’ve experienced a lot of compatibility problems with Robolectric and Robotium especially with new features added by Google.

As you can see there are lots of choices to architect an Android app. In our case we’re drawing from personal experiences in large scale projects. This is by no means the definitive list of everything. There is always better solutions and things are always changing. We’ll take our selected technologies and begin to build our client in Part 2: Architecture Basics, Project Organization and Clean Code

Thanks for reading. If you have any questions or would like to know more about working with the Nordstrom Technology team feel free to shoot us an email!

RX by Example

This is the first in a series of blog posts co-authored with our friends over on the Nordstrom Technology team. This one might be a bit technical for the non-developer crowd. Today we’ll be taking a look at Nordstrom’s use of Reactive Java and Reactive Android.

We’d be lying to say that our adoption of RX-Android  hasn’t been a somewhat bumpy ride. We’ll get into the challenges reactive brought in a later post. Today we’re going to  take a look at some of the simplifications reactive has brought to the code base.

For those completely new to the reactive model see

http://paulstovell.com/blog/reactive-programming

https://medium.com/reactive-programming/what-is-reactive-programming-bc9fa7f4a7fc

When building any application these days you’ll need to make a large number of network calls. These calls are often, but not always dependent on each other. Additionally they need to update the state of application UI, often in many different places. This leads to several common problems.

The first problem is in a series of network calls dependent on each other. In this example we need to authenticate the user, fetch their shopping cart, and some details about one of the items in the shopping cart.

The traditional approach looks something like this.

mAuthentication.Authenticate(username, password, new Callback<AuthenticationResult>() {
  @Override
  public void success(AuthenticationResult authenticationResult, Response response) {
    mShoppingCartService.shoppingCarFor(authenticationResult, new Callback<ShoppingCart>() {
      @Override
      public void success(ShoppingCart shoppingCart, Response response) {
        mProductDetails.getItemDetails(shoppingCart.mainItem, new Callback<itemDetail>() {
          @Override
          public void success(ItemDetail itemDetail, Response response) {
            updateUIWith(itemDetail);
          }
          @Override
          public void failure(RetrofitError error) {
            //something with Error
          }
      }
      @Override
      public void failure(RetrofitError error) {
        //something with Error
      }
    });
  }
  @Override
  public void failure(RetrofitError error) {
    //something with Error
  }
});

Welcome to nested callback hell. Sure it works but it’s a pain to read and thus pretty simple to introduce bugs. A common alternative is to use class variables to store intermediate state. This opens us up to inconsistent state and mutability issues.

Here it is with Reactive:

Subscription shoppingCartSubscription = mAuthentication.authenticate(username, password).flatMap(new Func1<AuthenticationResult, Observable<ShoppingCart>>() {
  @Override
  public Observable<ShoppingCart> call(AuthenticationResult authenticationResult) {
    //This returns an Observable that will emit the Shopping cart for the authenticationResult
    return mShoppingCartService.shoppingCartFor(authenticationResult);
  }
}).flatMap(new Func1<ShoppingCart, Observable<ItemDetail>>() {
  @Override
  public Observable<ItemDetail> call(ShoppingCart shoppingCart) {
    //This returns an Observable that will emit the ItemDetail for the mainItem in the ShoppingCart
    return mProductDetails.itemDetailsFor(shoppingCart.mainItem);
  }
//We now can do whatever we need with the Item Details. No need to store all the previous responces
}).subscribe(new Observer<ItemDetail>() {
  @Override
  public void onCompleted() {
  }
  @Override
  public void onError(Throwable e) {
  }
  @Override
  public void onNext(ItemDetail itemDetail) {
    updateUIWith(itemDetail);
  }
});

Composition is simple and straightforward.  There’s very little difference in handling a network async call to how you would just handle a list of items in an array.

You also get:

  • filters: ignore unwanted return values
  • throttles: prevent excessive network calls
  • maps: transform the data to something different
  • etc.

The second problem arises when you have several independent network calls to combine into a single result. We could use the previous pattern but then our result would take the sum of the call length rather than the length of the longest call. Doing this without RX total pain. Make all the calls. Keep track of when they’re all done in a class variable. When a callback fires check if we are all done. If so run the final callback.

Something like this:

mUser.PersonalData(user, new Callback<PersonalData>() {
  @Override
  public void success(PersonalData personalData, Response response) {
    mPersonalData = personalData;
    done1 = true;
    if (done2 && done3) {
      updateUIwith(mPersonalData, mShippingInfo, mCreditCard);
    }
  }
  @Override
  public void failure(RetrofitError error) {
   //something with Error
  }
});
mUser.shippingInfo(user, new Callback<ShippingInfo>() {
  @Override
  public void success(ShippingInfo shippingInfo, Response response) {
    mShippingInfo = shippingInfo;
    done3 = true;
    if (done2 && done1) {
      updateUIwith(mPersonalData, mShippingInfo, mCreditCard);
    }
  }
  @Override
  public void failure(RetrofitError error) {
    //something with Error
  }
});

mUser.CreditCard(user, new Callback<CreditCard>() {
  @Override
  public void success(CreditCard creditCard, Response response) {
    mCreditCard = creditCard;
    done2 = true;
    if (done1 && done3) {
      updateUIwith(mPersonalData, mShippingInfo, mCreditCard);
    }
  }
  @Override
  public void failure(RetrofitError error) {
    //something with Error
  }
});

This works OK, but now you’ve got a bunch of different incomplete states your object can be in. It’s not so bad now but with a few more calls it can get difficult to see interdependent calls. Worse yet adding a new call into the set requires making changes all over. You can avoid some of this by being clever but let’s take a look at the simple approach instead.


With Reactive:
Subscription userInfoSub = Observable.combineLatest(mUser.personalData,mUser.shippingInfo,mUser.defaultCreditCardInfo
 new Func3<PersonalData, ShippingInfo, CreditCard, UserDataViewModel>() {
  @Override
  public UserDataViewModel call(PersonalData personalData, ShippingInfo shippingInfo, CreditCard creditCard) {
    //UserDataViewModel can do whatever logic it needs to merge all three responses.
    return UserDataViewModel.create(personalData, shippingInfo, creditCard);
  }
}).subscribe(new Observer<UserDataViewModel>() {
  @Override
    public void onCompleted() {
  }
  @Override
    public void onError(Throwable e) {
  }
  @Override
  public void onNext(UserDateViewModel userDataViewModel) {
    updateUIwith(userDataViewModel);
  }
});

In the RX example you see that nothing outside this call is mutable. You have no risk of someone later inadvertently modifying your data or of the data being in inconsistent states. There’s no need to reset everything before making the call once more.  Testing the behavior becomes drastically simpler.  You see in one place the flow of logic which is taking place. It is a bit of a paradigm shift. However, it’s going to be hard to go back after looking behind the curtain.

Some gotchas:

Subscriptions: Subscribe calls return Subscription objects. Once you unsubscribe the Observer will no longer receive events. Call unsubscribe on destruction lifecycle events in Android.

Observer – Observers receive the final event. In general you want to use them to update the UI. You may want to .observeOn(AndroidSchedulers.maintThread()) to make sure the update is on the correct thread.

 

Thanks for reading. If you have any questions or would like to know more about working with Reactive Java at Nordstrom shoot us an email.

WEDNESDAY COLLABORATION/COACHING AT FIX (FOCUS ON ReactiveCocoa)

tl;dr version:

What: Hangout and talk about coding/customer development/etc at Fix Coffee House in Greenlake.

Liffft Focus: I’ll be focusing on ReactiveCocoa but bring any projects you’re working on

Date/Time: Wednesday 10/22/2014 from 10am-4pm

Location: Fix Coffeehouse

6900 East Green Lake Way N
Seattle, WA 98115
Hit me up @lindyblues on twitter if you have questions or want to join!

Starting Wednesday collaboration/coaching at Fix (Focus on DI with iOS)

tl;dr version:

What: Hangout and talk about coding/customer development/etc at Fix Coffee House in Greenlake. (I’m personally prepping for a video on DI and iOS)

Date/Time: Wednesday 10/22/2014 from !0am-4pm

Location: Fix Coffeehouse

6900 East Green Lake Way N
Seattle, WA 98115
—–
Details :  For a little while now I’ve been spending time on Wednesdays to chat with people about their projects, code, and anything else that I might be able to help out with. I’ll personally be focusing on Dependency Injection with iOS, primarily using Typhoon and Objective-C but I’ll also be doing some swift I’m sure.  Feel free to join if you just want to hang out and work on your projects, want to help out and/or need help.