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!

 

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.

Saving Marriages One Stand-Up at a Time

I once believed you could make anything work in a relationship. Part of me still thinks you can. The greater question becomes “should you?”. What are issues which are resolvable vs those that require you to move on?  These questions had been on my mind for a while and jumped front and center during my morning check-in with my folks on my way to work.

The conversation starts with the normal “how have the last couple days gone?”, however quickly she starts complaining about trivial things. I know my mother well enough that this isn’t normal behavior so I asked “How are things really doing?”, it seems that adding “really” does make a difference.   I find out my parents’  relationship is going through a rocky phase.  Various personal topics get touched on, the ones every relationship has gone through at least once and I can hear the pain in my mom’s voice at the upcoming hurdles.  It’s time for a trip back home to Ohio.

My mother picks me up from the airport  a couple weeks later and the tone is still the same.  I always have a tough time knowing what’s appropriate to say when  it comes to relationship issues between my parents. I see my mother’s pain but never know exactly what will make it go away.

In this instance I heard more about miscommunication, resentment over unfulfilled promises, and past-based assumptions than anything else.  I really wish these weren’t common issues, however these complaints are almost identical to those I’ve heard within corporate groups. In fact, the more I thought about it the more overlap I found. With a slew of  my intimate relationships having been a mess, I started wondering if the similarities were close enough that some of the tools and strategies could cross over. Could implementing some of the processes we use to reinforce group buy-in and communication have the same beneficial effects in a relationship as they do within organizations?  After all, what are organizations other than groups of relationships?

I resolved to test out some ideas I had with my folks.

I felt a little odd trying to run a small workshop with my parents. Who am I to teach my parents? In a company you have less emotional baggage, whereas with your parents it weighs heavily. You’re committed, you’ve got literal skin in the game: skin and blood and genes. It’s really a great exercise in active listening and humility.

Though they’re hesitant at first, after a series of questions and answers they commit.  We get started right away and I spend the next few hours applying everything I’ve done within teams at corporations to my parents relationship. We talk about working agreements, stand-ups, Kanbans, and commitment. We talk about ensuring respect, establishing empathy, and creating structure.  We talk a lot. Their brains are spinning, churning over thoughts of using these tools for the kids’ chores, church activities, and personal goals.

It’s working.

Though I’d hoped this exercise would help remove stress and conflict from my parents’ lives, it wasn’t until weeks later that I truly saw the real results.  Many of the complaints that were present prior to our discussion had dissipated.  Agreements had been made and had a structure for evolving, as well as a way to be kept in check if they weren’t.  Additionally, empathy was now present in all of their interactions. My father, a vehement opposer of lists and being told what to do, was now keeping track of tasks on the kanban board…and enjoying it. For him, the reward of seeing things move from the “to do” to “done” column provided a sense of accomplishment that replaced any sense of feeling nagged. It was simple: he could see what needed to get done, and my mother was able to visualize why priorities might change. They developed empathy; conversations changed from “why isn’t this getting done?” to “how can I help you with this?”.

Empathy in general is a key skill to have and is particularly beneficial in functional business relationships.  However, in personal relationships it’s become even more important with it’s strong ties to love. People want a loving relationship not just one that’s based on convenience or complacency.  Building empathy with your partner will directly impact having a loving relationship!  An interesting write up on the the connection of Love and Empathy can be found at http://www.percepp.com/lovempat.htm.

Now, it’s not all roses. My participation in the stand-ups with my parents decreased as time passed.  Though I’m not sure if the structures are still in place after a year, their conversation techniques have permanently changed, meaning that any future attempts to improve will be easier for them to take on. I’m planning another trip home soon and expect to continue working on strengthening their understanding of the principles behind these tools.

Over the course of working with many types of relationships some of the underlying questions that have come up for me are, “How can I merge my desire for immediate gratification with longer term contentment and happiness?” and “How can I ensure I continuously prioritize relationships?”. Though I’ve always said that my personal relationships are the most important part of my life, recently I’ve had to accept that this not actually the case.  It’s high time I also  start using these tools and systems to help make sure my  lifestyle lines up with my desired priorities.

Most people can relate to these problems in their personal lives.  Whether it’s their parents, siblings, friends, or professional relationship; I’d highly recommend trying it out.  Below is the format I used.  Feel free to tweak it and make it your own.  I’d love to hear your feedback on what worked for you!

1. Get buy-in to try something new

  • In this case I asked, “Would you guys be up for trying something new that I’ve been playing with for a while?  I’m not sure what the outcome will be, but it will only take a little while, and the results I’ve seen in companies have been pretty amazing.”

  • I don’t have a great new solution that will solve all their problems. There is no guaranteed outcome, just cases of past experience that indicate that it will likely help.  Don’t tell them you have magic fairy dust to solve all their problems. People are smart and they’ll know when you’re full of shit.

  • Stay away from implying you know more about their situation than they do. It will only annoy them. Try not to use “should” and “shouldn’t”.

2. Tell a couple of stories about the types of changes you’ve seen within groups.

  • Here I had some good examples of teams that suffered from major communication problems (both professionally and socially), who spent most of their time on Facebook, choose to procrastinate, didn’t have tools to communicate, and resented each other because they had no empathy for one another. The emotional distance that results from feeling more and more separate from each other dehumanizes the other person.  As they become more of an object that you perceive is causing suffering in your world, the more you separate yourself from that entity, which leads to less empathy and propagates the issue.  With this understanding it becomes easy to see how passive-aggressive behaviors in the workforce really aren’t that dissimilar from those in intimate relationships.

3. Developing working/relationship agreements

  • In this case I started with the main complaints of what each person was or was not doing. Some examples included never bringing receipts home, spending too much money on coffee, failing to plan trips ahead of time, spending too much money on gas, neglecting to schedule property viewings, not supporting decisions with kids, and nagging.

  • We next discussed the changes that would help things work, having them each ask the other if they would be willing to take responsibility for specific tasks, and whether they would agree to write those tasks on sticky notes to put on the wall for everyone to see.  We ended up with goals like “receipts will always be in the house at the end of the day”. Everyone needs to be completely in on the agreements.  No “kind of” type of language allowed.

  • I emphasized that nothing is permanent.  There are structures to allow for this to change when it makes sense for it to. This is only an agreement till it no longer works. This is really important for people that get stuck on not wanting to try something out for the fear of being stuck with it forever.

4. The magic of Kanbans

  • For those of you that don’t know, “Kanban” means signboard. It’s incredibly simple and yet impactful.  In short, it visually shows you what you’ve done in the past day, what you plan on doing the next day, and what’s blocking you from moving forward.  Yes, there are wip limits and much more, but we’ll keep it simple for the time being. The point is that communication is now visual, and it’s clear for everyone to see.

  • Start out simple and make 3 columns for To Do, Doing, and Done. You can always add more later but don’t overthink your options.

  • MAKE THIS VISIBLE. If it’s not in a place you look at everyday, you won’t do it. You’ll even want to hide it to not deal with it. Fight that urge.

  • Use the order as a priority and grab from the top of the list to move over.

  • Establish a “Work In Progress” (WIP) limit. Don’t put more than 2 things per person in the “Doing”. Get things done before starting more.

5. Relationship/work stand-ups

  • We all agreed to have 15 minute stand-ups to check in on only the following:  What did I accomplish yesterday? What am I committing to tomorrow? What do I need help with (blockers)?

  • This will seem odd to most people to apply in a home environment, however these are common things that we need to talk about all the time to build empathy and yet never really have structures for. Especially for families that don’t all eat together, have busy schedules, etc.

6. What needs to evolve (retrospectives)?

  • After discussing the rationale for these continuous improvements and an evolution to something more fulfilling, we made a commitment to implement our new strategies once a week.  There are many games to foster follow through, and I always suggest learning multiple fun games.  This needs to be something you look forward to and enjoy, otherwise it falls by the wayside until you have large enough problems that you need to bring it back.  Why not just build a system that constantly rewards doing it? This is also a great place to revisit agreements and make modifications.