RSSAmplifier

Blog

Ryan Harter

Recent content on Ryan Harter

ryanharter.comRSS feed ↗67 posts

Latest posts

A Great Gradle Module Structure

Flattening my Dependency Graph Jesse Wilson Jesse explores a Gradle module structure that he likes. Read now ➡ I liked this not-so-recent post from Jesse Wilson, which outlines a Gradle module convention that prioritizes clear public/private boundaries to support encapsulation and build speed. The approach, adapted from one presented by Ralf Wondratschek , also happens to closely resemble one that…

Graceful Exit

Public Mirror Mark (from unsigned.io ) Mark explains why he is stepping back from public-facing interaction with his Reticulum projects, and invites anyone who wants to use or continue the project. Read now ➡ It’s always sad, but not uncommon, to see some open source maintainer burn out. We build these projects for any number of personal reasons, we share them with the world. If we’re…

Incremental Maintenance

I recently reviewed some code at work that made me pause. The change affected a part of the codebase that we affectionately call “The Monolith”, which is some of the oldest code in our 16 year old app. While there are reasonable arguments that it’s hard to tease apart this older hairball of code, there are often small choices that can either move you closer to the decoupled…

Values

I was recently pruning and organizing my RSS subscriptions and indirectly came across Jake Wharton’s hiring page . I knew he was on the job market, but I love the way he approaches this resume, by listing some of his values, clearly communicating what’s important to him and how he likes to work. This kind of straight-forward honesty goes a long way.

Celebrate the code you didn't write

Over the past few years I’ve been driving an architecture and tech spec review process at work. This has been helpful in breaking down certain silos, distributing knowledge across the organization, and building skills and experience in more junior engineers. A recent tech spec caught my eye, and resulted in a really valuable learning opportunity. The specifics of the spec aren’t…

Start More Projects

A couple of months ago I was pair programming with a colleague, sharing my screen, and he was amazed to see the number of branches I had in my git repo. This wasn’t simply a case of poor git hygene, these were branches that I had started but never pushed, branches that were never merged. As I explained this I realized that my attitude towards starting and finishing projects has changed…

Make Things Easy

I’ve been using feature gates for a long time. Having the ability to conditionally alter the behavior of an app unlocks so many benefits that I wouldn’t go back. I love being able to have a consistent release train by keeping in-progress features locked behind a gate, being able to validate the utility and impact of the features I work on using A/B testing, and being able to mitigate…

Extending Coil

I was recently working on showing thumbnails for files, and found that the image loading code was surprisingly complex. I load thumbnails from my backend service via an SDK, which means I don’t have a simple URI that I can provide to an image loading library to load images. Added to that is the fact that I usually pass around a lightweight file id to represent files within my app, but my…

Screenshot Tests Are Manual Tests

When I joined Dropbox almost 2 years ago, I was asked to help improve the screenshot testing experience, resulting in Dropshots . While I’d played around with early versions of Paparazzi by that point, many of our tests were too heavily reliant on full Activities and Fragments to make use of host side JUnit tests. The more I’ve worked with screenshot tests, the more I’ve come to…

Simple APIs are elegant APIs

I recently gave a presentation about how Dagger works under the hood, and I was once again struck by the elegance of the javax.inject.Provider interface. The interface is so simple it almost seems useless, but it’s also incredibly flexible, and forms the basis of much of the code generated by Dagger. Like many dependency injection frameworks for JVM languages, Dagger uses and builds on the…

Rounded Corners

The other day I happened to notice an interesting question that Michał Zieliński shared in an Android Graphics channel that I frequent. He had observed that if he has a 40dp square and sets a 30dp corner radius, on Android the resulting shape looks the same as a 20dp corner radius. He then concluded that, unlike iOS, Android appears to clamp the corner radii of a rectangle to half of the shortest…

Building Plugable Features on Android

As Gradle projects and their teams grow, modularization becomes an important tool to help ensure developers can continue to be productive without stepping on each other’s toes. This can lead to some interesting architectural challenges, however, when creating features that require aggregating dependencies. One example of a feature like this could be a developer settings screen, which allows…

Make a Prototype

When coming up with ideas for new ways to solve problems in my code, there are usually a number of unknowns. As I brainstorm solutions, I don’t mind a bit of hand-wavy magic over certain portions of the solution, but I find it valuable to be honest about which parts I’m sure of, and which parts will need some more investigation. I was recently thinking about an experimental brushing…

Handling Dates & Times in SQLite

As I’ve been refactoring a fairly large section of Pigment , my coloring book app for adults, I came across some SQL code which I haven’t touched in a very long time and didn’t seem quite right. Part of Pigment’s large library of coloring books and pages are the Daily books, which are a different book each month in which a new page is released each day. The day’s page…

SQLDelight on the Server

I’ve used Cashapp’s SQLDelight for years in my Android apps. Unlike other ORM libraries, which create an abstraction that allows you to access databases in native code and generates the SQL to access the data for you, SQLDelight embraces SQL as a first class language, recognizing it’s optimizations for defining and querying data, and allows you to write queries and data…

Server Side Analytics with GoAccess

When I updated my blog about a month ago, my primary goals were to simplify and modernize things. I updated to the latest version of Hugo , which powers by blog, added automatic deployment of new posts using GitHub Actions, and moving away from my previous hosting provider, Firebase, which was far more than was needed to host my simple, static site. One of those simplifications was removing Google…

Replacing Mocks

Sam Edwards recently posted his strategy for wrapping mock objects to avoid using verbose syntax and facilitate reuse. After reading the post, my first thought was that this example comes really close to showing my strategy for removing mock objects from tests. Why Remove the Mocks There has been endless discussion about the benefits and drawbacks of Mock objects in testing. As I’ve become…

Your Labor is a Product

Before joining Pixite I spent several years as a freelance Android developer. Being 100% remote for all of those years, I learned many things about the process of hiring and employment. The biggest eye-opener for me was the realization that when you apply and interview for a job, you are selling a product. Though the language is often about employers providing perks to “sell you” on…

Easy Android Scopes

A common challenge when writing Android apps is properly scoping objects: if they outlive the lifecycle in which they’re needed then we are wasting memory and they can be leaked, but if we recreate objects too soon then we could be duplicating work when we don’t need to. The most common place that this manifests in is Activities and Fragments, since they’re destroyed and replaced…

Handling Transient Events

LiveData has become an important part of many Android apps. With it’s elegant handling of the complex lifecycle inherent in many Android components, its understandable that we would try to use them everywhere we can. LiveData, however, was designed with a very specific use case in mind. Its intended to hold data for use by views in an application, and make that data available in a…

Encapsulating View State

The AndroidX ViewModel has become a central component in many modern Android apps. They offer a relatively simple abstraction to encapsulate business logic and decision making code which separates it from the platform frameworks, which are often difficult to test. Since ViewModels are easier to test than Framework classes like Activity and Fragment due to their simple lifecycles and lack of…

Cloud Build Recipes - Saving the Build Cache

When building development projects on your local workstation speed is important. A quick feedback cycle can mean the difference between a productive day of test driven development and a day filled with distraction. Your continuous integration environment is different. Since CI is responsible for preventing bad code from being merged and creating production releases, most people value precision…

Cloud Build Recipes - Incrementing Build Numbers

Many CI services use an incrementing build number to identify builds. GCB, however, uses a randomly assigned unique identifier, as is common in large scale systems. While this is common and helps make GCB infinitely scalable, it makes it difficult to reason about the relationship between builds. Since I like to use the CI build number in my Android app versioning, I decided to reimplement this…

Google Cloud Build for Android

As I’ve written before , I’m always on the lookout for a great continuous integration and delivery system. For a long time I used CircleCI, but in the last month or so I’ve started hitting some limitations that I needed to work around. My requirements are pretty standard, I need something that works well with Android, requires minimal maintenance, and can handle somewhat larger…

Android Development on a Pixelbook

A couple of weeks ago I bought a Google Pixelbook. I’ve been doing a bit of Android Development on it, mostly to optimize Pigment for Chromebooks. It’s taken some experimentation and discovery to find out how to get things set up, largely because the Android documentation is slightly out of date, so I thought I would share my experience, hopefully saving others time. This post serves…

Introducing Billingx

A few months ago I was tasked with rewriting the subscription code for Pigment , the coloring book app I work on at Pixite. Our users were suffering from a bug causing paying users to sometimes lose access to premium content, and the original implementation was somewhat hastily written, so I decided it made sense to invest the time to rewrite the billing code from scratch. Play Billing Library…

Continuous Delivery for Android

For a long time I’ve been in search of a good continuous integration server for Android. I’ve even written about one that I used years ago, which is no longer suited to Android development, in my opinion. As the Android community has grown, so has the wealth of tools available. In that time I’ve also moved from simply wanting continuous integration, to wanting continuous…

AutoValue Extensions

This is the third article in a series on AutoValue. The first article introduced AutoValue, the code generating annotation processor for value types. The second took a more in depth look at the code generated by AutoValue, and the benefits of compile time code generation. In a previous article introducing AutoValue, I briefly mentioned AutoValue Extensions. Now it’s time to go a bit more in…

A Deeper Look at AutoValue

In my last article , I gave a basic introduction to AutoValue , the code generating annotation processor that makes immutable value types in Java easy. Now I’d like to take a bit of a deeper look at AutoValue and how it works. Compile Time Annotation Processing First things first, AutoValue is a compile time annotation processor. This means that it only runs when you compile your code, as…

An Introduction to AutoValue

Value types in Java are hard. Well, not hard, but tedious. Google’s AutoValue library makes them much easier and has just received the long awaited update that adds the flexibility of extensions. Value Types in Java Before we can talk about how great AutoValue is, let’s look at the problem it solves: value types. A value type is simply an immutable objects whose equality is based on…

Dealing with AsyncTask in Unit Tests

There may be a shortage of love on the internet for AsyncTasks , but that doesn’t mean they don’t have their uses. I’ve found myself using them a fair bit in the latest project that I’m working on. All in all, they make offloading tasks from the main thread quite simple, but can pose some challenges, particularly in tested environments. The biggest challenge with using…

Should this be a library?

I come from the consulting world, where it’s common to try to make everything a library. This makes perfect sense, boost profit margins by writing something once and selling it to everyone. But often times this doesn’t work out as expected for several reasons, the first of which is failing to ask the question “Should this be a library?” Here are a few tips to help you…

Wrapping Existing Libraries with RxJava

RxJava is all the rage in the Android world lately, and with good reason. While Functional Reactive Programming has a bit of a steep learning curve, the benefits are enormous. One issue I’ve run accross is the fact that I need to use libraries that don’t support RxJava, but use the Listener pattern instead, and therefore miss out on many of the composability benefits of Rx. I ran into…

Using All the App Stores

Shortly after our initial release of the Pack Store in Fragment earlier this year, other companies started contacting us wanting Fragment on their App stores, as well. With the addition of the Pack Store, and in app purchases, this made things challenging. When I first implemented the Pack Store, I used Sergey Solovyev ’s excellent Android Checkout library to implement the In App Billing…

Hosting a Private Maven Repo on Amazon S3

Remember the olden days of Android development? There were times when including a library in a project meant relative links to source , or using Maven. Fortunately for us, those days are long gone now with the introduction of Gradle. Gradle has made developing and consuming libraries for Android amazingly simple, and has spurred a new boom in library development for Android. We’ve always had…

Custom Drawables

We’ve all seen posts about why you should use custom views when applicable and how it can help you properly encapsulate your application code. What we don’t see quite as much is how this type of thinking can be translated to other, non-View related, portions of our apps. In my app, Fragment , there are a few places where I make use of custom Drawables to encapsulate my logic just like…

The Architecture effect of Test Driven Development

I’ve finally done it. In the latest client project I’m working on I’ve decided to take a test first approach. I’ve been wanting to experience Test Driven Development on Android for years, but have never felt comfortable enough to really commit. After reading through Kent Beck’s book and checking out Corey Latislaw’s latest book , I decided I was ready to make…

Styling Chromecast Icons

One of my favorite new devices from Google is the Chromecast. I have 3 throughout my house, and one for travel. It’s great to have a cheap device that anyone can stream to. I’ve also had the pleasure of integrating Google Cast support on several apps in my freelancing business . These are usually pretty cut and dry, but I recently had a client who needed a custom Google Cast action…

What's Your Intent?

One of the most powerful, yet sometimes overlooked, features of Android is the Intent system. Android’s Intents allow apps to interact with each other, without intimate knowledge of each other. Intents are one of the differentiating factors that allows Android apps to interact and send data beyond their walls, while still keeping the system relatively safe. Anatomy of an Intent I like to…

Using Gestures

Modern Android apps often make use of gesture interaction to provide fluid, natural interaction with the app. There are a few ways to handle these interactions, and in this post I’m going to cover some of the basics for easily adding gesture support to your app. The code for this sample app can be found at Github . The basic building blocks of this simple gesture handling code is the…

Kindly Asking for Ratings and Reviews

One of the most important factors in determining whether or not people will buy your app is the rating. Especially if your app isn’t free, people will generally check the ratings and reviews before downloading your app. And if your app is a paid app, ratings and reviews can mean success or failure for your app. When launching Fragment for Android, our first though was making a kick ass app,…

Building Dynamic Custom Views

Last week I released Fragment for Android. Fragment is made up of all sorts of custom Views, which I think sets it apart from many apps in the Play Store. Some of these views have a similar pattern to views I’ve had to create for other apps, in which a scroll view has padding such that every item within it can be scrolled to the center of the view. On it’s surface this doesn’t…

Bringing Fragment to Android

In November 2013, Ben Guerrette from Pixite reached out to me after reading my post about my experience being featured on the Google Play . He was interested in bringing one of their iOS photo apps to Android. At this point I wasn’t familiar with Pixite, so I promptly fired up the Google to do my research. I was quite impressed with what I found. The guys at Pixite had created some really…

A Modern CI Server for Android

As a freelance Android developer, I’ve gotten the opportunity to work with many different client environments when it comes to building and releasing Android (and other) apps. One of the things that I’ve learned over the years is the importance of a good build server. Why CI? Continuous Integration servers, or CI servers, are designed to checkout your code after each push and build…

Using Custom Compound Views in Android

On a recent client app, I ran into a situation where I needed an arbitrary number of EditText fields based on a selected value, where the user could enter people’s information. My initial thought was to put this logic in my Fragment, just adding EditTexts to a LinearLayout container as the selected value changes, but that bloated my Fragment, and didn’t allow for much reuse. This was a…

Customizing the ListView

In the last post we created a basic Android project using Android Studio templates. While it’s great that we have a fully functioning master/detail style app, it does look a bit bare. In this post, we’ll change this by styling our list view, incorporating (sort of) real data to feed our list. We’ll make a custom adapter to drive our list with custom layouts, and introduce testing…

Two Months With the Moto X

Two months ago, after an unfortunate incident with my Nexus 5 and tile floor, I decided to hop off the Nexus train and get a Moto X. After years of using nothing but Nexus devices (starting with the Nexus S) this was a big switch that made me a little nervous. {% img /images/posts/moto-x-review/front-right-on.jpg “Moto X” %} Since I buy all of my phones off contract, it wasn’t…

Creating an Android Project

This is the third post in my Start to Finish series. Last time I talked about source control with Git . We’ve talked about basic tools , and about source control , so now we’re ready to get into actually creating an Android app. In this part of the series, we’re going to create a new project using Android Studio . Android Studio is Google’s Integrated Development…

Getting Started with Git

This is the second post in my Start to Finish series. You can check out my first post introducing the series and my tools here . What is SCM? SCM, or source code management, is a system that helps developers manage the source code for their projects. They have been around forever, things like CVS, Subversion (SVN) and now Git are the popular ones. SCMs allow you to version your source code, which…

Developing an Android App - Start to Finish

If you checkout the Android Development community on Google+, you’ll find a lot of people asking how to get started building an app for Android. Though quite a general question that can’t really be answered in a social post, I understand how frustrating it can be to figure out where to get started. There are plenty of tutorials on the web about how to accomplish specific tasks, but…