“本地字体无法制作”只适用于某些人

我有一个应用程序,可以改变一些元素的字体。对于大多数人来说,这种方法很管用,但是也许有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);
59714 次浏览

Android 操作系统的这个 bug 可能就是你问题的原因:

CreateFromAsset 泄露资产流

在这个 bugreport 中还有一个变通方法:

我修改了 HTH 的变通方法,这样该方法就不会采用字体 字体资产的完整路径必须以 我还将对 createFromAsset ()的调用包装在 Try-catch 块,以便 get ()方法在资产 找不到。

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

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

资产似乎无法进口: Android 图书馆资产文件夹不会被复制

这里还有一些其他的案例: 使用自定义字体时出现问题-“无法制作本机字体”

在我的例子中,它基于字体的文件名,由于某种原因它被命名为 FontName. . ttf

我不知道为什么有两个点-我查找原始字体,他们在我的窗口字体文件夹作为字体名称。.TTF.Windows 显然不在乎,但是 Android 吓坏了。我重新命名了文件,现在一切都很顺利。

我遵循了这里找到的一些解决方案,但没有成功。我认为这是一些非常隐晦的东西,就像程序员经常做的那样。然后我在某个地方读到它可能与字体路径有关,抓到你了:

而不是:

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

我改成:

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

我的文件在 asset/fonts/blach _ cap. ttf 文件夹中!

我一直在纠结这件事。我尝试了所有的可能性,但都没用。最后,问题出在别的地方。如果您正在使用 Gradle 构建项目,不要忘记在 build.Gradle 文件中添加这些行。这解决了我的问题。

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

使用小写字母:

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

记住还要重命名文件。

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

  1. 在主项目资产文件夹中,创建一个称为“字体”的子文件夹
  2. 将 ttf 文件复制到 asset/fonts 文件夹中。我的文件名是 camelcase (例如 Reserve Grunge.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" />
    

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

在我们的情况下,我们已经使用了命中的解决方案与缓存。我们引入的问题是,我们正在测试的 OTF 文件和 TTF 文件在同一个 try 块中;)这显然是要失败的第一次尝试 OTF,如果你想得到一个 TTF,但我认为它值得张贴只是因为它溜过了别人的通知,而他们可能正在尝试相同的解决方案。

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

在我的例子中,我只是删除了资产文件夹(我手动创建的) ,并使用向导创建了一个新的文件夹。显然,它不是作为资产文件夹读取的,而是作为一个普通文件夹读取的,因此 getAsset ()无法工作,并给出了错误。

您必须在 AndroidStudio 中的 Src-> 总台中创建资产文件夹!

在 android 工作室中: 对我有效的是把 ttf 文件直接放到资产文件夹,没有一个子文件夹的字体,它不工作的子文件夹((getAsset () ,“ fonts/oldengl.ttf”)不工作时,我有在 src/main/asset/fonts)。 这个方法可行: Src/main/asset/oldengl.ttf Typeface customfont = Typeface.createFromAsset (getAsset () ,“ oldengl.ttf”) ;

换这个

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

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

我是运行在这个问题时,我导入了一个模块,这是为了支持两个 Eclipse 风格的项目和 android 工作室风格的项目。

我通过从源集中删除资产来解决我的问题

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 工作室风格也可以解决这个问题。

对我来说,

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

但是我两个小时都想不明白。

此错误的可能情况,

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

对于 ex: 字体/roboto.ttf而不是 字体/roboto.otf