Talks From Facebook, Paper Team

During the long weekend of Easter holiday, I spent some time on watching tech talks from Facebook. The newly uploaded “Building Paper 2014” series is really cool. Even I don’t do iOS, seeing how they tackle the problems and share their approach is totally enjoyable.

Android and iOS apps may have different platform structures, but when your app goes bigger, most likely you will need another level of abstraction to handle large amount of logic, UI and communication betweens components. And when you want further performance tuning, you may need to go beyond the platform like what Paper team did. At that stage, although you are using different languages, the architecture will be similar across platforms.

I also like the part about contextually aware tutorials, if you have time, you should watch the whole event.

UI details and A/B test

Besides new talks, I also watched an old talk from “Mobile Developer Day by Facebook + Parse 2013”. Not sure why I skipped this talk before, probably because the title is so generic – Mobile at Facebook. The part that caught my attention is the A/B testing on their drawer to nav bar changes. It’s not about what framework they used, not about how many users they put in the AB test, it’s about how you see the numbers.

She mentioned that after changing the drawer to nav bar, the result in internal test is good, navigation experience is improved, users feel the app faster. However, when they shipped to 1% test, they find that users liking and commenting less, because users are kind of distracted by the nav bar notification.

This is very interesting to me. We do not have a very detailed metrics system on mobile (have some, but not detailed), I am sure if we do AB test like that, we will not be able to see the abnormal usage changes. This even put me in a doubt that what if we already did changes like that and we still don’t know that?

This is like a regression test, not on code but on usage.

Android Image Decode Bug on Samsung Devices

Image decode bug on Samsung devices

Few weeks ago I got some users reported about seeing “black lines” on the images. In 9GAG app, displaying images is everything so I can’t just leave the problem unsolved.

At first I thought it is a problem I worked on before that when multiple download tasks running for the same image, may corrupt the file. However, this time is a little bit different.

I checked those reports and find that only users using (high end?) Samsung devices (S4 and Note3) hit this problem, and I cannot reproduce the problem on my testing devices. Luckily, we recently equipped a Samsung Galaxy S4 in office so I can schedule some time on this problem. And they are actually not black lines, they are transparent lines…

Even I suspected it is a manufacture specific problem, I did not expect I can reproduce the problem easily, so I am a little bit surprised to see the problem on the device. There are two possible causes of the problem, 1. the image file corrupted, 2. the image is correct but corrupted during decode to bitmap object. After a little test, I can confirm that I am dealing with (2)… When debugging with logcat, the following logs appear everytime the problem occurs.

skia  D  JPEG content is corrupt, got a zero length row(272)
skia  D  JPEG content is corrupt, got a zero length row(273)
skia  D  JPEG content is corrupt, got a zero length row(274)
skia  D  JPEG content is corrupt, got a zero length row(275)
skia  D  JPEG content is corrupt, got a zero length row(276)
skia  D  JPEG content is corrupt, got a zero length row(277)

I thought once I have the error message, I am done, problem like this must be all over google and stackoverflow…

Nope, not this time.

There is not much I can do when there is only logs but no error message returned, I can’t even detect the problem and reload the images. So I approach to tackle the problem is to reduce the chance of happening instead of fixing it. One observation is that, even this is not a step of reproduce, it usually/always comes with a dalvikvm heap grow. Follow on this direction and tuned a bit memory performance, somehow like harder to hit the problem. (magic?)

This is for sure not a “fix”, and “looks harder to hit the problem” could actually be luck, but that’s all I can get in a few hour scheduled time.

Move Fast and Break Things

Who said that

Mark Zuckerberg did.

Moving fast enables us to build more things and learn faster. However, as most companies grow, they slow down too much because they’re more afraid of making mistakes than they are of losing opportunities by moving too slowly. We have a saying: “Move fast and break things.” The idea is that if you never break anything, you’re probably not moving fast enough.

I totally agree on the idea. However, like doing startups, the idea is important but what really matter is execution. How do you interpret “move fast and break things” affects the direction of the team. If you are in the wrong direction and move fast, there is no guarantee that you can go back to where you were even you “move fast” again.

Be able to move fast

Depends on the scale of your product, there should be different way to move fast. For new product or just a prototype, you should collect user feedbacks, move fast, break things, get on the right direction as soon as possible. That is the speed you needed to survive in the industry.

What’s next? You have some users, using your app everyday, but not yet the giant scale. To get more users, you need to keep moving and this is another type of moving fast. This time, you cannot just move fast and break things like the time when you start. From development point of view, as the code complexity increase, unless you have a good infrastructure, you will find that it is getting harder and harder to add features on top of it. When you add one feature, you may introduce two bugs, and slowed the app down at the same time. Beside that, there is a cost when you break things, maybe get some bad rating, maybe pissed off some users.

This does not mean you should not move fast, but you have to do it smart. You have to be clear on what you want to achieve from moving fast. If you want to try out new interface and get user feedback, it does not need to be 100% polished, but don’t rollout a 20% done ugly version, all you can get is bad rating instead of constructive feedback about the new features.

I agree on moving fast, but I also believe in “less is more” (slow is fast?). At the end of the day, it is all about what the users want, new features may boost your number a little bit, but sometimes quality is what makes the users come back and use your app and not switching to other competitors.

Instead of running on your foot, isn’t it better to get a bike or a car if you want to move fast?

When you break things

Please, fix it, before you break another thing.

Reference

Notes on Migrating Android Project From Ant to Gradle

Few months ago, I spent a little time to try migrating my Android project from to gradle, although it is announced in last Google IO (May 2013), and saw some big companies switched to it early, I considered that not ready that time and decided to wait for later version.

Projects structures

The project I am working on used some library projects like pull to refresh, facebook sdk, google play services, etc, due to the limitation of the old ant build system, you have to include the source and compile with your app. We also splitted some of our own components to separate library projects for reuseing in other projects. Currently my app is depending on 14 other library projects, and it takes about 3 minutes to have do a clean build.

We also use git submodules to include projects from other repositories. I am still not sure if this is the right way to manage projects especially when we keep modifying the libraries. It increases the complexity when we have multiple branches in development, and causes some pains when merging codes.

First migration attempt

I tried to migrate to gradle few months ago, when Android studio was in version 0.2 I think. One of the unknown part of the migration, it’s 0 or 100, no 50% migrated. Even you build every library successfully, it does not mean you are getting close to finish the migration. In my case, I first made a simple app to get familiar with the build system, then migrated my libraries one by one, but guess what I got when I tried to have a complete build? Out of memory… I googled a little bit and found a way to increase the memory limit but still got the same error, in both command line and Android studio.

I didn’t put more time on that since the ant scripts still work at that time and I got (many) other tasks pending.

Second attempt

I recently reopened the migration task, mainly for 3 reasons.

  1. Eclipse can’t handle the project anymore. When I tried to add some code in a core library project that is also used in 3 other library projects, eclipse just hangs there and I have to kill it myself.
  2. Need more tools for development. Actually this is one of the reason of my first attempt of migration, I had some (simple) scripts/code generators to help development, some are standalone but some are hooked into the build flow. It does not make sense to keep developing scripts based on ant if there is a migration coming, so I didn’t add any scripts in the last 6 months. In order to continue the development, the migration task now becomes a blocker.
  3. Team expand. We are expecting more man power on Android, the migration has to be done before they start.

Not like last time, this is no longer a “try out”, it has to be done, no matter how many effort required.

After reinstalling the Android studio and gradle, I still got the out of memory error during compile. At this point, even I can get through the compile task of each library, I may got other error when combining everything in the app project, so I have to do some experiments first. I compiled all library projects to aar and uploaded to local maven repositories, this also required me to modify the build.gradle of the app project to use aar instead of compile form source. With some luck, I can compile the app with those aar successfully.

Next step is to make it fits my development workflow. Some library projects need to compile from source and those relatively stable libraries can use aar. Fortunately it worked as expect and did not gave me out of memory error, and even better, it also worked on Android studio without any extra modification.

Migrating the basic workflow is just the beginning, there are still many things to test before using it to do release, like app signing, proguard, build with different package names, etc… But before those tasks, there is still one problem needed to work on. I am not sure it is just me, but the gradle configure time seems very long with multi projects setup, and it may not suppose to be that slow. I posted my question on Google plus and got some quick responses from Xavier Ducrohet. He said the configure time should be around 3s if run with daemon, but what I got is at least 10s for every one, even a simple “gradle projects” command call. I am not sure if this is the best I can get but it would not be a great development experience if every run need to wait for 10s and the actual compile is just 2s.

The Gatekeeper

Recently read some articles from Julie Zhuo’s, she is a Product design director in Facebook. Although her posts are not about engineering, I still feel connected with most of the topics. I wrote some of my thoughts originally, but I think just put the quotes here is enough.

“Don’t be a gatekeeper”

If you are somebody with an incredible amount of passion for high quality, you may be compelled to become a gatekeeper at some point in your life.

If you are a gatekeeper or find yourself thinking we need a gatekeeper, the thing that is broken or missing is trust. So instead of judging yes or no, good or bad, consider this instead: what could I do to make it so that I have more trust in the people around me?

“Why Designers Leave”

Every person who works in a creative field has an aspiration for her work, a yearning for that ideal plane which is the culmination of her taste.

When an environment fails, over and over and over again, to provide her with a means to follow her internal compass, then she will leave.

If you are in a position to influence that kind of environment, take heed. Lay the foundations for a space that nurtures, that yields the kind of work the best creative people can be proud of.

“Quality is not a tradeoff”

Quality is a bar, not a tradeoff.

It just doesn’t work like that.

Why? Because to create high-quality work, there has to be a minimum acceptable bar. And high-quality creators cannot trade off below that bar. They simply can’t.