Thursday, December 18, 2014

Clio’s Road to Android


Disclaimer: I am a software developer at Clio and this post is also published at Clio Lab; since I am an author, I believe it is okay to publish here.

There’s a saying at Clio: “draw the fucking owl.” Last year, for me, that owl was an iOS app. This year, it was the Android app. From absolutely no Android app development experience to leading a team of six amazing product members and building a full-spec practice management app, it’s been truly an amazing journey.

On September 22nd, when I witnessed the launch of the Android app at the Clio Cloud Conference in Chicago, I was absolutely amazed at how everything came together.


The Beginning

It’s hard to believe that it was only eleven months ago that we started the project. I was definitely nervous. It wasn't really because of the new responsibilities that came with being a team lead; it was because I had no experience with Android, yet I had to lead a team of developers and make a million decisions. I powered through a handful of Android development books and met with a few key players in Android development communities in Vancouver. I want to thank Jerome from Amazon, Mike Worth, and Jeff Stautz from HootSuite for giving me advice and tons of tips. I also went to a local mobile app development shop, SteamClock Software, and arranged a workshop; in two days, we covered topics like multi-threading, UI implementation, animations, best practices, and some major differences between iOS and Android. These were just some of the steps I took to get into the Android game.

Our team started with one product manager who oversaw both Android and iOS as well as API, one UI designer/developer, and three developers including myself. We added another developer and a new mobile QA analyst. Hiring was/still is challenging because there’s a lot of pressure to make a decision with just a few hours of interviewing, but I had to make a call. Criteria for a talented software developer remain consistent regardless of the field, but I’m definitely a lot more comfortable interviewing now with the experience and knowledge I’ve gained.

These are some of the things I look for from candidates: a deep understanding of the Activity and Fragment lifecycles, various issues with a runtime configuration change, consequences in dealing with a runtime configuration change in a variety of situations, threading, and processes, UI view elements, database knowledge, Java skills, experience with major HTTP libraries, etc. For a QA analyst, I’d like to see experience in Continuous Integration systems and configuring with mobile environment, various integration testing tools for mobile app development, and some programming experience.

It comes down to: "if you have to plan for an Android app release and need to have support for thousands of devices, multi-OS versions, and a variety of screen resolution sizes, what is your plan to meet our quality standard with these conditions and being able to confidently ship an app at a release date?" We've been working on that since the beginning and are still trying to get it right. If you can give me a solid answer for this question, you’re all set. Come chat with me. :)


Development and Tooling

One of the best decisions we made at the beginning was being aggressive about setting support for OS versions. Although the Android market is getting much better with adopting newer OS versions (especially thanks to the release of Android 4.4), many Android developers suffer from supporting older versions of OS. Having looked at the market and where it’s going, we determined that we’ll be able to cover a majority of US Android market with version 4.1 and up, and decided to go with ‘minSdkVersion 16.’ Looking back now, we definitely made a good bet. In fact, about 85% of our Android customers are on Android 4.4, which is very impressive.

We all use Android Studio for IDE. It got a lot better and more stable after Version 0.8 which came out at this year's Google I/O, and I see fewer crashes and less hassle every time I upgrade to a new version. Gladle is used as the build tool as it’s a default build tool for Android Studio. It has its own learning curve, but it’s highly customizable and comes with many preconfigured commands. For distribution, we use Google Play. It makes it very easy for us to do alpha and beta testing; this has definitely been an important part of our development cycle. Four months after starting the project, we started doing alpha testing with internal people; a month before the public release, we beta-tested with users. This gave us a lot of valuable feedback and caught hundreds of bugs prior to the public release. This built-in alpha/beta release functionality in Google Play Store is a unique advantage for Android vs. iOS development, and I am hoping to see this space improved for iOS development.
Our best friend for crash reports and monitoring builds is Crashlytics; their bug reports and detailed information about exceptions logs are a golden asset to developers.

About testing... coming from Rails development with Rspec, writing tests for an Android project is not as friendly and can get frustrating. We use Roboletric for JUnit testing and Instrumentation tests bundled with Espresso. Setting them up alone took us a few weeks to figure out. There are so many gotchas with these testing tools, and we sometimes spend more time writing tests and trying to get tests working than actual app programming. This is one place where I would like to see more improvement for Android development. We use dependency injection; we started with Roboguice and later on switched to Dagger. It gives you a lot of flexibility and lets you change configurations to deal with different environments for testing, development, and production.

For an HTTP client, we started with Retrofit but switched to Volley; Volley offers a lot more flexibilities, and it offers multi-threaded HTTP requests, providing a capability to manage request queues.

Oh and 65K DEX methods limit... you should know this since you will have to eventually deal with it. Read more about it here or from Jake Wharton.


If I had to give one piece of advice to a new Android developer…

It would be this: "an activity can be destroyed at anytime, and your code has to survive that." Activity lifecycle is by far the most important piece of this puzzle; without understanding this in-depth, you will not have a reliable application. This detailed chart for both Activity and Fragment lifecycles describes its complexity. Print that out and absorb it. All of it.

This well-defined article from our best friend Crashlytics describes the three most important issues that everyone will face: 3 Key Ways to Increase Android Support Library Stability.

In fact, for the last few weeks since the beta testing and continued through public releases, we've been constantly fighting with these issues. Understanding these problems and addressing them throughout the project is a key to increasing the stability of a project.

Related to development, we've introduced a few things to keep us informed on this very complex nature. What we call Android tea time is where team members give a brief demo on what they’ve been working on for past few weeks and walk the team through codes and designs. This brings an immediate advantage, because as a project gets bigger and complex, it’s easy to lose track of what else is going on. This is an opportunity for us to exchange ideas and share knowledge across the team. Another one is the lunch-and-learn. As soon as we face a new issue or discover a new technology, a team member is assigned to do research for a few days and come back to the team with a talk. Lastly, we've organized an information exchange night with the HootSuite mobile development team (and we’re planning to have another one with Mobify); each of us prepares five topics that we can do presentations on, and both sides pick two topics that they’d like to hear and give talks about. It’s not only beneficial to hear the talks, but also helps us learn about how other companies manage mobile products. I’d love to do this again with HootSuite and possibly other Vancouver-based companies.


Minimum Viable Product

When we plan out a road map, we handpick core functionalities of the app and choose the minimum set of features that are needed to create an useful app for users. This lets us focus on key features and work on the most important ones first, speeding up our user feedback process.


The Importance of Design

The app is described as "incredibly smooth, well designed, and intuitive” from a Play Store review. Jeff Taylor said that "Clio’s Android app is something they should be proud of. The app is beautifully designed." There is no doubt that design plays a significant role in product development here. I originally came from a web development background, without any design expertise. It used to be okay to say, “Designers work on front-end, and developers worry about back-end.” But with two years of mobile app development, I’ve come to realize that it’s no longer acceptable. I, as a mobile app developer, need to have as much expertise in mobile designs as a designer. I am not a design expert, but in order to become a better mobile app developer, I need to change that. Design will only increase in significance and it will continue to be a major part of product development in Clio.


What's Possible in Mobile

It took us close to two years to get here, but now, we have a presence in both iOS and Android. This is a significant achievement as a company. We've learned so much. We've learned what each platform can offer, what users want from the mobile apps, and how they interact with the apps. With the experience we've had over the years, we are moving up to the next iteration of mobile app products. We’ve literally just entered this space, and the possibilities ahead of us are big. I’m very excited about the road ahead—it's going to be another fun ride.

ps: we are hiring at Clio! If you are a passionate developer or designer who believes a beautifully designed software can make a difference in the world, come work with us!



Tuesday, January 7, 2014

How to create a remarkable career in Software Development

Step one: you should buy and read "The Passionate Programmer: Creating a Remarkable Career in Software Development". I just finished reading this book in the last winter break; it was probably the best way to start a new year. If you haven't read it (you should!), I found a fairly good summary entry here; having read this book, the next step is doing things. "just being good isn't enough. You have to be doing." It is nothing more important than actually doing it. I would like to go over some of the points that this book covered and planning to execute this year.

Be a generalist. Learn lots of things.
At work, I am working on an Android project right now; in spare time, I am going to learn something new. I don't know what yet, it doesn't even have to be programming related. It could be a business thing, finance, or even cooking; an important point is, be open to learn new things.

Be a specialist.
I am working on an Android app at work, so be a specialist on Android framework. It is going to be a focus of this year. Go deep into the framework, have a deep understanding of its technology. Pick a library and dive into the code. I need to develop a strong understanding of a particular topic. Android itself is still vague; a lesson is that when I am working on something, try to develop a deep understanding of subject; for example, try to look into source code and understand how things actually work.

Learn the business rules of your organization.
I need to pay more attentions to the market we (as a company) are in and know more about its business. Pay more attention to how the business works and be aware of the market I am in. I bought a book that is recommended in the book, The Ten-Day MBA. It is a step forward to understand how businesses run and knowing how companies operate.

Have a mentor.
Mentors are living examples and it is a lot easier to learn by example. I am not quite sure how I can find mentors, but I will start by talking to people that I admire and try to have a regular catch up with people in town that are working on great things.

A good way to learn things is to teach it to others. This is an advantage that comes with mentoring.
Teaching a subject to others is going to be a key point this year. At my company, we do lunch and learn where a developer talks about stuff that he is working on, or tips that they can share with others. It is a great place to start this. And we also plan to have a monthly info exchange night with other development companies in town, sharing lessons and talk about technologies that we are working on. These places will be a great learning experience and it will be a great opportunity to have a deeper understanding of a subject.

"Do not work more than 8 hours a day. But you should work so relentlessly that there is no way that you could continue longer than eight hours."

This year, my big goal is become a opensource contributor. I have not picked a particular project that I would like to contribute to, but I can start by reporting issues, fixing known bugs, or adding tests to existing code. I would like to become more active in opensource community and if I can get a patch accepted in some of the major opensource libraries, that is a big accomplishment :)

"Try to be known outside of your company for your excellence. Write blogs, give presentations at local technical meetings and even better in large conferences."
I will be more active in local tech meetups and I would like to give few talks at local meetups. This blog will also play an important role. It is a place to demonstrate my skills and show expertise on subjects. It is also a place to exercise my writing skills and communication skills, which will be an important skill to develop.

wow, that is a long list of things that I want to do this year. Don't be lazy; remember, "you have to be doing".

This year is going to be a great year. I look forward to this.

Hello, 2014.

Wednesday, November 6, 2013

How to configure a custom gson object to Retrofit's RestAdapter

From the previous post, I decided to go with Retrofit for our sync framework for our Android app. There are few reasons behind this. Retrofit offers significantly simple syntax to let us do http GET, POST, PUT, DELETE, and HEAD operations, handles mapping of JSON to Java objects and vice versa, active community and maturer than other alternatives; the fact that Jake Wharton from Square is actively developing on this makes me feel comfortable to go with them as well.

In this post, I am trying to demonstrate how you can use Retrofit to hook up with a modern API service and configure few global mapping definitions. One thing I find in Android community is a lack of intro, how to get started type of articles. Since myself is a newbie to Android development, I would like to document as much as I can to build an Android app with using whatever tools we find the best to work with (any suggestions are welcome!).

Disclaimer: I don't know what I'm doing (yet). I started an Android development literally few weeks ago, so a code sample here is not necessarily the way it should be implemented. Just keep that in mind, and I will make improvement as I get better at it.

How to install Retrofit
We use gradle for a build tool, which works nicely once it sets up correctly.
just add
 compile 'com.squareup.retrofit:retrofit:1.2.2'  
in dependencies.

Setting up Retrofit
RestAdapter is an interface to a REST API. You want to create a singleton instance for a REST API that you want to talk to.

 sRestAdapter = new RestAdapter.Builder().setRequestInterceptor(new RequestInterceptor() {  
       @Override  
       public void intercept(RequestFacade requestFacade) {  
         requestFacade.addHeader("Authorization", "Bearer yourToken");  
       }  
     })  
         .setServer(API_URL)  
         .build();  
I want to add a header with an authentication token for every request we make. so the above line with RequestInterceptor accomplishes that. Set the server URL and you're good.

This will be enough to get you started. But I needed to add few more global wide customization to RestAdapter. I want to add a global mapping rule so that JSON keys with snake_case should be mapped to camelCase keys in Java objects and vice versa. Another customization I wanted to make is I need to correctly map date and date time values to Java objects. Bit tricky thing is that we need to handle two types of dates. One with only date and the other is with time. We can accomplish these customizations by creating our own Gson object (Gson does actual mapping).

This is how I constructed a Gson object to meet the needs above.

 Gson gson = new GsonBuilder()  
           .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)  
           .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")  
           .registerTypeAdapter(Date.class, new DateDeserializer())  
           .create();  
private static final String[] DATE_FORMATS = new String[] {  
       "yyyy-MM-dd'T'HH:mm:ssZ",  
       "yyyy-MM-dd"  
   };  
private static class DateDeserializer implements JsonDeserializer<Date> {  
  @Override  
  public Date deserialize(JsonElement jsonElement, Type typeOF,  
              JsonDeserializationContext context) throws JsonParseException {  
    for (String format : DATE_FORMATS) {  
      try {  
        return new SimpleDateFormat(format, Locale.US).parse(jsonElement.getAsString());  
      } catch (ParseException e) {  
      }  
    }  
    throw new JsonParseException("Unparseable date: \"" + jsonElement.getAsString()  
        + "\". Supported formats: " + Arrays.toString(DATE_FORMATS));  
  }  
}  
and you add this gson object to the restAdapter by
 setConverter(new GsonConverter(gson))  

There you go. Now every JSON conversion will follow the rules defined above.
Making a http GET request is slightly simple and the official documentation does fairly good job of describing steps. So I won't go over that here.


Next up is setting up a database system and store the java objects after it's been mapped. I hope to address that soon.
Happy Android coding:)

Thursday, October 31, 2013

Sync framework for Android

Background: I work for Clio, we make a web-based practice management software for lawyers (and we are hiring!). We recently launched an iPhone app which I was a part of (more about the experience I had with iOS development and the project in general, here is the blog post). And we recently started to work on Android app for that. I am new to Android development, so for the past few weeks, it is all about learning Android development and researching things. One of things I am researching on right now is deciding what framework we should use for syncing.

Clio is a data-heavy app. For the iOS app, we use RestKit and CoreData as a persistent storage system. I am looking for an equivalent of RestKit in Android. I have few acceptance criteria for this. It should work well with Clio's REST API, and should be flexible enough to work with the nested attributes and polymorphic associations. And it should support JSON, and have a good community, well used, well tested by apps of similar complexity to Clio.

This post is a summary of my findings today and a conclusion I am about to make. If you have any suggestions or comment, you are more than welcome :)

I am new to Android, so if you have experience with this field, please share your experience with me. I would love to talk. Find me on Twitter at @naoyamakino.




it looks like yet another HTTP client for Android. Nothing much beyond that.



“Spring's RestTemplate is a robust, popular Java-based REST client. The Spring for Android RestTemplate Module provides a version of RestTemplate that works in an Android environment.”

“RestTemplate's behavior is customized by providing callback methods and configuring the HttpMessageConverter used to marshal objects into the HTTP request body and to unmarshal any response back into an object.”

HTTP Client: used default ClientHttpRequestFactory,  when you create a new RestTemplate instance. (the standard J2SE facilities)
Google recommends to use the J2SE facilities on Gingerbread (Version 2.3) and newer, while previous versions should use the HttpComponents HttpClient.
RestTemplate supports sending and receiving data encoded with gzip compression.
Libraries that are used for JSON mapping: Jackson JSON Processor, Jackson 2.x, and Google Gson.
RestTemplate provides higher level methods that correspond to each of the six main HTTP methods. These methods make it easy to invoke many RESTful services and enforce REST best practices. For example, the method getForObject() will perform a GET, convert the HTTP response into an object type of your choice and return that object. The method postForLocation() will do a POST, converting the given object into a HTTP request and return the response HTTP Location header where the newly created object can be found.
Objects passed to and returned from the methods getForObject(), getForEntity(), postForLocation(), postForObject() and put() are converted to HTTP requests and from HTTP responses by HttpMessageConverter instances.
You can also write your own converter and register it via the messageConverters property (customizable)
RoboSpice is a modular android library that makes writing asynchronous long running tasks easy. It is specialized in network requests, supports caching and offers REST requests out-of-the box using extension modules.
- executes network requests asynchronously (in a background AndroidService)




RestTemplate from Spring seems to accommodate most of my needs. it handles HTPP requets/response, and do a mapping from JSON to Java objects and vice versa. It looks pretty cool. I haven't tried it yet, but I like it so far from the readings I've done. If you have any suggestions or things I might want to know, please let me know.


Journey with Android development continues..

Monday, September 2, 2013

Absolute Insanity @ #BurningMan2013




When it comes to Burning Man, insanity means it really means it. I've been thinking about how I could describe the experience in Burning Man to others. I could say nothing but insane. It is as if you flip a coin, everything is flipped to opposite; normal becomes abnormal, real becomes unreal, and sane becomes insane. There is no single sober person in that city, everything you see is insane; art, architecture, food, drink, buses, everything.



It was my first trip to Burning Man, a week-long celebration of art, music and general mayhem. Burning Man participants share ten principles. I was amazed how well it was executed, applied to every corner in Black Rock City. We instantly faced welcomes from everyone in the city a second after we stepped in, and it took me while to adapt norm of radical self-expression.
 


In Black Rock City, we gift everything. Wake up in the morning, drop by a next door and grab a coffee, wander around the city with a mug, poured beer at a themed bar, exchange a costume. Everything happens without exchange of currency.

As an attempt of gifting, I volunteered as a temple guardian. It was freezing cold after midnight but worth an experience with other volunteers and shared one of the most memorable moments, seeing sunrise.



Wandering in a city myself one night, I felt I am still not a part of this big project yet. I am taking too much and not enough of gifting. This is something that I need to work on for a next visit, if that day ever comes again.

One of takeaways.
If you think you are crazy, you are probably not crazy enough.




here are few photos I took at Burning Man.










Thursday, June 13, 2013

"Whatever you do will be insignificant, but it is very important that you do it." via Mahatma Gandhi

"Don't let life randomly kick you into the adult you don't want to become." via Chris Hadfield

“Well, folks, it’s a good life if you don’t break too many guitar strings. And it’s pretty good life if you do." via Simon Whitfield


"Life can be much broader once you discover one simple fact: Everything around you that you call life was made up by people that were no smarter than you and you can change it, you can influence it, you can build your own things that other people can use." Steve Jobs

Thursday, May 2, 2013

RailsConf 2013



I just wrapped up my first RailsConf in Portland. Overall, it was a great experience with a lot of learnings, mingling with whole bunch of people and getting good beers every night.
here are my notes on the lectures that were worth sharing. the orders are by my best interests.

there are quite few good talks about APIs and gave me few useful tips that we could add to our API.
- How to Write Documentation for People That Don't Read Kevin Burke
tips about writing good documentations for both internally and publicly. Kevin is from Twilio and an engineer of their API. There are good examples from various API docs that we can take good practices (eg: error reference page, breaking up the contents by verbs..) Highly recommended to check the note and the slides.

- "Designing great APIs: Learning from Jony Ive, Orwell, and the Kano" via @jondahl
another API engineer from Twilio. API is an interface. looking from an API user perspective, he talked about how API can delight users. some suggestions are API wrapper, request logs, sandbox API, API builder (Zencoder API Builder). None of them are necessities, but having things like those will differentiate from other APIs and will delight API users. 

- Using Elastic Search with rails app via Brian Gugliemetti
Search is hard, how can we make our search less suck? this is worth checking.

- How Shopify Scales Rails via @JohnDuff
Moved away from DelayedJob to Resque, use of Redis, MySQL tuning, caching gems etc. (presentation video link attached in the end of the note)

- Rails vs. The Client

- Dissecting Ruby with Ruby - Richard Schneeman
described few tipis on how to debug through rails code and potentially become a bug reporter to bug fixer!

- Building Extractable Libraries in Rails via Patrick Robertson

- Testing HTTP APIs in Ruby

The word of the conference was from James Duncan Davidson's keynote.
"Create more value than you capture" via Tim O'Reilly. 
He emphasized the importance of contributing to OpenSource communities and help make a world better place. 

The whole conference was surrounded by very positive atmosphere and felt a lot of open source community love, which was different from Goolge I/O that I attended last year.

Last not least, witnessing Aaron merging one of our teammates' pull requests to rails/rails was one of the most memorable moments of this week.

Time to go enjoy a last night with Portland beer.