Levi's Blog

Android custom fonts and memory issues: a quick fix

Levi Notik

Android allows you to import custom fonts into your project (just copy a .ttf file into your assets folder and you’re good to go). Typically, you’ll grab the custom font, like this

Typeface myTypeface = Typeface.createFromAsset(getResources().getAssets(), 
    "fonts/DroidSerif-Bold.ttf");

If you’re using custom fonts a lot (constantly grabbing the font inside of your Views or Activities), it can create a major strain on memory. In my app, I noticed that as I switched between activities, Logcat was spitting out something like the following: DEBUG/skia(1510): purging 197K from font cache [20 entries]. Ok, so apparently there’s some caching mechanism and it’s getting purged. Sounds good. The problem was that this was happening way too often. Eventually, the memory was so strained that Android started killing all processes on the device until, eventually, my app was killed as well.

Here’s how to fix this: if you need to grab a custom font often, use a Singleton which holds on to and returns the Typeface when you request. For good measure, you can even hold onto the Typeface as a static field inside of the classes in which you use it.

All you need is something like this:

public class TypefaceSingleton {

    private static TypefaceSingleton instance = new TypefaceSingleton();

    private TypefaceSingleton() {}

    public static TypefaceSingleton getInstance() {
        return instance;
    }

    public Typeface getDroidSerif() {
        return Typeface.createFromAsset(MyApp.getContext().getResources().getAssets(), "fonts/DroidSerif-Bold.ttf");
    }
}

Notice, I’m using “eager”, as opposed to “lazy” instantiation (where getInstance() checks if the instance is null), but either way should work. After I switched to using the Singleton implementation, the memory issues disappeared.

Hope this helps.

Back to top