Android : 处理多个字体文件 - 正确的方法

Android : Dealing with multiple font files - Correct way

在我的应用程序中,我需要处理多个字体文件。因此,我没有每次都创建新实例,而是实现了 Singleton 来获取 Typeface,如下所示:

public class FontSingleton {

    private static FontSingleton instance;
    private static Typeface typeface;

    private FontSingleton(){
        //private constructor to avoid direct creation of objects
    }

    public static FontSingleton getInstance(Context context,String fontFileName){
        if(instance==null){
            instance = new FontSingleton();
            typeface = Typeface.createFromAsset(context.getResources().getAssets(), fontFileName);
        }
        return instance;
    }

    public Typeface getTypeFace(){
        return typeface;
    }
}

现在,我可以这样得到 typeface

FontSingleton.getInstance(mContext,"font1.otf").getTypeFace();

处理内存泄漏和实现单例的正确方法是什么?我是设计模式的新手 Android。谁能指导我正确的方法?

Is is the correct way to deal with memory leak and implementing Singleton?

getInstance()应该是synchronized,在你标记为synchronized之后,那么对于模式的实现来说它是正确的。我仍然认为它不太适合您的需要。例如,您不能创建新的 TypeFace 对象。你写它的方式你被困在使用font1.otf。如果需要,则无需提供字体名称作为 getInstance().

的参数

作为替代解决方案,您应该考虑子类化 TextView 的可能性,提供自定义 xml 属性,您可以通过该属性指定要使用的字体。

如果我没看错的话,这太复杂了而且不正确(实例将始终保留给它的第一个字体,因为它不会再被调用,因为实例已经存在)。

为什么不实现这样的东西:

public class FontHelper {
    public static Typeface get(Context context, String fontFilename) {
        return Typeface.createFromAsset(context.getResources().getAssets(), fontFileName);
    }
}

那么您只需拨打:

FontHelper.get(mContext,"font1.otf")

FontSingleton 设为单例是没有用的,因为您真正需要的是缓存 Typeface 对象,而不是创建它们的 class。因此你可以让你的FontSingleton(它不再是单例,所以我们称它为FontHelper)一个没有实例的class,并让它存储一个Map Typefaces。这些将以惰性方式创建:如果字体名称没有 Typeface - 创建它并将其存储在 Map 中,否则重用现有实例。这是代码:

public class FontHelper {

    private static final Map<String, Typeface> TYPEFACES = new HashMap<>();

    public static Typeface get(Context context,String fontFileName){
        Typeface typeface = TYPEFACES.get(fontFileName);
        if(typeface == null){
            typeface = Typeface.createFromAsset(context.getResources().getAssets(), fontFileName);
            TYPEFACES.put(fontFileName, typeface);
        }
        return typeface;
    }
}

抱歉,如果代码不能正常工作,但希望思路清晰。