在我的开始活动中,我调用FontFactory.init(getApplicationContext());
将Context设置为FontFactory类。
我还有一个扩展TextView
的类,在这个TextView的构造函数中有setTypeface(FontFactory.Fonts.ROBOTO_LIGHT.getFont());
。因此,首次需要时,而不是之前,在启动期间加载文件中的字体。
问题是有时,不是每次都 启动错误并且应用程序崩溃:
InflateException:二进制XML文件行.. - 错误膨胀类LayoutWithExtendedTextView
由字体nativeCreateFromAsset中的NullPointerException引起,createFRomAsset和FontFactory.loadFont(FontFactory.java:46)
第46行是return Typeface.createFromAsset(assetManager, fontEnum.getPath());
我的FontFactory类:
public final class FontFactory {
public enum Fonts {
ROBOTO_CONDENSED("fonts/Roboto-Condensed.ttf"), ROBOTO_LIGHT(
"fonts/Roboto-Light.ttf"), ROBOTO_MEDIUM(
"fonts/Roboto-Medium.ttf"), ROBOTO_REGULAR(
"fonts/Roboto-Regular.ttf");
private String path;
private Typeface loadedFont = null;
private Fonts(String path) {
this.path = path;
}
public String getPath() {
return path;
}
public void setLoadedFont(Typeface font) {
this.loadedFont = font;
}
public Typeface getFont() {
if (loadedFont == null) {
this.loadedFont = FontFactory.loadFont(this);
}
return loadedFont;
}
}
private static final String TAG = "FontFactory";
private static AssetManager assetManager;
public static void init(Context context) {
assetManager = context.getAssets();
}
private static Typeface loadFont(FontFactory.Fonts fontEnum) {
return Typeface.createFromAsset(assetManager, fontEnum.getPath());
}
}
加载资产时有延迟吗?
谢谢。
答案 0 :(得分:1)
metrhod createFromAsset 调用 nativeCreateFromAsset ,这是本机C ++代码。
static JNINativeMethod gTypefaceMethods[] = {
{ "nativeCreate", "(Ljava/lang/String;I)I", (void*)Typeface_create },
{ "nativeCreateFromTypeface", "(II)I", (void*)Typeface_createFromTypeface },
{ "nativeUnref", "(I)V", (void*)Typeface_unref },
{ "nativeGetStyle", "(I)I", (void*)Typeface_getStyle },
{ "nativeCreateFromAsset", "(Landroid/content/res/AssetManager;Ljava/lang/String;)I",
(void*)Typeface_createFromAsset },
{ "nativeCreateFromFile", "(Ljava/lang/String;)I",
(void*)Typeface_createFromFile }
};
通过代码挖掘,我发现了 Typeface_createFromAsset 的以下实现。
static SkTypeface* Typeface_createFromAsset(JNIEnv* env, jobject,
jobject jassetMgr,
jstring jpath) {
NPE_CHECK_RETURN_ZERO(env, jassetMgr);
NPE_CHECK_RETURN_ZERO(env, jpath);
AssetManager* mgr = assetManagerForJavaObject(env, jassetMgr);
if (NULL == mgr) {
return NULL;
}
AutoJavaStringToUTF8 str(env, jpath);
Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
if (NULL == asset) {
return NULL;
}
return SkTypeface::CreateFromStream(new AssetStream(asset, true));
}
此方法在以下两种情况下返回null:
此外,请阅读问题“Native typeface cannot be made” only for some people,该问题可能提供有关该问题的最完整信息(此处不值得复制/粘贴)