Dex Ed
I presented this at ‘Enabling Android Teams’ on November 10, 2015. Available as video, slides, YouTube, & Speaker Deck.…
I presented this at ‘Enabling Android Teams’ on November 10, 2015. Available as video, slides, YouTube, & Speaker Deck.…
Lots of great Android developers have been promoting FlatBuffers. Miroslaw Stanek recently posted benchmarks comparing JSON, FlatBuffers, and a hybrid that uses both. He mentioned that decoding JSON to FlatBuffers is about 30-40% faster than decoding JSON to Java models with Gson. Colt McAnlis has been referring Android developers to…
OkHttp’s HTTP/2 doesn’t interop with NGINX 1.9.5. HTTP requests made from OkHttp to impacted NGINX servers will fail like this: java.io.IOException: stream was reset: PROTOCOL_ERROR at com.squareup.okhttp.internal.spdy.SpdyStream.getResponseHeaders(SpdyStream.java:145) at com.squareup.okhttp.internal.http.…
Colt McAnlis has been arguing that Android developers avoid enums because they have a non-negligible runtime cost compared to int constants. In his talk he measures it, and suggests that pervasive use of enums can harm your Android app. “And the worst part is that you don't really know that…
ProtoParser is a simple Java project that parses .proto files. It’s a dumb parser: whenever you reference a type, it lacks any mechanism to resolve that reference. Wire is a much more sophisticated Java project that builds upon ProtoParser. It performs that essential linking to make ProtoParser’s output…
Today I’m playing with JMH, the Java benchmarking harness written by Oracle. I’m hoping to try out some optimizations for Moshi. Some History After years of struggling with one-off benchmarking harnesses, Kevin B and I started Caliper in 2009. It started out as a project for benchmarking Android…
In announcing OkHttp's new URL class, I wrote about how parsing returns null instead of throwing exceptions: Instead, parse() just returns null when it doesn’t understand what you passed it. Several developers thought this was a lousy API. Derek Morr tweeted: "parse() just returns null" so, not…
Neither of Java’s built-in APIs make it easy to get at a URL’s query parameters. Instead, you end up having to muck around with string concatenation, string splitting, UrlEncoder, UnsupportedEncodingException, and MalformedURLException. HttpUrl is a new class that makes URLs easy: HttpUrl url = new HttpUrl.Builder() .scheme("…
We’re in the age of Emoji. We fought in the charset wars, obsoleted old bad encodings like ISO-8859-1, and emerged victorious. Being able to sprinkle our writing with sprinked donut emoji is the English speaker’s upside to ubiquitous UTF-8. Unfortunately, java.io.Reader is stuck in the UTF-16…
Java has checked exceptions and unchecked exceptions. Checked exceptions are for expected problems that you should deal with and recover from at runtime. Flaky network? Catch the IOException and deal with it. Unchecked exceptions are for unexpected problems that should trigger a crash. Is the byte count negative? Got a…
I presented this with Jake Wharton at Droidcon Montreal on April 11, 2015. Available as video, slides, YouTube, & Speaker Deck. A successful app takes a lot of code. The best developers don’t write all of that code themselves; instead they rely on open source to solve all of…
Suppose you’ve requested a webpage with a Last-Modified date and no other caching headers: HTTP/1.1 200 OK Last-Modified: Tue, 16 Dec 2014 06:00:00 GMT ... The HTTP client will happily store this response in the cache indefinitely. But it won't serve it from the cache unless…
Anton Rieder just contributed an OkHttp code sample that monitors a download’s progress using an interceptor. With it, you get a callback as bytes arrive: interface ProgressListener { void update(long bytesRead, long contentLength, boolean done); } I like this example because it’s all layered decorators: The Interceptor puts code…
Lately I've been building HTTP APIs for Square Cash, to be used by our website and partners like Snapcash. It turns out this is a particularly difficult task because I need to balance two competing concerns: Keep separate things separate. If the app wants to look up payments 123, 246…
Okio’s buffer reads like an InputStream: when you read 50 bytes from the buffer, you implicitly remove those bytes from the buffer. This is a handy optimization and it means we can move data rather than copying it by default. But sometimes you need non-destructive reads. So in Okio…
Java’s crypto APIs are flexible and powerful. But just awful to use. There are too many contexts, managers, factories, and providers. Want a certificate? Take your pick! java.security.Certificate java.security.cert.Certificate java.security.cert.X509Certificate javax.security.cert.Certificate javax.security.cert.X509Certificate Gross. Suppose you…
On Cash we communicate with the web and mobile apps via both protocol buffers and JSON. For both data formats, we use proto2 as a schema language. It defines what our message types are, what their fields are, and gives us a language-neutral place to document all the things. This…
I'm proud to share the keynote stage with Jake at Droidcon Montréal this April. We're planning to talk about open source. That’s a broad topic, and one I’ve presented on previously. But it isn’t just about bug reports and pull requests. I’m thinking a lot about…
Exceptions are powerful control flow: mainline code handles the mainline cases, and exception cases can be handled elsewhere. But sometimes you want to observe whether an exception occurred, without necessarily handling that exception. For example, suppose we're writing a service that sends webhooks to a far-away webserver. Webhooks are naturally…
I was running a jstack dump on my project's app server this afternoon & I saw Okio Watchdog among the threads: "Okio Watchdog" #1972 daemon prio=5 os_prio=0 tid=0x00007f4a8c01e800 nid=0x362 in Object.wait() [0x00007f48f2351000] java.lang.Thread.State: WAITING (on object monitor) at java.…
GitHub's wiki permits embedded images, but offers no UI to upload your own images. Here's how to do it from the command line. Clone the Wiki's Git Repo GitHub's wiki is itself a git repository. Clone it to your desktop using an SSH URL to make git push just work…
When Josh Bloch measures an API, he evaluates its power to weight ratio: great APIs let you accomplish a lot (high power) without much mechanism (lightweight). Interceptors are a new feature of OkHttp 2.2. There isn't much mechanism: two interfaces and four methods: public interface Interceptor { Response intercept(Chain…
Étienne Vallette d'Osia tweeted about a surprising behavior lurking in SimpleDateFormat: If you use SimpleDateFormat and “YYYY” for years (not “yyyy”), your code currently returns 2015 instead of 2014. Enjoy! (no pb w/ jodatime) He's right. SimpleDateFormat format = new SimpleDateFormat("dd-MMM-YYYY"); Calendar day1 = new GregorianCalendar(2014, Calendar.DECEMBER,…
Tonight I was looking around the web for examples of Content-MD5 in an HTTP response. I was thinking it'd make for another example of OkHttp's powerful new Interceptor API. I haven't found such an example yet. But I did stumble upon some curious headers on Apple's CDN: ~ curl -v http:…
Public APIs I work on lots of public APIs. For those, it's nice to have nicely-formatted Javadoc, following the Guava guidelines. This means lots of <p> tags, {@code} blocks! Here's an example from Okio: /** * Wait at most {@code timeout} time before aborting * an operation. Using a per-operation timeout…
Much of the Dagger vs. Guice comparison is about code generation vs. reflection. But they're also different in how they ask you to structure your application... Guice Guice apps are built with these fundamental abstractions: Multiple injection points: dependencies, being injected. Multiple bindings: dependencies, being provided. Multiple modules: a collection…
OkHttp 2.1 is out. The release candidate announcement explains that 2.1 is focused on caching & crypto. The release has new APIs to customize TLS, giving you control of certificate pinning, cipher suites, and TLS versions. For example, now you can restrict an OkHttpClient to cipher suites that…
We've just cut the first release candidate of OkHttp 2.1. This release is focused on caching & crypto. Caching We've improved cache APIs and also fixed some long-lived cache bugs. If you're using OkHttp with Picasso, it may fix some unexpected cache misses. The cache is now private which…
My hobby app Rounds was 99¢ for its first 2 years. In September, I made a bunch of changes. I made the app free and instead offered a 99¢ in-app purchase to unlock a full palette of colors. ■ Blue is sales. ■ Red is current installs. Note that current installs were…
Pierre-Yves Ricau: “The backstack isn't an activity specific notion; you can implement a backstack within an activity.” Great advice. Fragments are too complicated to be worthwhile for simple apps. But they're also too complicated to be productive in sophisticated apps. You don't need 'em.…
Nolan Lawson: “If you design your UIs for people who are disconnected or only infrequently connected, you create better interfaces for everyone, including those who are online with fast connections.” Brilliant post.…
Dagger has always been a collaboration between Google and Square. Both companies are heavily invested in Guice (and Bob!), and eager to see our code become faster & easier to use. Dagger 1.0 was born in Square Register for Android. We’d been using a lot of Guice, and…
KitKat + dalvikvm: java.lang.NullPointerException at com.roundsapp.HomeActivity.onCreate(HomeActivity.java:61) at android.app.Activity.performCreate(Activity.java:5312) Android L + ART: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference at com.roundsapp.HomeActivity.…
When Gson binding fails, it gives you a crappy exception that tells you where in the document things went sideways: com.google.gson.JsonSyntaxException: Expected a boolean but was NUMBER at line 1 column 4728 at com.google.gson.stream.JsonReader.nextBoolean() at com.google.gson.TypeAdapters$3.read() at…
Brent Simmons: Here’s my secret, or maybe my superpower, or maybe just me being lucky — I’ve never had a bug related to using a string literal when I should have used a constant. But I have had bugs when I used the wrong string constant. I'm the same.…
Holo's color palette is opinionated, but limited. Five hues each in a primary and darker shade for a total of ten colors. (There's swatches for lighter tints, but these are rarely used.) Material Design's color palette is the opposite: 19 hues, 16 of which have accent variants. With all tints…
Ned Batchelder: Paying more attention to the comments will help you write better code. I can't tell you how many times I've written what I thought was a perfecty good function or line of code, then gone to write the comment or docstring, and realized a better way to do…
Today Google released a revised Roboto. Their design site says, It is slightly wider and rounder, giving it greater clarity and making it more optimistic. In Blue, Roboto from Android 4.4 (download .zip) In Red, Roboto from “The L Release” (download .zip) To my eyes they're quite a bit…
On the Android Developers blog, Wouter van Oortmerssen writes: Game developers, we've just released FlatBuffers, a C++ serialization library that allows you to read data without unpacking or allocating additional memory, as an open source project. [...] Use this library to store game data with less overhead than alternative solutions (e.…
Last year, during Square's 7 days of open source, we announced Mime Craft, which makes it easy to build browser-style HTTP request bodies. With this week's OkHttp 2 release candidate, we've promoted that MimeCraft code into OkHttp itself. You can encode a form request: RequestBody formBody = new FormEncodingBuilder() .add("…
I was planning two TLS code samples for OkHttp's recipes page. One to make development easier by disabling certificate checks and another to make deployment more secure by pinning TLS certificates. Disabling Certificate Checks It's a hassle to get TLS going on a local development server. Disabling certificate checking is…
OkHttp has a bunch of docs: Marketing Site: what it is, basic examples, and download links. Design Overviews: high-level explanation on how things fit together. Recipes: executable sample code. Javadoc: reference docs. The recipes are new. The contrast between recipes and Javadocs is interesting: Javadocs show you how to call…
Adrian, Jake and I have been working on OkHttp 2.0 quite actively for nearly a year, and we're finally ready to share its new API with the world: OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://square.com/") .build(); Response response = client.newCall(request)…
Claiming “We’re the fastest!” is a great way to grow a project’s popularity, particularly for mechanical tasks like JSON parsing. This month there's been plenty of comparison between Jackson and Boon. Boon author Rick Hightower: “Boon JSON parser and the new Groovy 2.3 JSON parser are faster…
Flaky tests are the worst. They break the continuous build, the presubmit checks and confidence in the test suite. Fixing flaky tests is unpleasant because you need a way to reliably reproduce something unreliable. And a way to confirm that you've fixed it. I prefer brute force: @Test public void…
Maggie will give me five stars if I give her app five stars. No. Though I do feel somewhat tempted to rate their app based on its merits. Previously.…
Peter Nixey in How to be a great software developer: I believe that your seniority and value as a programmer is measured not in what you know, it’s measured in what you put out. Peter's advice is accurate and comprehensive. I wish I would have read this a decade…
Here's some code that uses Okio to serialize an object to a base64-encoded string: String toBase64(Object object) throws Exception { Buffer buffer = new Buffer(); ObjectOutputStream out = new ObjectOutputStream(buffer.outputStream()); out.writeObject(object); out.close(); return buffer.readByteString().base64(); } And this code will deserialize that string back into an object:…
I've been on stock Android since before the T-Mobile G1 was released. The new HTC One (M8) is the first time I've experienced the joys/horrors of a third-party skin in my day-to-day phone. I was anxious, especially after seeing Touchwiz on my wife's Note 3. Sense 6's built-in apps…
It was six weeks from when I teased an Okio code sample, to releasing the project publicly. In that time I went back and forth over and over on how to do timeouts. The lightbulb came when I discovered that we were addressing two different problems: Detecting network partitions. That…