仅某些人可以“制作本机字体”


74

我有一个可更改某些元素字体字体的应用程序。它对大多数人来说效果很好,但是尝试更改字体时可能会有0.5%的异常。堆栈跟踪的重要部分是:

Caused by: java.lang.RuntimeException: native typeface cannot be made
at android.graphics.Typeface.<init>(Typeface.java:147)
at android.graphics.Typeface.createFromAsset(Typeface.java:121)

正如我所说,它对大多数人都有效,所以我认为这与字体文件或代码无关。关于如何解决这个问题的任何建议?

编辑:这是我的代码:

Typeface phoneticFont = Typeface.createFromAsset(getAssets(),
                                                 "fonts/CharisSILR.ttf");
TextView tv;
tv = ((TextView) findViewById(R.id.searchPronunciationTitle));
tv.setTypeface(phoneticFont);

我已经用代码更新了问题。
user936580 2012年

您将ttf文件放在哪里。
Rishabh Agrawal

您从哪个Android版本收到此错误?我是从一个GT-I9000,2.3.6
bigstones

我已经在Android 2.2和2.2.2版中得到它
user936580 2012年

您看过< karanbalkar.com/2013/07/… >吗?这是将roboto字体添加到android应用中的简单方法。
2013年

Answers:


68

Android OS的此错误可能是导致您出现问题的原因:

Typeface.createFromAsset泄漏资产流

此错误报告中还有什么解决方法:

我更改了HTH的解决方法,以使该方法不采用字体路径或格式。字体资产的完整路径必须作为参数提交。我还将对createFromAsset()的调用包装在try-catch块中,这样,如果找不到资产,则get()方法将返回null。

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);
        }
    }
}

4
谢谢。如果我对它的理解正确,那么该错误的描述就说明该问题是内存泄漏,将引发内存不足的错误。但是,这不是我所看到的:我收到“无法制作本机字体”消息,而没有内存不足的异常。另外,对于失败的用户来说,它总是失败的,并且我的应用程序不使用很多资源。
user936580 2012年

1
@ user936580加载字体时,catch块将避免异常爆炸给您的用户。这里的权衡是丑陋的字体而不是崩溃。我认为值得:)
Bolhoso,2013年

1
@Hit您如何使用/调用此方法?我一直在努力弄清楚。
Compaq LE2202x 2014年

我没有帮我摆脱Exception,但是如果我Typefacesandroidsvg库一起使用,它将停止泄漏大量内存,在该库中,我使用加载了多种字体SVGExternalFileResolver
德克2014年

52

我遵循此处找到的一些解决方案,但没有成功。我认为它确实像程序员经常做的那样晦涩难懂。然后在我读过的某处可能与字体路径有关,即:

代替:

Typeface phoneticFont = Typeface.createFromAsset(getAssets(),
                                             "blanch_caps.ttf");   

我改为:

Typeface phoneticFont = Typeface.createFromAsset(getAssets(),
                                             "fonts/blanch_caps.ttf");   

我的文件在assets / fonts / blanch_caps.ttf中。不是它像魅力一样起作用!


1
这确实对我有用,非常感谢!虽然有一些小技巧:我的字体被称为用大写字母,像这样我不得不把它写在代码中还大写字母“COOPBL.TTF” ..也许它可以帮助别人:)
ylka

还修复了它createFromFile
0101100101

50

当字体在库资产文件夹中时,出现此错误。当我将其复制到使用该库的应用程序的资产中时,错误消失了。

似乎无法导入资产未复制Android Library资产文件夹

这是其他一些情况:使用自定义字体时出现的问题-“无法制作本机字体”


谢谢,但是我在应用程序资产文件夹中有该字体。它在大多数情况下都有效,但对于某些人却不起作用,我不知道为什么。
user936580 2013年

很高兴知道。我已经在尝试加载每种自定义字体的地方放了try / catch,如果出错,它将默认为内置的android字体,以防ttf字体在某些设备上不起作用。
Lumis

我认为这是因为您使用应用程序的上下文而getAssets()不是库... +1对我有用。
Saeed.re 2014年

25

我为此付出了很多努力。我尝试了所有可能性,没有任何帮助。最后,问题出在别的地方。如果您正在使用Gradle构建项目,请不要忘记在build.gradle文件中添加这些行。这解决了我的问题。

    sourceSets {
    main {
        assets.srcDirs = ['assets']
    }
}

1
谢谢你的回答。我正在使用Eclipse,所以这不是我的问题。
user936580 2013年

10
如果我们使用的是Android Studio和Gradle-请观看此内容。资产目录应直接位于main下。这解决了我的问题。字体名称和字体文件没有任何问题。这一点特别重要,因为我们使用的字体名称使用大写/小写,而资产文件名应全部使用小写。
B先生

15
在Android Studio(当前为0.8.1)下,我不必将行添加到build.gradle,但是我必须将自己的Assets文件夹直接放置在main(例如src\main\assets)下
Dominic K

1
DMan的解决方案对我来说是完美的。我不需要在build.gradle中做任何事情
CodyMace 2014年

当Gradle Android插件低于0.5且您需要自己指定res文件夹时,此答案才有效。现在当然没有必要了!
Michal 2014年

7

您必须在AndroidStudio的src- > main内部创建资产文件夹。这样有效!


4

就我而言,它是基于字体的文件名。由于某种原因,它被命名为FontName..ttf

我不知道为什么双点在那里-我查找了原始字体,它们以我的FontName..ttf出现在我的windows \ fonts文件夹中。Windows显然不在乎,但Android却吓坏了。我重命名了文件,现在一切顺利。


4

就我而言,我发现资产文件夹位于中,/main/java/assets但它们必须位于/main/assets


就我而言!谢谢
Adrian L

2

小写:

Typeface phoneticFont = Typeface.createFromAsset(getAssets(),
                                             "fonts/charissilr.ttf");

记住还要重命名文件。


1

换一个

Typeface phoneticFont = Typeface.createFromAsset(getAssets(),
                                             "fonts/CharisSILR.ttf");

Typeface phoneticFont = Typeface.createFromAsset(getAssets(),
                                             "CharisSILR.ttf");

这样做不起作用,因为我在字体目录中有它。我试图将其放在根目录中,但是无论如何它还是失败了。
user936580 '02

0

我在使用qwerjk的MagicTextView时遇到了这个问题。我试图将MTV课程放在一个库中,并在我的主要项目中使用它。这是我如何使其工作的方法:

  1. 在主项目资产文件夹中,创建一个名为fonts的子文件夹。
  2. 将ttf文件复制到asset / fonts文件夹中。我的文件名是camelcase(例如ReservoirGrunge.ttf),因此大写或无大写似乎无关紧要。
  3. 在我的主要项目中,我从xml扩展了MTV视图。确保MagicTextView指向正确的库路径。例如,我的MTV类库是com.library.library_magictextview.MagicTextView,因此主视图的xml必须读取:

        <com.library.library_magictextview.MagicTextView
        android:textSize=           "50dp"
        android:textColor=          "#ffffffff"
        android:layout_width=       "fill_parent"
        android:layout_height=      "wrap_content"
    
        android:textStyle=          "bold"
        android:padding=            "20dp"
        android:gravity=            "center"
    
        r:strokeColor=          "#FFff0000"
        r:strokeJoinStyle=      "miter"
        r:strokeWidth=          "5"
        r:typeface=         "ReservoirGrunge"
        android:text=               "BobDillon" />
    

0

在我们的情况下,我们在缓存中采用了Hit的解决方案。我们引入的问题是,我们正在同一try块中测试OTF文件和TTF文件;)如果您希望获得TTF,则在第一次尝试进行OTF时显然会失败,但是我认为值得发布只是以防万一它滑倒通过了某人的通知,而他们可能正在尝试相同的解决方案。

protected static Typeface getTypeface(Context p_context, String p_fontName){
    Typeface tf = null;
    try {
        tf = Typeface.createFromAsset(p_context.getAssets(), "fonts/" + p_fontName + ".otf");
    }catch(Exception e) {}

    if( tf != null ) return tf;

    try {
        tf = Typeface.createFromAsset(p_context.getAssets(), "fonts/" + p_fontName + ".ttf");
    }catch(Exception e) {}

    return tf;
}

0

在我的情况下,我只是删除了Assets文件夹(我手动创建的),并使用向导创建了一个新文件夹。显然,它不是作为assets文件夹读取的,而是作为普通文件夹读取的,因此getAssets()无法正常工作,并给了我错误。


0

在android studio中:对我有用的是将ttf文件直接放到没有字体子文件夹的assets文件夹中,它不能与子文件夹一起使用((getAssets(),“ fonts / oldengl.ttf”)在我在src / main / assets / fonts中有ttf)。这有效:src / main / assets / oldengl.ttf字体customfont = Typeface.createFromAsset(getAssets(),“ oldengl.ttf”);


0

当我导入一个旨在支持Eclipse风格项目和android studio风格项目的模块时,我遇到了这个问题。

通过从源集中删除资产,我的问题得到了解决-

defaultConfig {
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName '1.0'

        sourceSets {
            main {
                java.srcDirs = ['src']
                res.srcDirs = ['res']
                //assets.srcDirs = ['assets']//commented this out because modlue was not having this directory
                manifest.srcFile 'AndroidManifest.xml'
            }
        }
    }

或者将项目转换为android studio风格也可以解决我想的问题。


0

就我而言

我只是使用以前的代码。所以我忘记了Assets文件夹中的字体文件。

但是我两个小时都找不到。

此错误的可能情况,

  1. 字体文件丢失
  2. 字体名称错误或扩展名错误

例如:fonts / roboto.ttf而不是fonts / roboto.otf

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.