Memory Leaks with Custom Font for Set Custom Font

Memory leaks with custom font for set custom font

You should cache the TypeFace, otherwise you might risk memory leaks on older handsets. Caching will increase speed as well since it's not super fast to read from assets all the time.

public class FontCache {

private static Hashtable<String, Typeface> fontCache = new Hashtable<String, Typeface>();

public static Typeface get(String name, Context context) {
Typeface tf = fontCache.get(name);
if(tf == null) {
try {
tf = Typeface.createFromAsset(context.getAssets(), name);
}
catch (Exception e) {
return null;
}
fontCache.put(name, tf);
}
return tf;
}
}

I gave a full example on how to load custom fonts and style textviews as an answer to a similar question. You seem to be doing most of it right, but you should cache the font as recommended above.

Using Custom Fonts Properly in Android

You should find your answer here.

Basically you need to build your own system to cache those typefaces after you create them (and therefore you'll only be creating each typeface once).

RuntimeException: native typeface cannot be made or memory leak for custom TextView loading font

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.

Memory leak when using custom text in React Native

You can try loading the fonts in async manner and keep a check in your useEffect to setState only if its not unmounted, like given in this expo documentation using-fontloadasync-instead-of-the-usefonts-hook

Here is the expo snack example

Also, I would suggest to load fonts from local cache instead from direct web, which will increase the app size a little bit, but fonts will load much faster, just like given in the above example.

Memory leak when using custom text field in SwiftUI

Here is fixed part - to avoid cycling it needs to update only with really new value

Tested with Xcode 12 / iOS 14

.onReceive(Just(textValue)) {
guard self.hasInitialTextValue else {
// We don't have a usable `textValue` yet -- bail out.
return
}
// This is the only place we update `value`.
let newValue = self.formatter.number(from: $0)?.decimalValue
if newValue != self.value {
self.value = newValue
}
}

To use or not to use Custom Fonts on Android

Besides what CommonsWare said, (that was my first accepted answer), I have found a major bug, that creates memory leaks when using Custom Fonts:

http://code.google.com/p/android/issues/detail?id=9904#c7

Because of this, I tend to think that it is not a good ideia to use them.. or at least beware when you use them!

If you do need to use them, you can use this to avoid the biggest part of the memory leaks:

public class Typefaces {
private static final String TAG = "Typefaces";

private static final Hashtable<String, Typeface> cache = new Hashtable<String, Typeface>();

public static Typeface get(Context c, String assetPath) {
synchronized (cache) {
if (!cache.containsKey(assetPath)) {
try {
Typeface t = Typeface.createFromAsset(c.getAssets(),
assetPath);
cache.put(assetPath, t);
} catch (Exception e) {
Log.e(TAG, "Could not get typeface '" + assetPath
+ "' because " + e.getMessage());
return null;
}
}
return cache.get(assetPath);
}
}
}


Related Topics



Leave a reply



Submit