"Native Schrift kann nicht gemacht werden" nur für einige Leute

74

Ich habe eine App, die die Schriftart für einige Elemente ändert. Es funktioniert gut für die meisten Leute, aber vielleicht bekommen 0,5% eine Ausnahme, wenn sie versuchen, die Schriftart zu ändern. Der wesentliche Teil der Stapelverfolgung ist folgender:

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)

Wie gesagt, es funktioniert für die meisten Leute, daher denke ich nicht, dass es ein Problem mit der Schriftartdatei oder meinem Code ist. Irgendwelche Vorschläge, wie man das löst?

Bearbeiten: Dies ist mein Code:

Typeface phoneticFont = Typeface.createFromAsset(getAssets(),
                                                 "fonts/CharisSILR.ttf");
TextView tv;
tv = ((TextView) findViewById(R.id.searchPronunciationTitle));
tv.setTypeface(phoneticFont);
user936580
quelle
Ich habe die Frage mit dem Code aktualisiert.
user936580
wo Sie Ihre ttf-Datei ablegen.
Rishabh Agrawal
Was ist die Android-Version, von der Sie diesen Fehler erhalten? Ich habe es von einem GT-i9000, 2.3.6
Bigstones
Ich habe es in Android-Versionen 2.2 und 2.2.2
user936580
Haben Sie < karanbalkar.com/2013/07/… > gesehen? Dies ist eine einfache Möglichkeit, Roboto-Schriftarten in die Android-App einzufügen.
Pranav Jagtap

Antworten:

68

Dieser Fehler des Android-Betriebssystems könnte der Grund für Ihr Problem sein:

Typeface.createFromAsset leckt den Asset-Stream

Wo gibt es auch eine Problemumgehung in diesem Fehlerbericht:

Ich habe die Problemumgehung von HTH so geändert, dass die Methode nicht den Schriftpfad oder das Format annimmt. Der vollständige Pfad des Font-Assets muss als Parameter übergeben werden. Ich habe auch den Aufruf von createFromAsset () in einen Try-Catch-Block eingeschlossen, sodass die get () -Methode null zurückgibt, wenn das Asset nicht gefunden wird.

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);
        }
    }
}
HitOdessit
quelle
4
Vielen Dank. Wenn ich es richtig verstehe, besagt die Beschreibung dieses Fehlers, dass das Problem ein Speicherverlust ist, der zu Speicherfehlern führt. Dies ist jedoch nicht das, was ich sehe: Ich erhalte die Meldung "Native Schrift kann nicht erstellt werden" ohne Ausnahmen wegen Speichermangels. Außerdem sieht es so aus, als würde es für den Benutzer, der fehlschlägt, immer fehlschlagen, und meine Anwendung verwendet nicht viele Ressourcen.
user936580
1
@ user936580 Der catch-Block beim Laden der Schrift vermeidet die Ausnahme, die für Ihren Benutzer explodiert. Der Kompromiss hier ist eine hässliche Schriftart anstelle eines Absturzes. Ich denke, es zahlt sich aus :)
Bolhoso
1
@Hit Wie benutzt / ruft man diese Methode auf? Ich habe versucht herauszufinden.
Compaq LE2202x
Ich habe mir nicht geholfen, die Ausnahme loszuwerden, ABER es geht nicht mehr viel Speicher verloren, wenn ich sie Typefaceszusammen mit der androidsvg- Bibliothek verwende, in der ich mehrere Schriftarten mit der lade SVGExternalFileResolver.
Dirk
52

Ich habe einige der hier gefundenen Lösungen ohne Erfolg verfolgt. Ich dachte, es sei etwas wirklich Dunkles, wie es Programmierer oft tun. Dann könnte ich irgendwo lesen, dass es mit dem Schriftpfad zusammenhängt, gotcha:

Anstatt:

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

Ich wechselte zu:

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

Und meine Datei befindet sich in assets / fonts / blanch_caps.ttf. Nicht, dass es wie ein Zauber wirkt!

joao_dv
quelle
1
Das hat bei mir funktioniert, vielen Dank! obwohl ein kleiner tipp: meine schrift wurde mit großbuchstaben wie "COOPBL.TTF" aufgerufen, also musste ich sie auch mit großbuchstaben in den code schreiben .. vielleicht hilft es jemandem :)
ylka
Behebt es auch fürcreateFromFile
0101100101
50

Dieser Fehler trat auf, als sich die Schriftart im Bibliotheks-Asset-Ordner befand. Als ich es in die Assets der Anwendung kopierte, die diese Bibliothek verwendete, verschwand der Fehler.

Es scheint, dass Assets nicht importiert werden können: Der Assets-Ordner der Android Library wird nicht kopiert

Und hier sind einige andere Fälle: Problem bei Verwendung einer benutzerdefinierten Schriftart - "native Schrift kann nicht erstellt werden"

Lumis
quelle
Vielen Dank, aber ich habe die Schriftart im Anwendungs-Asset-Ordner. Es funktioniert in den meisten Fällen, aber für einige Leute funktioniert es nicht, ich weiß nicht warum.
user936580
Gut zu wissen. Ich habe versucht, jede benutzerdefinierte Schriftart zu laden. Wenn ein Fehler auftritt, wird standardmäßig die eingebaute Android-Schriftart verwendet, falls eine ttf-Schriftart auf einigen Geräten nicht funktioniert.
Lumis
Ich denke, das liegt daran, dass Sie den Kontext Ihrer Anwendung getAssets()nicht für die Bibliothek verwenden ... +1 hat für mich funktioniert.
Saeed.re
25

Ich hatte viel damit zu kämpfen. Ich habe jede Möglichkeit ausprobiert und nichts hilft. Am Ende war das Problem woanders. Wenn Sie Ihr Projekt mit Gradle erstellen, vergessen Sie nicht, diese Zeilen in die Datei build.gradle einzufügen. Dies löste das Problem in meinem Fall.

    sourceSets {
    main {
        assets.srcDirs = ['assets']
    }
}
Michal
quelle
1
Danke für die Antwort. Ich benutze Eclipse, das ist also nicht mein Problem.
user936580
10
Wenn wir Android Studio und Gradle verwenden - Sehen Sie sich das an. Das Vermögensverzeichnis sollte sich direkt unter main befinden. Dies löste mein Problem. Hatte kein Problem mit dem Schriftnamen und der Schriftdatei. Dies ist besonders wichtig, da der von uns verwendete Schriftname Groß- / Kleinbuchstaben enthielt, während der Name der Asset-Datei nur Kleinbuchstaben enthalten sollte.
Herr B
15
Unter Android Studio (derzeit 0.8.1) musste ich die Zeilen nicht hinzufügen build.gradle, aber ich musste meinen Assets-Ordner direkt unter main (z. B. src\main\assets)
ablegen
1
DMans Lösung war perfekt für mich. Ich musste nichts in build.gradle
CodyMace
Diese Antwort war zu diesem Zeitpunkt gültig, als das Gradle Android Plugin unter 0,5 lag und Sie den res-Ordner selbst angeben mussten. Jetzt ist es natürlich nicht nötig!
Michal
7

Sie müssen den Assets-Ordner in src -> main in AndroidStudio erstellen . Dieser Weg hat funktioniert!

Madi
quelle
4

In meinem Fall basierte es auf dem Dateinamen der Schriftart. Aus irgendeinem Grund wurde es FontName..ttf genannt

Ich weiß nicht, warum die Doppelpunkte dort waren - ich habe die Originalschrift nachgeschlagen und sie befanden sich in meinem Ordner windows \ fonts als FontName..ttf. Windows war das anscheinend egal, aber Android flippte aus. Ich habe die Datei umbenannt und jetzt ist alles glücklich.

Tab
quelle
4

Für meinen Fall habe ich festgestellt, dass sich der Assets- Ordner in befindet, /main/java/assetsaber sie müssen sich in befinden/main/assets

Chulo
quelle
Das war es in meinem Fall! Vielen Dank
Adrian L
2

Machen Sie mit Kleinbuchstaben:

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

Denken Sie daran, die Datei auch umzubenennen.

Pedro HCDO
quelle
1

Ändere diesen

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

zu

Typeface phoneticFont = Typeface.createFromAsset(getAssets(),
                                             "CharisSILR.ttf");
Kadir altınok
quelle
Damit funktioniert es nicht, weil ich es im Schriftverzeichnis habe. Ich habe versucht, es in das Stammverzeichnis zu legen, aber es schlägt trotzdem fehl.
user936580
0

Ich bin gerade auf dieses Problem gestoßen, als ich MagicTextView von qwerjk verwendet habe. Ich habe versucht, die MTV-Klasse in eine Bibliothek zu stellen und in meinem Hauptprojekt zu verwenden. So habe ich es zum Laufen gebracht:

  1. Erstellen Sie im Hauptordner für Projektressourcen einen Unterordner mit dem Namen "Schriftarten"
  2. Kopieren Sie die ttf-Datei in den Ordner Assets / Fonts. Mein Dateiname war camelcase (zB ReservoirGrunge.ttf) und daher scheinen Großbuchstaben oder keine Großbuchstaben keine Rolle zu spielen.
  3. In meinem Hauptprojekt habe ich die MTV-Ansicht von XML aufgeblasen. Stellen Sie sicher, dass MagicTextView auf den richtigen Bibliothekspfad zeigt. Zum Beispiel war meine MTV-Klassenbibliothek com.library.library_magictextview.MagicTextView und daher musste die XML-Datei meiner Hauptansicht lauten:

        <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" />
    
Chris Sprague
quelle
0

In unserer Situation hatten wir die Lösung von Hit mit dem Cache verwendet. Das Problem, das wir eingeführt haben, war, dass wir innerhalb desselben try-Blocks auf OTF-Dateien UND TTF-Dateien getestet haben;) Was beim ersten Versuch für OTF offensichtlich fehlschlagen wird, wenn Sie nach einem TTF suchen, aber ich dachte, es lohnt sich, es zu veröffentlichen Nur für den Fall, dass es jemandem nicht auffiel, während er möglicherweise die gleiche Lösung versuchte.

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;
}
neoRiley
quelle
0

In meinem Fall habe ich gerade den Assets-Ordner (den ich manuell erstellt habe) gelöscht und mit dem Assistenten einen neuen erstellt. Anscheinend wurde es nicht als Assets-Ordner gelesen, sondern nur als normaler Ordner, und so funktionierte getAssets () nicht und gab mir den Fehler.

omarwaleed
quelle
0

in android studio: was für mich funktioniert hat ist, die ttf-datei ohne einen unterordner von schriftarten direkt in den vermögensordner zu legen, es hat nicht funktioniert mit dem unterordner ((getAssets (), "fonts / oldengl.ttf") hat nicht funktioniert, wenn Ich hatte die ttf in src / main / assets / fonts). Dies funktioniert: src / main / assets / oldengl.ttf Typeface customfont = Typeface.createFromAsset (getAssets (), "oldengl.ttf");

Stas Krantsov
quelle
0

Ich bin auf dieses Problem gestoßen, als ich ein Modul importierte, das sowohl Projekte im Eclipse-Stil als auch Projekte im Android Studio-Stil unterstützen sollte.

Ich habe mein Problem behoben, indem ich die Assets aus dem Quellensatz entfernt habe.

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

Oder das Konvertieren des Projekts in einen Android Studio-Stil kann das Problem auch lösen, denke ich.

Sanjeet A.
quelle
0

In meinem Fall,

Ich benutze nur den vorherigen Code. Also vergesse ich die Schriftartdatei im Assets-Ordner.

Aber ich kann es 2 Stunden lang nicht herausfinden.

Mögliche Fälle für diesen Fehler,

  1. Schriftdatei fehlt
  2. Falscher Schriftname oder falsche Schriftartenerweiterung

Zum Beispiel: fonts / roboto.ttf anstelle von fonts / roboto.otf

Ranjith Kumar
quelle