RuntimeException:无法制作本机字体或自定义 TextView 加载字体的内存泄漏
Posted
技术标签:
【中文标题】RuntimeException:无法制作本机字体或自定义 TextView 加载字体的内存泄漏【英文标题】:RuntimeException: native typeface cannot be made or memory leak for custom TextView loading font 【发布时间】:2014-01-23 10:13:50 【问题描述】:我的代码中存在一个巨大的问题,其中我从自定义 TextView
类加载我的 assets\fonts\
文件夹中的字体。第一个问题是它在 4.0 设备上崩溃,但 Caused by: java.lang.RuntimeException: native typeface cannot be made
除外。我正在使用相同的过程here 方法:
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"));
请注意,我正在使用扩展名.ttf
,我发现这是导致RunTimeException
的原因。所以我用.otf
扩展名转换了各自的字体,现在它已经在4.0 设备中运行,但基于here 存在内存泄漏。有解决方法here,但我不知道如何使用/调用它。任何帮助都可以,谢谢。
【问题讨论】:
【参考方案1】:好的,所以我终于想到,在 TextView
类中实例化 TypeFace
对象会在每次实例化相同的 TextView
时导致如此多的负载。这导致我的应用程序滞后并最终导致OutOfMemoryException
。所以我所做的是创建一个不同的自定义 TypeFace
类,该类将从资产中调用我的字体,以便它从 TypeFace
类而不是 TextView
类实例化。
这是我的 TypeFaces 类:
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);
还有自定义的 TextView 类:
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"));
请注意,我现在在这里从 TypeFaces
类调用 getTypeFace
方法。
【讨论】:
【参考方案2】:如果您在 android Studio 上遇到此问题,请将您的资产放在主目录下,而不是放在 res 目录下。
在字体命名中也只能使用小写字母和下划线,例如我的字体.ttf
这对我来说很有魅力
【讨论】:
【参考方案3】:如果您是从 xml 扩展此视图,请尝试以这种方式使用它::
public class MyTextView extends TextView
public MyTextView(Context context, AttributeSet attrs, int defStyle)
super(context, attrs, defStyle);
init();
public MyTextView(Context context, AttributeSet attrs)
super(context, attrs);
init();
public MyTextView(Context context)
super(context);
init();
public void init()
Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/hirakakupronbold.ttf");
setTypeface(tf);
它对我来说工作正常。为每种字体样式创建单独的类扩展 TextView。要应用它,请将“TextView”替换为“com.yourpackage.MyTextView”
问候,
【讨论】:
【参考方案4】:就我而言,我用于自定义视图 (costum) 的 XML 命名空间前缀设置不正确:
xmlns:costum="http://schemas.android.com/apk/tools"
我要做的就是把它改成
xmlns:costum="http://schemas.android.com/apk/res-auto"
& 成功了。
【讨论】:
以上是关于RuntimeException:无法制作本机字体或自定义 TextView 加载字体的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章
java.lang.RuntimeException:无法连接到相机服务
Android Java.Lang.RuntimeException:无法启动活动组件信息
java.lang.IllegalArgumentException:无法加载本机库
java.lang.RuntimeException:无法在尚未调用 Looper.prepare() 的线程上敬酒 [重复]