There's a HUGE problem in my code wherein I am loading a font in my assets\fonts\
folder from a custom TextView
class. The first problem is that it crashes on 4.0 devices with the exception Caused by: java.lang.RuntimeException: native typeface cannot be made
. I was using the same process here with the method:
public class MyTextView extends TextView {
public MyTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyTextView(Context context) {
super(context);
}
public void setTypeface(Typeface tf, int style) {
if (style == Typeface.BOLD) {
super.setTypeface(Typeface.createFromAsset(
getContext().getAssets(), "fonts/hirakakupronbold.ttf"));
} else if (style == Typeface.ITALIC) {
super.setTypeface(Typeface.createFromAsset(
getContext().getAssets(), "fonts/hirakakupronitalic.ttf"));
} else {
super.setTypeface(Typeface.createFromAsset(
getContext().getAssets(), "fonts/hirakakupron.ttf"));
}
}
}
Notice that I'm using the extension .ttf
, and I found that this is causing the RunTimeException
. So I converted the respective fonts with a .otf
extensions, and now it runs already in 4.0 devices but has memory leaks basing here. There are workarounds here but I don't know how to use/call it. Any help would do, thank you.
Okay, so I finally figured that instantiating a TypeFace
object inside a TextView
class would cause so much load each time that same TextView
is instantiated. This caused my app to lag and resulted to OutOfMemoryException
eventually. So what I did was to create a different custom TypeFace
class that would call my fonts from the assets so that it instantiates from the TypeFace
class and not from the TextView
class.
Here's my TypeFaces class:
public class TypeFaces {
private static final Hashtable<String, Typeface> cache = new Hashtable<String, Typeface>();
public static Typeface getTypeFace(Context context, String assetPath) {
synchronized (cache) {
if (!cache.containsKey(assetPath)) {
try {
Typeface typeFace = Typeface.createFromAsset(
context.getAssets(), assetPath);
cache.put(assetPath, typeFace);
} catch (Exception e) {
Log.e("TypeFaces", "Typeface not loaded.");
return null;
}
}
return cache.get(assetPath);
}
}
}
And the custom TextView class:
public class TextViewHirakaku extends TextView {
public TextViewHirakaku(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public TextViewHirakaku(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TextViewHirakaku(Context context) {
super(context);
}
public void setTypeface(Typeface tf, int style) {
if (style == Typeface.BOLD) {
super.setTypeface(TypeFaces.getTypeFace(getContext(),
"fonts/hirakakupronbold.ttf"));
} else if (style == Typeface.ITALIC) {
super.setTypeface(TypeFaces.getTypeFace(getContext(),
"fonts/hirakakupronitalic.ttf"));
} else {
super.setTypeface(TypeFaces.getTypeFace(getContext(),
"fonts/hirakakupron.ttf"));
}
}
}
Notice that I'm now calling getTypeFace
method from TypeFaces
class here.