Android Studio tips – Mouseless development

I heard somebody making the comment that you can tell an expert by the mastery of their tools. Since I’m a developer (and a pretty good one), I figured it’s time to put in some more effort to master my tools (IDE, VCS, etc).

To this end, I’ve been stalking Hadi Hariri (http://hadihariri.com/) for the last few weeks and a couple of things he published has really resonated with me.

My Android Studio setupThe first was an article called No tabs in IntelliJ IDEA, which covers what you would expect – How to use IntelliJ IDEA without tabs. I wrote about my setup based on this here: My Android Studio setup.

This set me on a quest to use my mouse less, which eventually led me to Hadi’s Mouseless Driven Development talk, which is beyond awesome.

These 2 pieces of content has made me both more productive and happier (With my RSI, using a mouse is literally painful).

If you want to be a better developer, ditch the mouse.

My Android studio setup

I figured I’d start documenting some of my setup so that I can keep track of it. Most of this works for IntelliJ as well.

I like dark themes, so I use a modified version of the Darcula theme.

Turn off everything possible

One of the most surprising deviations seems to be the fact that I turn off tabs. They take up screen real-estate and make you either use a mouse or scroll through multiple tabs using keyboard shortcuts to find the one you are interested in.

There’s a great article about it here: No Tabs in IntelliJ IDEA

Editor -> General -> Editor Tabs

Placement: None

I also hide ‘Tool Buttons’ and the ‘Navigation Bar’ in the ‘View’ menu. UPDATE: I now turn off the “Toolbar” as well. I was only using the run button and I can use a keyboard shortcut for that 🙂

This is what you end up with:

 

The great thing with this set up is that it forces you to use keyboard shortcuts. You can easily get away with CTRL+B to select recent files, CTRL+SHIFT+B for recently edited files and double tapping SHIFT to search for anything.

It sounds counter-intuitive, but this is much faster than trying to find the correct tab in the open ones.

I also hide the Project view (and in fact all tool windows) when I’m not using it (ALT + 1 to turn it on or off quickly) and I’ve set it up to Autoscroll to/from Source so that when I open it the file I was in is selected and if I select a new file, it displays in the editor window:

Android Studio Project View

Change fonts and colors

I find this makes the code more readable.

Editor -> Colors & Fonts -> Font

Primary font: Consolas
Size: 14
Line spacing: 1.1

Font settings

Editor -> Colors & Fonts -> Android Logcat:

  • Assert: #9876AA
  • Debug: #6897BB
  • Error: #FF6B68
  • Info: #6A8759
  • Verbose: #BBBBBB
  • Warning: #BBB529

Android Logcat colors

Set up code styles

I’ve saved a version of my code styles in a github repo with an install script: https://github.com/riaancornelius/android-style-guide

Creating high quality Android code – Getting started

My previous post highlighted some of the problems working with a legacy codebase (I agree with Michael Feathers that any code that doesn’t have tests is legacy code).

So how do we start refactoring in a situation like this?

Simply put, it is all about managing risk. You want to find the highest impact, smallest risk incremental improvements that you can make without too much effort.

Since we know that we read more code than we write, anything that makes code more readable is probably worthwhile and will make the code more maintainable.

Getting started

So, how do you make code more readable? The first step for me was to get everybody on the same page by creating a style guide for Java and for Android.

Fixing your code style doesn’t necessarily make the code any better, but it does make it more readable.

The next step for us was to start creating a best practice guide for Android. There are a lot of things to keep in mind for performance and stability which can ultimately make or break the user experience. By documenting these, we give new developers a place to start and everybody a place to reference these points.

Refactoring

We also follow the idea of the boy scout rule, which can be summed up as “Leave any code you touch in a better state than you found it”.

This is of course a bit of a slippery slope. Some reviewers argue that it makes code reviews more difficult because it’s hard to see what changes was due to refactoring, and what was specifically related to your task. Personally I think having to work a bit harder in the peer review to make the code more maintainable is a perfectly fair trade-off. One way to make it even easier is to make sure that you separate refactoring changes into their own commits.

Of course, if you don’t have test coverage you have to be very careful with the type of refactoring you do and focus on low risk items.

Peer review

Now that we have style guides, best practices and a plan to start refactoring, we need tho start enforcing it. The simplest way to do this is by starting to do peer reviews. Ideally, for styling, naming, etc, you should also get a CI server set up and running static analysis.

I tend to see a lot of pushback against peer reviews, but as long as you can create an environment where peer reviews can be constructive and can give feedback on the code without having people feel that they are being judged, there are no better way to drastically improve your code quality over time.

In summary

So, in summary, the low hanging fruit which you can start picking off without too much risk or effort:
  1. Create a style guide
  2. Create a best practice guide
  3. Do opportunistic refactoring. Refactor low risk items like styling, naming and big methods while you are working on the code.
  4. Start peer reviewing ALL code to make sure people adhere to style and best practice guides and that they are leaving the code in a better state than they found it in.

Creating high quality Android code – History

I recently started working on a legacy Android code base. This is a massive project with slightly more than 250 000 lines of code, zero tests, lots of code duplication and in general, massive issues.

There’s no consistent formatting, naming or even package structure. I’ve seen classes and activities with 8500 lines of code.

The code is peppered with things like:

The app often crashes with OutOfMemoryError’s, which has led the developers to just catch those as well.

This raises a few issues.

How do you get an objective measure of how bad the code quality is?

This is necessary for a couple of reasons, but the most important in my opinion is to start getting an indication of whether the code is getting better or worse over time.

The simplest solution here is probably tools like static analysis which can give you a standardised metric and maybe test coverage.

All of these numbers are at least somewhat useless, ambiguous and possibly misleading, but tracking them over time in some kind of sensible manner can at least give you an indication of whether your code is improving.

How do you explain to an inexperienced developer why these practices are wrong?

In a recent code review, I called a developer out on catching a NullPointerException. His argument was that he would need to do 3 null checks, so why can’t he rather just catch it once?

My first thought was: “Because it’s wrong”. Everybody knows you never catch unchecked exceptions. My second though was that catching an NPE gives me an instant indication that you don’t know better, so I can’t trust your code and need to be much more careful with anything else you do.

But why? What reasons do I give this developer? Saying “Because it’s wrong” doesn’t help anybody.

How do you start fixing this project?

There are lots of big problems:

  • We are still developing new features. We can’t stop dev to refactor.
  • Which parts of the codebase would most benefit from improvement? This is not necessarily purely a matter of quality. If I have a really bad module, but nobody has touched it for two years, it might not need to be improved.
  • There are less experienced developers on the project. How do you stop them (or the more experienced devs for that matter) from adding more bad code.
  • The lack of tests means that we have to be very careful about how we refactor.
  • The code is not testable at the moment:
    • There is no inversion of control, so most things cannot be mocked out.
    • The app relies on heaps of global state which makes testing harder (It also leads to the aforementioned OutOfMemoryError’s).
  • Where do you start? There are so many major problems, which do you tackle first?

Where to go from here?

I’ll tackle these in upcoming blog posts. I expect this will turn into a fairly big series of posts… I’ll add links to the relevant posts here as I create them.

While I’m specifically referring to Android development, most of what I discuss will make perfect sense to Java developers and I suspect the practices will apply to any development.

This is what I think is necessary at the moment. This list may change as I work on these:

  1. Starting to fix legacy code
  2. Style guides
  3. Identifying problem areas
  4. Best practices
  5. Sensible refactoring
  6. Starting testing?