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


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.