Image debugging

The other day I was asked to help out a colleague who was running into some problems while generating an image.

He would generate the image in an Android app, but when he previewed the generated image, sometimes the image was broken. The bottom part of the image seemed to be missing altogether.

What he would do is the following:

  1. Add some text to a Canvas.
  2. Add some images to the Canvas.
  3. Convert the generated Bitmap to a Base64 encoded PNG String.
  4. Print out the Base64 String.
  5. Copy the Base64 String into another Kotlin app. (This was the easiest way for him, as he was new to Android.)
  6. Write the image to the hard drive of his laptop.
  7. Open the image in an image viewer.

The first thing we checked was what configuration was used to load the image that we added to the composite. Changing the configuration made unfortunately no difference to the outcome.

Next we changed how the image was loaded. Originally a Base64 String was decoded and converted to a Bitmap. We changed this to a bit more Android like way by loading the image from Resources. This made no difference either, the resulting image was still broken.

Right, so it’s not the configuration and not how the image is stored. Maybe it is this particular image that is causing it? Replaced this image with a different image and guess what? Still no luck! The resulting composite image was again broken.

Time to take some drastic measures. Let’s turn off steps of the compositing process until we find what step is causing it. Not adding an image, no luck. Not adding two images, nope! Ok, let’s not add text either, of course not. The only thing left was to not fill the background with a solid colour. That seemed to do it!

Obviously generating an empty image wasn’t an option, so we had to keep looking. Taking another leap, we decided to try and preview the image directly in the Android app. Turning all compositing steps back on and now displaying the image in the app directly. Success!

How was this possible? We had gotten a broken image as a result every single time. Then it (finally) hit me: Logcat has a maximum line length! Anything that exceeds the line length gets truncated. The Base64 encoded String that represented the composite image was naturally quite long, exceeding the Logcat maximum line length and thus getting truncated. As a result we had a broken image no matter what we tried.

The moral of the story: Don’t trust your console to print everything you throw at it.

SQLite on Android

Warning: Illegal string offset 'language' in /var/www/vhosts/ on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ on line 513 Warning: Illegal string offset 'language' in /var/www/vhosts/ on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ on line 513 Warning: Illegal string offset 'language' in /var/www/vhosts/ on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ on line 513

In the past week I started working with SQLite databases on Android.

It can be quite cumbersome to explore the data stored in the DB on an actual device. What has helped me a lot is grabbing the DB from the device and loading the SQLite DB in a third party SQLite browser / manager. This will give you a lot more flexibility on exploring the data that is stored and will also be a great help for testing your queries.
You can retrieve your database from the device using ADB:

  1. adb pull /data/data/[app_package]/databases/[db_file] .

I’ve been using SQLiteBrowser to explore the DB and test my queries.

One thing I noticed is that inserting around a hundred rows took quite some time, about 350ms. I was inserting one row at a time and after some Googling on how to insert multiple rows in one query, I found an answer on StackOverflow. The suggestion was to do something like the following:

  1. INSERT INTO 'tablename'
  2.     SELECT 'data1' AS 'column1', 'data2' AS 'column2'
  3.     UNION SELECT 'data3', 'data4'
  4.     UNION SELECT 'data5', 'data6'
  5.     UNION SELECT 'data7', 'data8'

After trying this approach it cut the insertion time in half near the 170ms mark, still quite slow.
Some more searching brought me to an article about “Speeding up SQLite insert operations“. What this article advises is to use transactions, an example:

  1. database.beginTransaction();
  2. for (...) {
  3.     database.insert(...);
  4. }
  5. database.setTransactionSuccessful();
  6. database.endTransaction();

Using this technique the insertion was sped up to roughly 25ms, much better!

As an alternative to using a database, you could just store the data on disk. This works fine especially when you just use a database to store data and don’t need to sort it or do more complex queries. Even if you needed sorting, you could use the SortedMap class.

IntelliJ keyboard shortcuts

Recently I switched from Eclipe to IntelliJ and that meant getting to know IntelliJ’s keyboard shortcuts. Below is a list of the shortcuts I use most.

crtl + n = Open resource.
ctrl + f4 = Close window.
alt + [left/right arrow] = Move to the window on the left/right.
ctrl + shift + f = Find in path, i.e search in whole project.

Text operations
ctrl + d = Duplicate line.
ctrl + y = Remove line.
ctrl + shift + [up/down arrow] = Move line up / down.
ctrl + g = Navigate to line.
ctrl + shift + u = Toggle case.

ctrl + q = Quick docs (floating documentation window when having selected a class, method, member).
ctrl + f12 = Show members.
alt + f7 = Find usage.
shift + f6 = Refactor > rename.
ctrl + alt + l = Format.
ctrl + alt + [left/right arrow] = Back / Forward.
alt + insert = Generate code, i.e. constructor, getters/setters.

Global Exception handling in Android

Warning: Illegal string offset 'language' in /var/www/vhosts/ on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ on line 513

To be able to catch any exception you may encounter that isn’t part of a try-catch-clause, you can use the Thread.setDefaultUncaughtExceptionHandler( Thread. UncaughtExceptionHandler ) method.

In the handler you can then perform whatever action you want. Don’t forget to call “System.exit()” though, because otherwise this won’t work!

A simple example:

  1. public class SomeActivity extends Activity {
  3.     private static final String LOG_TAG = "SomeActivity";
  5.     @Override
  6.     protected void onCreate(Bundle savedInstanceState) {
  7.         super.onCreate(savedInstanceState);
  8.         Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
  9.             @Override
  10.             public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
  11.                 Log.e(LOG_TAG, "OMG! Uncaught Exception!");
  12.                 // Without calling System.exit() this will not work.
  13.                 System.exit(2);
  14.             }
  15.         });
  16.     }
  17. }

For some more details have a look at “Using Global Exception Handling on android” on

Ant-Contrib for loop error

Warning: Illegal string offset 'language' in /var/www/vhosts/ on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ on line 513

When trying to use Ant-Contrib for loops today, I ran into the error below:

C:\Projects\…\ant\build.xml:200: Problem: failed to create task or type for
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any <presetdef>/<macrodef> declarations have taken place.

To fix the error I had to update the Ant-Contrib taskdef resource path from using “” to use “antlib.xml” in my Ant build file.

  1. // Remove this line
  2. <taskdef resource="net/sf/antcontrib/>
  3. // And replace with this one
  4. <taskdef resource="net/sf/antcontrib/antlib.xml">

According to the Ant-Contrib manual (found in [Ant-Contrib install dir]/docs/manual/index.html) you need to use the “” file when you want Ant-Contrib to run with Ant Version 1.5. They even place a warning saying:

Keep in mind that some tasks will not be available to you , such as the <for> task

The confusing part is that on the project page they tell you to use the “” file.

Making your Flash faster / smaller

Lately I’ve been looking into optimizing SWF in both speed in file size, below is a list of interesting projects I came across.

Optimizers / disassemblers


Faster compilation

AS3 Language Specification:

I’m sure there are some projects I missed… Please do let me know about any good ones I omitted.

Installing ANT contrib for Eclipse

Warning: Illegal string offset 'language' in /var/www/vhosts/ on line 510 Warning: ksort() expects parameter 1 to be array, string given in /var/www/vhosts/ on line 513

A quick step by step guide to installing ANT-contrib for Eclipse (on Windows).

  1. Download ANT-contrib:
  2. Extract the zip to your harddrive, I extracted it to C:/ant-contrib/
  3. Include ANT-contrib in your ANT build file, so you don’t have to set it up every time you create a new project. (See XML below)
  4. All done!

Additional XML in ANT build script:

  1. &lt;taskdef resource="net/sf/antcontrib/"&gt;
  2. &lt;classpath&gt;
  3. &lt;pathelement location="[full path to ant-contrib jar]"/&gt;
  4. &lt;/classpath&gt;
  5. &lt;/taskdef&gt;