74
votes

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
I've updated the question with the code.user936580
where your put your ttf file.Rishabh Agrawal
what's the android version from which you're getting this error? I got it from a GT-i9000, 2.3.6bigstones
I've gotten it in Android versions 2.2 and 2.2.2user936580
Have you seen <karanbalkar.com/2013/07/…>? this is a simple way to add roboto font into android app.Pranav Jagtap

15 Answers

68
votes

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

I followed some of the solutions found here, with no success. I thought it was something really obscure, as programmers often do. Then somewhere I read it could be related to the font path, gotcha:

Instead of:

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

I changed to:

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

And my file is in assets/fonts/blanch_caps.ttf. Not it works like a charm!

50
votes

This error came up when the font was in the library asset folder. When I copied it into assets of the application which was using this library, the error disappeared.

It seems assets cannot be imported: Android Library assets folder doesn't get copied

And here are some other cases: Issue when using a custom font - "native typeface cannot be made"

25
votes

I was struggling with this a lot. I tried every possibility and nothing helps. In the end, to problem was somewhere else. If you are building your project with Gradle, don't forget to add these lines in build.gradle file. This solved the problem in my case.

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

You must create assets folder inside src-->main in AndroidStudio. This way worked!

4
votes

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.

4
votes

For my case I have found that the assets folder located in /main/java/assets but they must be in /main/assets

2
votes

Do with lower case:

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

Remember to also rename the file.

1
votes

Change this one

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

to

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

I just ran into this problem when I was using the MagicTextView by qwerjk. I tried to put the MTV class in a library and use it in my main project. Here's how I got it to work:

  1. In main project assets folder, create a subfolder called fonts
  2. Copy the ttf file into the assets/fonts folder. My filename was camelcase (e.g. ReservoirGrunge.ttf) and so caps or no caps doesn't seem to matter.
  3. In my main project I inflated the MTV view from xml. Make sure the MagicTextView points to the correct library path. For example, my MTV class library was com.library.library_magictextview.MagicTextView and so my main view's xml had to read:

        <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
votes

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

In my case i just deleted the assets folder (that i created manually) and just created a new one using the wizard. Apparently it wasn't read as the assets folder but read as just a normal folder and so getAssets() didn't work and gave me the error.

0
votes

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

0
votes

I was ran in to this issue when i imported a module which was meant to support both eclipse style projects and android studio style project.

I got my issue resolved by removing the assets from the source set as-

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

Or converting the project in to android studio style can also solve the issue I guess.

0
votes

In my case,

I just use the previous code.. So I forget the font file in assets folder..

But I can`t figure out for 2 hours..

Possible cases for this error,

  1. Font file missing
  2. Wrong font name or wrong font extension

for ex: fonts/roboto.ttf instead of fonts/roboto.otf