Groupon CTO & CEO Visit Seattle Office

Groupon CTO & CEO Visit Seattle Office

ENGINEERING

December 2017

CEO Rich Williams & new CTO Colin Bodell visit Groupon Seattle

Groupon recently added a new leader to our C-suite: Colin Bodell, Chief Technology Officer. As part of a North American tour to our Engineering and Product hubs, Colin and CEO Rich Williams made their final stop at our Seattle office, where Colin will reside. Grouponers in Seattle had the chance to mingle with the two leaders during an informal meet and greet. Conversations ranged from business questions to fun things to do in Seattle (using Groupons, of course).

Colin joins Groupon from American Eagle Outfitters, where he was CTO. Additionally—something Groupon is incredibly excited about—he serves as a trustee and board chair of AnitaB.org (formerly the Anita Borg Institute of Technology) as well as board chair of the National Center for Women and Information Technology. Together, with our Chief Product Officer, Jay Sullivan, the two will lead the technology strategy and implementation of the tools which serve Groupon’s 49 million customers worldwide.

Architecture Patterns for Backends beyond SOA

Architecture Patterns for Backends beyond SOA

Architecture Patterns for Backends beyond SOA

Javier Cano, Senior Software Engineer
Sergey Burkov, Senior Java Developer
December 13, 2017

In the Merchant Experience team specifically, and in Groupon in general, we have to deal with the challenge of scale and performance that our global business imposes. We make heavy use of SOA and microservices in our platform, though that is usually not enough. The solutions that we need make us explore and try different architectural patterns that move beyond what a SOA approach can provide. In this short talk we’ll explore some of these alternatives architectures, which problems they solve and how they integrate in microservices platform.

You can see lots more video of Grouponers and their smart friends on our YouTube channel.

Messaging at (Groupon) scale

Messaging at (Groupon) scale

Messaging at (Groupon) Scale

Nikita Berdikov
Senior Software Engineer
December 13, 2017

Every company is using messaging one way or another. So do we at Groupon. Messaging platform allows distributed heterogeneous services communicate with each other in asynchronous publish-subscribe fashion. Let’s talk about problems it helps to solve and problems it creates (especially from the owners of messaging infrastructure point of view). In addition we will go through tools we have built around messaging for better monitoring, maintenance and issues.

You can see lots more videos from Grouponers and other smart people on out YouTube channel.

Geekfest: Web.js (Full Stack Javascript)

Geekfest: Web.js (Full Stack Javascript)

Web.js (Full Stack Javascript)

Jaime Garcia Diaz
Software Engineer
November 14, 2017

1
2
3
4
5
6
7
Javascript is one of the most popular programming languages.
It's flexibility has impacted the way the web is being built.
Let'
s build a full-stack application with Javascript.
We'll touch on integrating with Docker, Mongo, Nextjs, Graphql, React and MaterialUI.
Recommended for anyone interested on Javascript and how it can be used on different web architecture tiers.
Demo:
https://github.com/jgarciadiaz/demo-events

See all Geekfest videos from Groupon and our friends.

Data Driven Chicago (Second Edition)

Data Driven Chicago (Second Edition)

Data Driven Chicago

Ilhan Kolko (Echo)
Andrew Lisy and Laura Hamilton (Groupon)
Tyler Hanson (Reverb)
Mary Feigenbutz and Greg Reda (Sprout Social)
Laurie Skelly and Elizabeth Cleveland (Trunk Club)
Moderated by Alli Diedrick (Built In Chicago)
November 2, 2017

Showcasing some of the great data-driven and machine-learning talent here in Chicago. Brought to your by Groupon, hosted by Built In Chicago.

See more videos from Groupon and our friends.

Grox: The Art of the State

Grox: The Art of the State

Grox: The Art of the State

Alin Turcu
Android Software Engineer
November 2, 2017

Once upon a time, you started a new app and everything was simple and nice: a few features, a simple UI and that’s it. But then it became bigger and bigger, and the logic became more complex, more entangled. Suddenly, you have a database, you have multiple network calls, several components talking to each others on different threads, callbacks everywhere and multiple user interactions.

The state of your app is modified from everywhere and at any time. At this point you can’t even clearly say in which state your app is after a user interacts with a few elements in the UI.

Let’s consider a typical Android App

Our apps do things like interacting with a server, with the local disk storage, and the UI. All these interactions can change the state of our app and can happen on different threads. How can we easily coordinate all this without losing our clear state?

Grox

Grox is an open source library inspired by Flux, Redux, Cycle, and Rx Managed State that makes it easier to manage the internal state of complex applications.

Let’s see how the above diagram would change with Grox.

Wow… That’s a lot of new stuff!

Let’s walk through all the elements in the diagram.

Grox concepts

Grox comes with 3 different modules.

The “Grox-Core” module defines the Action and Store classes.

The Store is the component that contains the state of your app. It is the unique source of truth about its state. The Store keeps state, dispatches actions and notifies its listeners of state changes. This part of the library is synchronized so only one action can change the state of the store at a time.

There is a second variant of the Grox-Core module, called “Grox-Core-Rx“ which uses Observable instead of a list of listeners.

Actions change the state inside the store, and in turn the store will emit the new state. Actions are pure functions, 100% reproducible and testable, their only purpose is to create a new state from the old one. The above diagram exemplifies how the store and actions work together. Actions are generated by commands.

Commands produce a stream of Actions. They are part of the Grox-Commands module and are based on RxJava. Commands return a stream of actions represented by an Rx Observable. Every possible output of the command is mapped to an Action. Commands are used in Grox to interact with non-pure logic, not 100% reproducible parts of your app such as a network call, an interaction with the file system, etc. Events are generated by user interactions or by system evens like push notification or location change. They are mapped to commands that get triggered when an event occurs.

How to Grox

Let’s use the concepts described above to create a login screen.

The sequence of events would be something like this:

Let’s see what happens when the user presses the login button:

  1. A click event is generated.
  2. A command will be started that will make a HTTP call to our server. This command knows the sequence of steps to be executed for the “Login use case”
  3. The first action the command will emit will create a new state that will represent the “login in progress state”.
  4. Once the HTTP call is completed, the command will emit a new Action that will change the state from “login in progress state” to “login finished successful” state.

The app will receive the new state from the store by subscribing to a stream of states. These states will be used to change the UI of your app. This way the UI becomes a passive representation of the state.

Enough talking, show me code!

Grox works wonderfully with RxJava so we will also use it in our example. Grox does not impose the use of RxJava, we can use the Store and Actions without it but we would need RxJava if we want to use commands.

First we define our login states.

Next, we build the initial state of the store. In the initial state we have no logged in user and the login request is not started.

Let’s see how the Login command looks like:

In the above example we assume that we have a LoginApiClient class that performs the actual network request and throws an error if the request fails or returns an error code different than 200. We perform the request in a separate class and we pass it as a parameter so we are able to test this command by mocking the loginApiClient object. The LoginApiClient returns the logged in user if the request is successful

All the outputs of a command must be actions, even in the case of errors. At the network layer, errors do occur but in upper layers, they will represent a state of the app. In case of an error, a new “error state” is created and the UI can display it accordingly.

Using the RxChain, we map the successful result of the request to a LoginSuccessfulAction and in case of an error to a LoginFailedAction. We also start with a LoginInProgressAction so, we change the state to “in progress” which will make the UI display a progress indicator while the actual network request will be performed.

The LoginSuccessfulAction and the LoginInProgressAction are very similar, their responsibility is to create a new state using the old one.

LoginSuccessfulAction saves the logged in user in the store so that the UI can display the user details.

The LoginInProgressAction works exactly in the same way. It just sets the loginState to LOGIN_IN_PROGRESS. Pretty straightforward, right? LoginFailedAction should also look familiar by now.

As you can see in the example, actions are pure functions and are easy to test. They are 100% reproducible (so, no network calls, no disk access, etc. as they can fail). The non-reproducible part of the job of our app goes into commands.

Wiring everything together

Ok. We have built all our components. Every component is encapsulated, testable, and has a clear responsibility. The next thing we need to do is to wire everything together. This can be done inside the View or inside the Presenter, it depends on what kind of design you have inside the app. For simplicity in our example we wire everything inside the LoginActivity.

Let’s walk through what is happening here. First we subscribe for store updates. states is a static method in Grox library that receives the store as parameter and returns a stream of states. We observe these states on the main thread and we update the UI once a new state is emitted.

Next, for every click event, we create a LoginCommand and we “launch” it by calling the actions() method. This method will return a stream of Actions that will be dispatched to the store. If we use RxBindings the code becomes even more elegant:

Now you can clearly see that the click event is mapped to a LoginCommand. That’s it! Pretty simple, right? We can now apply this design for every event and every operation in your app.

Once you start to Grox, you never go back

Smart people doing interesting work

Join us!

Grox your Android app!

Grox provides a clean solution for managing the state of an app. The main benefits of using the Grox design are:
Clear Concepts: Every entity described above has a well defined role. Grox provides a clean architecture, with a clear separation of concerns between state, store, commands, events.

  • Unified Process: Using Grox design you can actually represent everything that can change the state of your app or of a certain screen. All parts of an app, all screens, can use Grox to unify their handling of state. You can represent user interaction and you can represent operations. These operations can have different purposes like accessing the file system, making network request or even performing some computations.
  • Scalable: You can add as many operations as you want and your app state will still be clear at any time. The same design easily scales to all events and for every operation that changes your app’s state.
  • Testable: All the components that you create using Grox can be tested.

More info:

Github: https://github.com/groupon/grox

Cool introduction video:

Thanks to Stephane NICOLAS, keith smyth, Cody Henthorne, Eric Farraro, Samuel Guirado Navarro, David Dumitru, and Mihaly Nagy.

How I Learned to Love Unit Testing with Toothpick

How I Learned to Love Unit Testing with Toothpick

How I Learned to Love Unit Testing with Toothpick

Siqi Guo
Android Software Engineer
October 13, 2017

Once upon a time, you started a new app and everything was simple and nice: a few features, a simple UI and that’s it. But then it became bigger and bigger, and the logic became more complex, more entangled. Suddenly, you have a database, you have multiple network calls, several components talking to each others on different threads, callbacks everywhere and multiple user interactions.

The state of your app is modified from everywhere and at any time. At this point you can’t even clearly say in which state your app is after a user interacts with a few elements in the UI.

Mocking

In object-oriented programming, a class usually depends on other classes. However, as a good practice, you should only test one method of one class at a time. If a test interacts with more than one class, it would not be a unit test, but an integration test instead. In that case, when the test fails, it’s not clear which unit caused the failure. It could be the class under test or one of its dependencies.

Mock objects are commonly used to isolate the class under test from its dependencies. They are created to mimic the behavior of real objects. We can use mocked versions of the dependencies instead of real ones when unit testing. The class under test is unaware of whether the dependencies are mock or real objects. So we can test that the class under test behaves as expected by controlling the state of the mocks.

Here is an app, inspired from our business domain at Groupon, that sells deals. It uses the MVP pattern:

  • DealActivity is used to display the details of a deal.
  • DealPresenter is the presenter of DealActivity. It is responsible for reacting to user interaction and updating the view. DealPresenter has four dependencies, DealUtil, DealApiClient, WishlistManager and DealViewStateModel.

  • DealUtil is an utility class for deals.
  • DealApiClient is used to make network calls.
  • WishlistManager is used to add or remove the deal from the wishlist.
  • DealViewStateModel contains no logic. It is simply a bundle of variables that represent the view state. There is no method in that class, so nothing to mock.

DealPresenter needs to be isolated from its dependencies, when we are testing it. We can do this by creating mock objects for DealUtil, DealApiClient and WishlistManager. Then, expose these mocks to DealPresenter with Dependency Injection.

Dependency Injection (DI)

The intent behind DI is to decouple the dependencies from a class by passing in instances of those dependencies.

In the example above, instances of DealUtil, DealApiClient and WishlistManager are not created by DealPresenter, but are passed into its constructor.

How can DI make mocking easy? The class under test is not in charge of instantiating it’s dependencies. They will be passed to the object by the DI and the object just has to use them. Consequently, when unit testing, we can pass in mock objects which have the same interface as the real dependency.

In the previous example, we can pass in mocks for DealUtil, DealApiClient and WishlistManager, when testing DealPresenter. Note that we do not inject it but instantiate it manually, hence there is no need to mock the DealViewStateModel.

Toothpick

DI seems simple to implement in the example above, but if there are more classes in project, it’s not so simple anymore. In the graph below, class A has dependencies B and C, and class C has dependencies D and E. If we want to create these classes using DI, we need to inject D and E into C, then we need to inject B, C, D and E into A. Try to imagine in a real Android app, the dependency tree may be much bigger, it is a disaster to implement the DI manually. 😱

So we usually use dependency injection frameworks. You may have heard of some popular ones such as Dagger or Roboguice. At Groupon, we actively contribute to many open source libraries and have also developed a DI library named Toothpick. It’s as fast as Dagger, but designed with ease-of-use in mind. If you are interested in the library, you can get more info from Github.

Creating dependencies is really easy with Toothpick, we just need to annotate the fields with @Inject. Toothpick will create the dependencies and assign them to the right field for us:

But let’s go back to our topic, why am I talking about Toothpick? Because it comes with advanced test support!

ToothPickRule

Toothpick supports Mockito and EasyMock test frameworks. We will use Mockito in our example. Mockito comes with a JUnit Rule, MockitoRule. MockitoRule injects mocks into the fields that are annotated with @Mock, that way we can use them both in our test and in the class under test at the same time.

Afterwards, we can include the ToothPickRule provided by Toothpick. It does two things:

First, the ToothPickRule will create a real instance of the class under test.

Smart people doing interesting work

Join us!

Second, it will inject the dependencies of the class under test. If we have created a mock using the MockitoRule, it will inject that mock inside the class under test. Otherwise, it will create a real object and inject it.

So for our example these would be the steps:

  1. ToothPickRule creates dealPresenterUnderTest.
  2. It finds four fields annotated with @Inject in DealPresenter: DealUtil, DealApiClient, WishlistManager and DealViewStateModel.
  3. It tries to inject DealUtil into dealPresenterUnderTest and finds that we have defined a mock for this type with MockitoRule, so it will inject the mock.
  4. Same with DealApiClient and WishlistManager.
  5. While injecting DealViewStateModel, as we haven’t defined any mock for that type, it will inject a real one.
  6. We have our class isolated and ready to be unit tested!

Conclusion

Although there are some alternative DI libs available for Android and Java, Toothpick is still worth checking out. It is effortless to use and provides powerful test support. Thanks to the ToothPickRule, we can inject the mocks inside the class that we are testing in an simpler manner.

Unit testing helps improve your code quality and it becomes more and more important as you scale your projects. With Toothpick, you will start to enjoy writing unit tests, so I recommend you to go try it out!

With 💚 , the Groupon Android team.

Thanks to daniel hw, Jaden Choi, Eric Farraro, Aolei Zhang, Stephane NICOLAS, David Luu, Weihua Wang, Alin Turcu, and Michael Ma.

From Fragments to Activity: the Lambda Way

From Fragments to Activity: the Lambda Way

From Fragments to Activity: the Lambda Way

Stephane Nicolas
Senior Software Engineer
September 28, 2017

Activities have their lifecycle, and the same goes for Fragments. Hence, communication from Fragments to Activities is notoriously problematic.

The communication between Fragments and Activities cannot be as simple as passing a listener to the fragment that the activity could implement: the Activity would soon rotate and the Fragment would keep a reference to an Activity that had died and would leak. Google recommends a “good old pattern” to achieve this goal and limit the risk of leaks. In this article, we will demonstrate that lambdas are a better solution, more expressive, and easier to maintain.

We have created a Github repo that contains the code of our solution: https://github.com/stephanenicolas/activtity-fragment-lambda

The Good Old Way

The official way to make a Fragment communicate with its hosting Activity involves creating a communication interface and to implement it in the Activity:

The Fragment will get a reference to its hosting Activity and use an ugly and risky cast to communicate to the Activity via the communication interface:

There are various issues with this approach:

  1. the casting statement is ignominious and fails at runtime.
  2. you don’t see clearly how the Fragment and the Activity are linked. The link is more implicit than explicit.

This makes the Good Old Way crash-prone, and hard to maintain. Let’s try something different!

The Lambda Way

The Lambda Way will favor composition over inheritance. We don’t want our Activity class to implement the communication interface anymore:

Our communication interface is modified to use any Activity. Thus it becomes independent of the Activity instance and won’t leak it:

We will see below why it uses a generic and it is Serializable.

The Fragment will pass its current hosting Activity instance to the listener when it wants to communicate with it:

And here’s the key: the activity will now set a listener to the Fragment, using a simple method reference.

What is this method reference : MainActivity::onArticleSelected?

This is one of the tough questions of this approach, and it gives us an opportunity for a good dive into the Java syntax.

Actually, MainActivity::onArticleSelected is an ambiguous java statement. It can represent:

  • either a reference to a static method;
  • OR a reference to non static method of object of a specific type.

If onArticleSelected was a static method of MainActivity, we could refer to it via MainActivity::onArticleSelected. Referencing a static method is the most typical use of this type of reference.

But, in our case, onArticleSelected is not static. So, we would usually refer to it as mainActivityInstance::onArticleSelected. This method reference would point to the non-static method onArticleSelected. You could use, for instance, in a Rx chain to map an observable of positions:

So, what does MainActivity::onArticleSelected refer to?

Internally, all non-static methods in Java are compiled in the same way as static methods, but with one hidden first parameter of the type of its enclosing class. Thus, the 2 methods below are almost equal from the byte code perspective:

The method reference MainActivity::onArticleSelected is a reference to the second form of this method. It is now pointing to a method that takes 2 parameters: a MainActivity and a int.

This second method is interesting for us because it is independent of the MainActivity instance. Hence, a reference to it doesn’t leak the activity instance!

From a lambda perspective, the meaning of this method reference is now slightly different: it is indeed a method that accepts a MainActivity and invokes the method onArticleSelected on this activity:

MainActivity::onArticleSelected is equivalent to activity -> ((MainActivity)activity).onArticleSelected(position)

In other words, MainActivity::onArticleSelected is a method reference to a HeadLineListener implementation that is independent of the activity and will work with any instance of MainActivity.

For a fine-grained explanation of method references, please visit the official Java documentation.

Smart people doing interesting work

Join us!

Disambiguating MainActivity::onArticleSelected

As explained above, this method reference can be misunderstood by the Java compiler. It could understand it as a static method reference. In order to disambiguate it, both the interface HeadlineListener, and the method HeaderFragment#setHeadlineListener will use generics to trigger what is called a target type inference:

Thanks to these 2 generics, the compiler understands that the future method reference passed to setHeadlineListener as a reference to a non static method of object of a specific type, and it will only accept references that point to a method inside a class that extends Activity. This last constraint is reasonable because, from a Fragment perspective, we can easily get the hosting Activity using getActivity(). This is why we can now invoke our listener method on the current Activity:

Surviving the Fragment Lifecycle

The last point is to make sure that our fragment still knows about its callback when it dies and it is recreated by the FragmentManager (e.g. after a rotation). For this, we will serialize the listener into the arguments of the fragments.

In our Github repo, we opted for a very structured approach to create our HeadlineFragment by using a builder pattern. The builder will let you create the fragment with an appropriate listener. Of course, the builder is not mandatory for the “lambda way” to work, you just need to serialize the lambda and you can do it the way you want.

It is generally advised not to serialize lambdas in Java, exactly for the same reasons as inner classes. Nevertheless, this issue is softened here as:

  • On Android, serialization is short term and cannot create issues during application upgrades and class changes.
  • The lambda/method reference is fully static and stateless, and is intrinsically protected from any serialization issue as it can’t contain any reference to a non serializable element nor refer to entities that could have died (e.g. the Activity or the Fragment).

Conclusion

This new approach is quite technical, we agree on this. It also infringes the general rule of not serializing lambdas. However, we believe that this approach brings a few benefits to our code base:

  • The link between Activities and Fragments is now explicit. It can be traced easily inside our IDE as opposed to implementing an interface the Good Old Way.
  • We got rid of the hideous casting of the Good Old Way.
  • We favor composition over inheritance.
  • Code looks quite close to the rest of our modern Rx chains.
  • When using a Fragment with such an API, using the listener interface is as easy as using a method reference and most of the complexity of the solution goes behind the scene.
  • It enforces building fragments using a builder pattern to setup the arguments which reduces bugs at runtime.

Thanks to Samuel Guirado Navarro for bullet-proofing the approach.

Let us know what you think, and thx for reading this article!

With 💚 , the Groupon Android team.

Thanks to Carlos Sessa, Mihaly Nagy, Alin Turcu, Cody Henthorne, daniel hw, Eric Farraro, and Samuel Guirado Navarro.

Dependency Injection Checks

Dependency Injection Checks

Dependency Injection Checks

Mihaly Nagy
Android Software Engineer
August 15, 2017

Dependency Injection is great to design testable and modular apps, but whether you use Toothpick, Dagger or any other library, there are some tricky problems that come with DI. They can be hard to detect and quality and static code analysis tools (like pmd, findbugs, etc.) can’t help you to solve them.

At Groupon, we ❤️ Open Source software, and we decided to release a tool we developed internally. In this article we introduce Dependency Injection checks that will help you solve some issues that are common to all JSR 330 DI libs.

As code complexity grows, it can be difficult to track all of the dependencies that a particular class uses. This problem is even more complicated when we take inheritance into account. If multiple classes in a hierarchy inject the same dependency, it is perfectly valid from the language perspective, but it leads to slower runtime as you create the dependency subtree multiple times and your dependencies can get out of control. Let’s take a closer look at this issue we call a “duplicate injection”, and how we can use the new ‘Dependency Injection Checks’ library to automatically validate our design:

You’re writing a component “Foo” that uses an util class called “Waldo”, so you inject “Waldo” in that class. Now this class “Foo” in time is extended by “Bar” and “Baz”. Your project evolves and now you have another class “Qux” extending “Bar”.

There’s a new requirement in “Qux” to use “Waldo” for something, but by this time you already forgot all of the injected members of “Foo” so you inject the “Waldo” in “Qux.”

So now you have “Waldo” as a member of both “Foo” and “Qux”, and this is perfectly valid, but it’s not a good design since you can change the visibility of “Waldo” from “Foo” to “protected” and use it in “Qux” as well.

There is no tool to catch these sort of errors, and they creep into the cleanest of codebases.

Dependency Injection Checks

Open Source library is an annotation processor that detects common DI related issues (like the one described above). When a duplicate injection is found, compilation fails, pointing you to the right place in the codebase to fix your issue.

The library uses annotation processing to build up an internal model of the hierarchies that use the @javax.inject.Inject annotation (JSR 330). It then checks to see if an injection is found twice in a hierarchy and records the place where this mistake occurs. Once all the injections are processed it checks for errors and gives the compiler a non successful exit code if one is found.

As mentioned above this will work with DI frameworks that rely on JSR 330 (e.g uses the @javax.inject.Inject annotation) like Toothpick, Dagger and much more.

We designed the library to extend it and add more checks related to dependency injection and we have a plan to add some in the future, like making certain classes forbidden for injection.

You can check it out here: https://github.com/groupon/dependency-injection-checks

Feel free to use it in your projects, share it with other projects that might benefit an automated check like this.

We would be happy to get your feedback in this article, and invite every one to contribute with GitHub issues or even pull requests to our new project.

Data Driven Chicago

Data Driven Chicago

Data Driven Chicago

P. Edward Herman, Senior Data Scientist (Avant)
Saranga Komanduri, Tech Lead (Civis)
Laura Hamilton, Group Product Manager (Groupon)
Andrew Paley, Director of Product Design (Narrative Science)
Adam McElhinney, VP of Data Science (Uptake)
June 2, 2017

Chicago is a hotbed of data-driven and machine-learning work, but you’d be forgiven for not realizing it. In order to shine a bigger spotlight on this technology and the great Chicago companies using it, Avant, Civis Analytics, Groupon, Narrative Science and Uptake are partnering to host an after-work open house

See more tech videos from Groupon and our friends.

Better Android Intents with Dart & Henson

Better Android Intents with Dart & Henson

Better Android Intents with Dart & Henson

Daniel Molinero Reguera
Software Engineer
June 2, 2017

Intents are an essential part of the Android ecosystem. They are used to express an action to be performed and can be classified into implicit and explicit intents. In an abstract way, all intents together define a navigation layer inside an application. In this article we will explain why the Android way to create explicit intents is error-prone and also show some problematic ways to solve it. Finally, we will introduce Dart & Henson, a library that generates this navigation layer and make it easy, convenient, fast and robust to navigate among your activities and services.

Explicit intents are used to run specific components, habitually application internal activities or services. Together with the intent, additional information can be provided to the target components using extras. For instance, the following code creates an explicit intent and triggers an activity:

And this could be the activity being started:

This mechanism is great for component creation and communication, but there are some issues to keep in mind:

  • The target component as an entity, does not have any control over its input. In our example, itemId is mandatory, but the “best” DetailActivity can do is to fail at runtime.
  • The intent creation is not robust (at all), there is no check on the keys or values attached to the extra bundle.

An ounce of prevention is worth a pound of cure.

Problematic ways

A possible solution to those concerns is the Intent Factory pattern. It mainly consists in a factory class which encapsulates methods for every kind of Intent that an application needs. For our example, this might be the Intent Factory:

However, this approach is far from a suitable solution considering that it comes with some constraints:

  • The Intent Factory is a large, complex and centralized class.
  • It infringes the Meyer’s open/closed principle. It will never get closed, we will always add new methods for each new activity.
  • The target component is the one which knows about the parameters, it should be the one containing the logic.
  • Optional parameters handling. Should we have a bunch of different methods for the same component? Just one method and send default values?
  • It can quickly become tempting for developers to couple methods of the intent factory, one calling others.. and this will become a big ball of mud.

There is a similar strategy which involves distributing these factory methods among the target components. In other words, each component contains one static method (or more) to generate the intent that should be used to start it. It would solve the Meyer’s principle problem, decentralize the intent factories and probably make it easier to avoid the big ball of mud. Nevertheless, the problem about dealing with optional parameters persists. Someone said builder design pattern? Implementing it ourselves?

I choose a lazy person to do a hard job. Because a lazy person will find an easy way to do it.
-Bill Gates

Smart people doing interesting work

Join us!

Dart 2 & Henson

Dart is an Open Source library for Android. It binds activity fields to intent extras, in the same way Butter Knife does between activity fields and views in XML layouts. Applying it to our example Activity, it evolves into:

The @InjectExtra annotation specifies that a field corresponds to an extra with the same name key. By default, all annotated fields are required and an exception is thrown if the extra is not provided. To remove that check and make it optional, the @Nullable annotation needs to be added. Then, calling Dart.inject is enough to inject the extras using the generated code.

At Groupon, we realized that the information given by those annotations was enough to create the builders that we are looking for. Thus, we decided to bring Dart to higher levels: we introduced an annotation processor that generates the Intent builders for us. This new module is called Henson and is included in Dart 2.

For our DetailActivity, Henson produces a small DSL to navigate to it easily:

The first step is to get the builder for the target activity or service, for that we use Henson.with(context).gotoXXX(). Then, the mandatory extras need to be set using the generated methods named after them. For example, itemId is set using itemId(String str). After that, optional extras can be set using the same approach. And finally, just build and you will get a valid Intent to start your target component!

The DSL is created for all classes which contain @InjectExtra fields. These represent a navigation layer that solves our problem about creating intents:

  • The target component has full control over its extras through the annotations.
  • The DSL is defined in one place, inside the component. If it is updated, any issue is found at compile time.
  • The Meyer’s open/closed principle is not violated. Indeed we have nothing to write, everything is generated for us
  • Optional parameters can be easily provided, since the builder design pattern is used.
  • And it comes with auto-completion!

A full working sample can be found here.

Conclusion

Henson creates a small DSL to build intents to your activities and services in a robust way, making it impossible to miss a required extra and flexible enough to add optional arguments as needed. And the best of it, there is no need to write a single line of code, just use Dart 2 and Henson. 😊

Why not to try it?

Android’s multidex slows down app startup

Android’s multidex slows down app startup

Android’s multidex slows down app startup

Michael Ma
Android Software Engineer
December 17, 2015

The 65k method limit is a problem that has been addressed time and time again within the Android community. The current state of Android addresses the issue with multidexing. While multidexing is an excellent solution by Google, I’ve noticed a significant impact on app startup performance which has yet to raise any attention in the community. I wrote this article for developers who have never heard of this issue (but would like to implement multidexing) and to folks who already have multidexing but would like to observe the performance gains that I’ve seen with my solution.

Context

For the uninitiated, Android apps are written in Java which is converted into a .class file. This class file (and any jar dependencies) are then compiled into a single classes.dex file. This dex file is then combined with any resources needed into a .apk file: which is ultimately what you download from the app store. Read more here.

One limitation with this compilation process is that the system only allows up to 65k methods within a single dex file. In the early days of Android, applications that hit the 65k method limit addressed the issue using Proguard to shrink any unused code. However, this approach is limited and only delayed the inevitable approach to the 65k method limit for production apps.

In light of this issue, Google has released a solution in the recent Android Support Libraries to address the 65k method limit: multidexing. This solution is handy and will allow your app to break well beyond the 65k method limit, but (as I’ve said before), there is a significant impact on performance which may slow down your app startup.

Setting up multidex

Multidexing is a fairly mature solution with great documentation. I highly recommend following the instructions on the Android Developer site to enable multidex in your project. You can also refer to the sample project in my Github.

NoClassDefFoundError?!

While setting up multidexing for your project, you may notice a java.lang.NoClassDefFoundError when running your app. This means that the class for app startup is not located in the main dex file. The Android plugin for Gradle in Android SDK Build Tools 21.1 or higher has multidex support. This plugin uses Proguard to analyze your project and generate a list of classes for app startup in the file [buildDir]/intermediates/multi-dex/[buildType]/maindexlist.txt. However, this list is not 100% accurate and may miss some of the classes necessary for app startup.

YesClassDefFound

To solve this, you should list those classes in the multidex.keep file to let the compiler know which classes to keep in the main dex file:

  • Create a multidex.keep file in your project folder.
  • List classes reported in the java.lang.NoClassDefFoundError into the multidex.keep file (note: don’t modify the maindexlist.txt in the build folder directly; this is generated every time the app compiles).
  • Add the following scripts to the build.gradle in your app. This script will combine your multidex.keep and maindexlist.txt generated by Gradle while compiling your project.

Multidex app startup performance impact

If you use multidex, then you need to be aware that there will be an impact on your app startup performance. We’ve noticed this by keeping track of our app’s startup time — defined as the time between when a user clicks on the app icon up to when all images have been downloaded and displayed to users. Once multidex was enabled, our app startup time increased by about 15% on all devices running Kitkat (4.4) and below. Refer to Carlos Sessa’s Lazy Loading Dex files for more info.

The reason is because Android 5.0 and higher uses a runtime called ART which natively supports loading multiple dex files from application APK files. However, devices prior to 5.0 have extra overhead when loading classes from dex files outside of the main dex.

Smart people doing interesting work

Join us!

Addressing the multidex app startup performance impact

In the span between when the app starts and when all of the images are displayed, there exist many classes which are not be detected by Proguard and thus not stored in the main dex file. The question is, how can we know what classes have been loaded during app startup?

Fortunately, we have the findLoadedClass method in ClassLoader. Our solution is to do a runtime check at the end of the app startup. And if there is any class stored in the second dex file and that loads during app startup, then we move them into the main dex file by adding the class name into the multidex.keep file. My sample project will have the specific implementation details, but you can do this by:

  • running getLoadedExternalDexClasses in the following util class at the end of what you consider to be your app startup
  • adding the list returned by the method above to your multidex.keep file and then recompile

Results

Here are the startup performance improvements that we’ve observed in our app across multiple devices. The first column (blue) is the base app startup time without multidexing. You can see the significant time increase in the second column (red), which is the app startup time when we enabled multidex without any extra work. The third column (green) is the app startup time with multidex turned on and the improvements discussed. As you can see from the graph, the app startup time drop back to the same level or even faster than before turning on multidex. Give it a try and you should notice performance improvements as well.

multidex

Afterword

Just because you can doesn’t mean you should. You should treat multidexing as a last resort since it has a big impact on app startup and in order to address it you need to maintain extra pieces of code and solve strange errors (e.g. java.lang.NoClassDefFoundError). Once we hit the 65k method limit, we initially avoided multidexing in order to stave away the performance impact. We kept metrics and investigated the SDK’s that we were using and found a lot of useless code that could be removed and refactored. Only when there were no options left did we consider multidexing, and by then our code quality and standards had improved by leaps and bounds. Instead of jumping straight into multidexing, consider looking into keeping your code clean, reusing existing components, or refactoring your code in order to avoid the 65k method limit.