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

15 回答 15

68

Android 操作系统的这个错误可能是您的问题的原因:

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);
        }
    }
}
于 2012-10-26T12:43:09.047 回答
52

我遵循了此处找到的一些解决方案,但没有成功。我认为这真的很晦涩,就像程序员经常做的那样。然后在某处我读到它可能与字体路径有关,明白了:

代替:

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

我改为:

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

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

于 2013-07-20T20:35:07.917 回答
50

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

似乎无法导入资产: Android 库资产文件夹没有被复制

以下是其他一些情况:使用自定义字体时的问题 - “无法制作原生字体”

于 2013-01-05T09:47:24.130 回答
25

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

    sourceSets {
    main {
        assets.srcDirs = ['assets']
    }
}
于 2013-08-11T10:19:53.863 回答
7

您必须在 AndroidStudio 的src --> main中创建 assets 文件夹。这种方法奏效了!

于 2014-11-18T07:43:07.640 回答
4

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

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

于 2013-01-29T13:36:04.810 回答
4

对于我的情况,我发现资产文件夹位于/main/java/assets但它们必须位于/main/assets

于 2014-08-15T14:10:10.827 回答
2

使用小写:

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

请记住还要重命名文件。

于 2013-12-05T06:42:25.573 回答
1

换这个

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

Typeface phoneticFont = Typeface.createFromAsset(getAssets(),
                                             "CharisSILR.ttf");
于 2016-02-13T11:38:58.783 回答
0

我在使用 qwerjk 的 MagicTextView 时遇到了这个问题。我试图将 MTV 类放在一个库中并在我的主项目中使用它。这是我如何让它工作的:

  1. 在主项目资产文件夹中,创建一个名为 fonts 的子文件夹
  2. 将 ttf 文件复制到 assets/fonts 文件夹中。我的文件名是驼峰式(例如 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" />
    
于 2014-05-11T05:46:16.580 回答
0

就我而言,我刚刚删除了资产文件夹(我手动创建的)并使用向导创建了一个新文件夹。显然它不是作为资产文件夹读取的,而是作为普通文件夹读取的,因此 getAssets() 不起作用并给了我错误。

于 2014-10-28T10:49:45.593 回答
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;
}
于 2014-10-06T17:47:27.723 回答
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");

于 2015-08-27T00:27:29.740 回答
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 风格也可以解决我猜的问题。

于 2016-04-19T06:33:00.043 回答
0

就我而言,

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

但是我2小时都想不通..

此错误的可能情况,

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

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

于 2016-10-31T09:31:07.067 回答