Android for ActionScript developers, part 3: Threads and blocking

Multithreading support – the ability to run different blocks of code separately, in parallel – has always been a requested feature in the Flash/ActionScript community (and it’s, indeed, coming). But the reality is, due to the way the platform is designed, reasons to use concurrency in Flash are very rare. I’m sure some exist, but it’s not part of the tasks you normally have to program into a website or even a generic application.

The reason is simple. Consider the following code:

var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load("myimage.jpg");

protected function onLoadComplete(__e:Event) {
	trace("Image loaded!");
}

The code will attempt to load an image and, when that is complete, display a message stating it did so.

The important thing to notice about this code is that it is non-blocking; when the call to load() is made, Flash just continues execution of your next line of code as if nothing happened. This is one of the many moments where Flash executes your requests asynchronously, letting you know later (via an event) when that request has been completed (or reporting on its progress, or any other event conditions necessary).

One big hurdle I had when I started working with Java is realizing that the language is, indeed, blocking everything you’re doing. Consider a similar code to load an image on Android:

URL fileURL = null;
try {
	fileURL = new URL("http://domain.com/myimage.jpg");
} catch (MalformedURLException e) {
	Log.e("", "Error: URL is malformed");
}
try {
	HttpURLConnection connection = (HttpURLConnection)fileURL.openConnection();
	connection.setDoInput(true);
	connection.connect();
	InputStream inputStream = connection.getInputStream();

	Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
	myImageView.setImageBitmap(bitmap);
} catch (IOException e) {
	Log.e("", "Error: I/O Exception");
}

Apart from syntactical differences, the big distinction about this code is that when the Android system reaches the lines that make the connection and download the file, the whole execution thread hangs and waits for the file to download, continuing after it’s done. That’s why a completion event is not necessary; no code will be executed until the task is complete anyway.

This creates a situation where it’s very easy for a developer to write code that will technically work, but also hijack the main (UI) thread while running complex pieces of code, freezing the application. In an environment like this, it’s easy to see why threading is extremely relevant. It’s not just sugar; it’s something absolutely needed for a responsive user experience.

The solution in Android is creating a separate process for that kind of problem – a thread that executes a task, then, implements event or message dispatching as needed. The code is a bit more involved and there are different ways to do it; you have to decide between Threads or AsyncTasks, for starters. That’s why one of the first things I’ve done when working with the Android platform was build classes that allow me to work on the main UI thread without having to worry about blocking user execution all the time. With names like TextLoader, Loader, and XMLLoader, they essentially emulate what the Flash platform already does by default.

Maybe because they’re not as necessary in Flash, I used to think that working with threads was this untouchable apogee of low-level programming techniques that would only be necessary in crazily computationally expensive tasks. The reality, however, is quite different: on a platform like Android, if you don’t use separate threads for things that take more than a few milliseconds, you are doing something wrong.

  • Jan

    Zeh good point!

    But think about a situation where you are an animation running in the screen and you call some service in background, if the result of this service is a json or something you need to parsing, your animation will be blocked to running this task. It’s a bad thing.

    In my opinion, it’s the most common situation where threads could be help.

    A good practice to avoid this, is to wait until the end of expressive animations to do non visual tasks like read data, but sometimes it’s sounds like a “workaround”, because you delay to display the most important information to user.

    Even though the flashplayer’s performance is enough to do any parse, serialization, deserialization, anyway… threads are welcome to help in this point.

  • Zeh

    Jan, totally agreed. I had moments before where a thread would have been the right solution… I remember specifically a couple of moments where I had to do LZW compression on a large chunk of data (before Flash had the bytearray compression algorithms). I ended up having to roll a custom solution that would do the task in chunks, using intervals, with a given “priority” (running on the background) and updating a property that indicated compression/decompression progress. It was similar to, say, loading a file, since the compression could take more than 10 seconds and I definitely didn’t want to hang the player for that. Threads would have been perfect for that.

    My point with the article is that while they exist, those needs are hard to come by in the Flash platform. I guess my issue is that sometimes I see people with Java or C experience working in ActionScript and being surprised it doesn’t have threads – because they expect to *need* to use threads to do anything. But that’s often not the case, just because of the way the language is actually designed, and people with experience in other platforms should be aware of that.

  • Pingback: AS开发android应用——线程与阻塞 | Flash开发者大会()