Friday, April 9, 2010

Preventing TextView with links inside a ScrollView from dimming

I wrote an Android application that shows a scrollable TextView because I put it inside a ScrollView. When I added links to the TextView, I had to execute this so that the links can be clicked with proper highlighting:


It works:

However, when I use my finger to scroll it, the text other than links are dimmed, very, very dark until we can almost see nothing.
Calling setClickable(false) and setLongClickable(false) fixed the issue, but the link itself is not highlighted anymore when "hovered", and the user may think that the link is not clickable.

I found a solution, which is not perfect, but works. Just set the color of the TextView. The links will stay on the same color, but the normal text will change color, and it does not dim anymore!

Here is what I get using #fff (a.k.a. 0xffffffff) color.

Tuesday, April 6, 2010

String.format in Android is extremely slow!

I'm used to using String.format to construct messages. Even when I don't need to specify width or number of decimal places. It just looks neater to the eyes.

For example, on the Alkitab (Bible) application, I wrote this for debugging:

Log.d("alki", String.format("tebakKitab fase 3: dengan %s:%d skor %d", ref.pendek, ref.pos, skor));

Each of "my operation", involving about 70 calls to the above line, takes about 300 ms. I thought that was acceptable.

But when I tried to build a game engine, I found a bottleneck somewhere that drags the fps. I found it to be the String.format call, which takes about 6ms for just one call! That's ridiculously slow.

Guess what: when I change the above line to:

Log.d("alki", "tebakKitab fase 3: dengan " + ref.pendek + ":" + ref.pos + " skor " + skor);

"my operation" takes only 22 ms!

Okay, once again: Don't use String.format in Android applications!

Note: When I traced method calls to know what makes it slow, String.format apparently calls a very deep code, something with DecimalFormatter, even CurrencyFormatter even though I didn't use it. It also calls** packages. It really has a huge logic inside.