waffle

Waffle was a weblog that ran for nine years and five days from 2003 to 2012.
The last post has been written and comments will be closed by the end of March 2012.
The author of Waffle, some guy in Sweden, also occasionally writes stmts.net.

(If anything will ever succeed or revive Waffle, it will be announced in this location, and in the feeds.)

Once Again, With Feeling

Android developer advice:

The network is especially slow and inconsistent, so you should never do network requests on your main thread. In fact, in the upcoming Honeycomb release we’ve made network requests on the main thread a fatal error, unless your app is targeting an API version before Honeycomb. So if you want to get ready for the Honeycomb SDK, make sure you’re never doing network requests on your UI thread.

Network requests can (should!) be handled with asynchrony, and asynchrony can (should?) be handled without introducing threads (event/message loops). What they’re saying is that it’s not just okay to sit around spinning for network, you actually have to involve a new thread, on a device with scarce resources, just to do that, even if you’re just doing it asynchronously. That’s conceptual and actual overhead.

As long as you start the request asynchronously, it doesn’t really matter what happens. Even if network requests did involve the CPU sitting around spinning, the system should be able to do that in a special thread for you. With the way it actually works, the CPU sets off the request and the networking interface and the network does most of the busywork until you start to get stuff back and the buffers fill. You yield immediately for other stuff, and the asynchronous operation picks up when it’s done.

I’d like to hear from any Android developers whether there’s any architectural reason to actually do a new thread. Conventional wisdom and past experience, including several operating systems with millions of users, says you don’t have to do it. Are there any constraints I’m missing, or is it that the APIs (or Java itself) are so inept that most people can’t bother getting asynchrony right anyway?

Comments

  1. Theories off the top of my head, having never seriously developed for Android:

    1. There are a large number of developers who don’t know how to write asynchronous code, block the main thread constantly, and won’t change their behavior unless they’re forced to. It’s easier to mandate a library be used from a background thread than that it’s used asynchronously from the main thread.

    2. Android/Dalvik threads may be unusually lightweight, or in some other way tuned for this sort of use. I really have no idea.

    3. After an application receives data, it almost always stores or processes it in some way, and this is a legitimate use of a background thread.

    By Joel Bernstein · 2010.12.14 09:40

  2. HttpComponents 4, which is what Android encourages you to use, blocks the current thread for a request. Outside of Android you might use an Executor [1] with a thread pool for better asynchrony. Inside Android, I wouldn’t be surprised if they are optimizing it such that you’re better off just spinning a new thread like they tell you to. But this is an OS whose apps are noticeably less fluid than iOS’s, so there’s that.

    That’s is the way things have been done in Java since forever so that’s where Android is coming from. Java NIO is very much where things are headed, and there is an NIO extension for HttpComponents [2] that may well be usable in Android. It’s been around longer than Android. The problem is that callbacks create (even more) bloated code in Java so people are reluctant to use them extensively. Hence, the need for other languages that can represent blocks succinctly.

    By n8 · 2010.12.14 18:22

  3. Trying again with the links:

    http://download.oracle.com/javase/1.5.0/docs/api/index.html?java/util/concurrent/Executors.html

    http://hc.apache.org/httpcomponents-core-ga/httpcore-nio/index.html

    By n8 · 2010.12.14 18:24

  4. Joel:

    After an application receives data, it almost always stores or processes it in some way, and this is a legitimate use of a background thread.

    No, it’s a legitimate use for asynchrony, which may be easily, but not solely, achieved by threads. To force the creation of one (or more) separate network thread improves programmer ease and user experience in much the same way that handing out kevlar improves quality of life in a violence-riddled slum.

    Most programs “store or process data” in most of the code touching library APIs; why not kick every category off onto another thread?

    I was hoping that there was more depth to this issue than “no, the APIs available in Android in combination with the Java language really do make it that hard for us for the majority of applications to do it the right way”, and that I was just too ignorant to see it.

    By Jesper · 2010.12.14 23:10

  5. And having garbage collection is like having garbage collection in a violence-riddled slum.

    By n8 · 2010.12.15 06:04

  6. It’s like my old friend keeps saying: a good metaphor is like a screen door on a dog.

    By Jesper · 2010.12.15 21:15

Sorry, the comment form is closed at this time.