1

I'm right at the beginning of building an app (which doesn't even do anything yet, but display some buttons) and when I run it, I get the error message in logcat: "purding 193K from font cache [23 entries]" over and over, until about a minute later the app crashes due to low memory. My 3 buttons are custom buttons, using a custom font. Problem with the font perhaps?

Emma Assin
  • 851
  • 2
  • 12
  • 23
  • Yep. I think we need more details about your font and how you are using it. – Matthew Mar 09 '11 at 20:22
  • I think I may have got to the bottom of it. I was setting the Typeface in the onDraw method of the custom button. Moved it to the constructor and I don't get the problem any more :) – Emma Assin Mar 09 '11 at 20:40
  • I use Typeface.createFromAsset() extensively within onCreate() for a bunch of textview's (inflated from XML) and I see this skia message for every Activity.this.finish() – Someone Somewhere Jun 27 '11 at 18:30

2 Answers2

6

The problem is calling Typeface.createFromAsset().

I've reduced that creating a font factory, so it calls Typeface.createFromAsset() once per font type.

The font factory holds the typeface in a hashmap and that does the trick.

I found the solution on this link and tweaked a little bit:

http://www.levinotik.com/2011/09/22/custom-fonts-in-android-can-cause-issues-heres-how-to-fix-it/

This is how I've implemented it.

public class FontFactory {
    private static FontFactory instance = new FontFactory();
    private HashMap<String, Typeface> fontMap = new HashMap<String, Typeface>();

    private FontFactory() {
    }

    public static FontFactory getInstance() {
        return instance;
    }

    public Typeface getFont(String font) {
        Typeface typeface = fontMap.get(font);
        if (typeface == null) {
            typeface = Typeface.createFromAsset(MyApplication.getApplicationContext().getResources().getAssets(), "fonts/" + font);
            fontMap.put(font, typeface);
        }
        return typeface;
    }
}
tbraun
  • 2,636
  • 31
  • 26
0

I've been able to drastically reduce this skia message (and eventual low-memory condition) by declaring the Typeface as static within the activity class.

i.e.

public class myActivity extends Activity
{
    //font
    private static Typeface mFontHelvet;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mylayout);

        if (mFontHelvet == null)
        {
            mFontHelvet = Typeface.createFromAsset(this.getAssets(), "Helvetica.TTF");
        }

        myTextView = (TextView) findViewById(R.id.mytextview);
        myTextView.setTypeface(mFontHelvet);
        myTextView.setText("blah blah");
    }
}

this might seem risky, but at least a user can go back and forth between my two activities without entering a low-memory state !

Someone Somewhere
  • 23,475
  • 11
  • 118
  • 166
  • 1
    You could move this into a class that extends Application and have a `getHelvet();` method that way it's only ever loaded once per app run, rather than each time the activity is created. – Blundell Mar 18 '12 at 22:32
  • @Blundell could you please provide a sample of what you are recommending. I kinda have the same situation where I use custom fonts on my app. But I put it in every activity in my code. So the activities loads slowly. – SleepNot Aug 15 '12 at 11:15
  • 1
    jeraldov - see this tutorial to "extend Application": http://www.devahead.com/blog/2011/06/extending-the-android-application-class-and-dealing-with-singleton/ – Someone Somewhere Aug 17 '12 at 06:17