“Native typeface cannot be made” only for some peo

2019-01-02 23:10发布

I have an app that changes the font typeface for some elements. It works well for most of the people, but maybe a 0.5% get an exception when trying to change the font. The significant part of the stack trace is this:

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)

As I say, it works for most of the people, so I don't think it is a problem with the font file or my code. Any suggestions about how to solve this?

Edit: This is my code:

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

15条回答
贼婆χ
2楼-- · 2019-01-02 23:36

In our situation, we had employed Hit's solution with the cache. The problem we introduced was that we were testing for OTF files AND TTF files within the same try block ;) Which is obviously going to fail on the first attempt for OTF if you're looking to get a TTF, but I thought it worth posting JUST incase it slipped passed someone's notice while they might be trying the same solution.

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;
}
查看更多
啃猪蹄的小仙女
3楼-- · 2019-01-02 23:36

This bug of Android OS could be the reason of your issue:

Typeface.createFromAsset leaks asset stream

Where are also a workaround in this bugreport:

I altered HTH's workaround so that the method does not assume the font path or format. The full path of the font asset must be submitted as a parameter. I also wrapped the call to createFromAsset() in a try-catch block so that the get() method will return null if the asset is not found.

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楼-- · 2019-01-02 23:37

in android studio: what have worked for me is putting the ttf file straight to the assets folder without a sub folder of fonts , it didnt work with the sub folder ( (getAssets(),"fonts/oldengl.ttf") didnt work when i had the ttf in src/main/assets/fonts). this works : src/main/assets/oldengl.ttf Typeface customfont=Typeface.createFromAsset(getAssets(),"oldengl.ttf");

查看更多
祖国的老花朵
5楼-- · 2019-01-02 23:38

In my case, it was based on the filename of the font. For some reason it was named FontName..ttf

I don't know why the double-dots were there - I looked up the original font and they were in my windows\fonts folder as FontName..ttf. Windows apparently didn't care, but Android freaked out. I renamed the file, and it's all happy now.

查看更多
Fickle 薄情
6楼-- · 2019-01-02 23:41

Change this one

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

to

Typeface phoneticFont = Typeface.createFromAsset(getAssets(),
                                             "CharisSILR.ttf");
查看更多
Lonely孤独者°
7楼-- · 2019-01-02 23:44

Do with lower case:

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

Remember to also rename the file.

查看更多
登录 后发表回答