“Рідний шрифт не можна робити” лише для деяких людей


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

Я оновив запитання кодом.
— user936580

куди ви поклали свій файл ttf.
— Rishabh Agrawal

яка версія Android, з якої ви отримуєте цю помилку? Я отримав його від GT-i9000, 2.3.6
— bigstones

Я отримав це у версіях Android 2.2 та 2.2.2
— user936580

Ви бачили < karanbalkar.com/2013/07/… >? це простий спосіб додати шрифт roboto до програми для Android.
— Pranav Jagtap

Відповіді:


68

Ця помилка ОС Android може бути причиною вашої проблеми:

Typeface.createFromAsset витікає потік активів

Де також є обхідний шлях у цьому звіті про помилки:

Я змінив обхідний шлях 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);
        }
    }
}

4
Дякую. Якщо я правильно розумію, в описі цієї помилки сказано, що проблема полягає у витоку пам'яті, який спровокує помилки в пам'яті. Однак це не те, що я бачу: я отримую повідомлення "рідний шрифт неможливо зробити" без винятків з пам'яті. Крім того, схоже, що користувач завжди зазнає невдачі, і моя програма не використовує багато ресурсів.
— user936580

1
@ user936580 блок catch під час завантаження гарнітури дозволить уникнути винятку, який вибухне для вашого користувача. Компроміс тут - потворний шрифт замість краху. Думаю, це платить :)
— Болхосо,

1
@Hit Як ​​ти використовуєш / викликаєш цей метод? Я намагався це зрозуміти.
— Compaq LE2202x

Я не допоміг мені позбутися винятку, АЛЕ він перестає витікати тонн пам'яті, якщо я використовую Typefacesразом з бібліотекою androidsvg , де я завантажую кілька шрифтів за допомогою SVGExternalFileResolver.
— Дірк

52

Я дотримався деяких рішень, знайдених тут, без успіху. Я думав, що це щось справді неясне, як це часто роблять програмісти. Тоді десь я прочитав, що це може бути пов’язано із шляхом шрифту, gotcha:

Замість:

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

Я змінив на:

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

І мій файл знаходиться в assets / fonts / blanch_caps.ttf. Не це працює як шарм!


1
це справді спрацювало для мене, велике спасибі! хоча невелика підказка: мій шрифт називався з великих літер, наприклад "COOPBL.TTF", тому мені довелося писати його в коді також великими літерами .. можливо, це комусь допомагає :)
— ylka

Також виправлено наcreateFromFile
— 0101100101

50

Ця помилка виникла, коли шрифт знаходився в папці ресурсу бібліотеки. Коли я скопіював його в активи програми, яка використовувала цю бібліотеку, помилка зникла.

Здається, об’єкти не можна імпортувати: папка об’єктів бібліотеки Android не копіюється

І ось деякі інші випадки: Проблема під час користувальницького шрифту - "рідний шрифт зробити не можна"


Дякую, але у мене є шрифт у папці активів програми. Це працює в більшості випадків, але для деяких людей це не працює, я не знаю чому.
— user936580

Добре знати. Я розмістив функцію try / catch під час завантаження кожного користувацького шрифту, якщо помилка буде за замовчуванням вбудованим шрифтом android, якщо шрифт ttf не працює на деяких пристроях.
— Lumis

Думаю, це тому, що ви використовуєте контекст вашого додатка, а getAssets()не бібліотеку ... +1 працював у мене.
— Saeed.re

25

Я багато з цим боровся. Я перепробував усі можливості, і нічого не допомагає. Зрештою, проблема була десь в іншому місці. Якщо ви будуєте свій проект за допомогою Gradle, не забудьте додати ці рядки у файл build.gradle. Це вирішило проблему в моєму випадку.

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

1
Дякую за відповідь. Я використовую Eclipse, тому це не моя проблема.
— user936580

10
якщо ми використовуємо Android studio і gradle - дивіться це. Регістр активів повинен знаходитись безпосередньо під основним. Це вирішило мою проблему. Не виникли проблеми з назвою шрифту та файлом шрифту. Це особливо важливо, оскільки назва шрифту, яку ми використовували, мала великі / малі регістри, тоді як назва файлу активів повинна бути нижчою.
— містер Б,

15
В ОС Android Studio (на даний момент 0.8.1) мені не потрібно було додавати рядки build.gradle, але папку активів потрібно було розміщувати безпосередньо під основною (наприклад, src\main\assets)
— Dominic K

1
Рішення DMan мені було ідеально підходить. Мені не потрібно було нічого робити в build.gradle
— CodyMace

Ця відповідь була дійсною на той час, коли плагін для Android Gradle був нижче 0,5, і вам потрібно було вказати папку res самостійно. Тепер це не потрібно, звичайно!
— Міхал

7

Ви повинні створити папку активів всередині src -> main в AndroidStudio. Цей спосіб спрацював!


4

У моєму випадку це базувалося на назві файлу шрифту. Чомусь його назвали FontName..ttf

Я не знаю, чому там були подвійні крапки - я шукав оригінальний шрифт, і вони знаходились у моїй папці windows \ fonts як FontName..ttf. Windows, мабуть, не хвилював, але Android злякався. Я перейменував файл, і зараз це все задоволено.


4

Для мого випадку я виявив, що папка активів знаходиться в, /main/java/assetsале вони повинні бути/main/assets


Це було в моєму випадку! Подяка
— Адріан Л

2

З малою літерою:

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

Не забудьте також перейменувати файл.


1

Змініть цей

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

до

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

З огляду на це це не спрацьовує, оскільки у мене це є в каталозі шрифтів. Я намагався помістити його в кореневий каталог, але він все одно не вдається.
— user936580

0

Я просто зіткнувся з цією проблемою, коли використовував MagicTextView від qwerjk. Я намагався розмістити клас MTV у бібліотеці та використати його у своєму головному проекті. Ось як я змусив це працювати:

  1. У папці основних ресурсів проекту створіть підпапку, яка називається шрифтами
  2. Скопіюйте файл ttf у папку ресурси / шрифти. Моє ім'я файлу було верблюдом (наприклад, ReservoirGrunge.ttf), тому, здається, великі та відсутні шапки не мають значення.
  3. У своєму основному проекті я завищив перегляд MTV з xml. Переконайтеся, що 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" />
    

0

У нашій ситуації ми застосували рішення Hit з кешем. Проблема, яку ми представили, полягала в тому, що ми тестували файли OTF І файли TTF у тому самому блоці спроб;) Що, очевидно, не вдасться з першої спроби 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;
}

0

У моєму випадку я просто видалив папку активів (яку я створив вручну) і просто створив нову за допомогою майстра. Очевидно, його не читали як папку активів, а читали як звичайну папку, тому getAssets () не працював і дав мені помилку.


0

в андроїд-студії: у мене спрацювало те, що файл ttf розміщується прямо в папці активів без підпапки шрифтів, він не працює з підпапкою ((getAssets (), "fonts / oldengl.ttf") не працює, коли я мав ttf у src / main / assets / fonts). це працює: src / main / assets / oldengl.ttf Typeface customfont = Typeface.createFromAsset (getAssets (), "oldengl.ttf");


0

До цього випуску я зіткнувся, коли імпортував модуль, який мав на меті підтримувати як проекти в стилі eclipse, так і проект в стилі андроїд.

Я вирішив свою проблему, видаливши активи з набору джерел як

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

Або перетворення проекту в стилі андроїд-студії також може вирішити проблему, на мою думку.


0

У моєму випадку

Я просто використовую попередній код .. Тому я забуваю файл шрифту в папці активів ..

Але я не можу зрозуміти протягом 2 годин ..

Можливі випадки цієї помилки,

  1. Файл шрифту відсутній
  2. Неправильна назва шрифту або неправильне розширення шрифту

наприклад: шрифти / roboto.ttf замість шрифтів / roboto.otf

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.