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

后端 未结 4 1284
没有蜡笔的小新
没有蜡笔的小新 2021-01-03 08:07

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

4条回答
  •  悲&欢浪女
    2021-01-03 08:24

    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 cache = new Hashtable();
    
        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.

提交回复
热议问题