码迷,mamicode.com
首页 > 移动开发 > 详细

Android 字体内存泄露

时间:2015-07-24 20:53:17      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:android   内存泄露   字体   

字体需求

在App开发中,一般都会使用自定义的字体,这些字体美化App的同时,可能还会带来额外的问题,最容易带来的问题就是内存泄露,这里举个实际中遇到的问题作为例子

技术分享

上面的UI,我们需要在Title、Price上做自定义字体。假如我们这么处理这个需求

  • Title
Typeface tf=Typeface.createFromAsset(getAssets(), Consts.LANTING_FONT_PATH);
title.setTypeface(tf);
  • Price
Typeface tf=Typeface.createFromAsset(getAssets(), Consts.LANTING_FONT_PATH);
price.setTypeface(tf);

像上面这么处理,进入这个页面以后,在滚动View的时候会明显卡顿 1S左右, 用户体验相当不好。
接下来看看问题在哪里
跑monkey测试:

发现问题

adb shell dumpsys meminfo 【packgename】

此命令会打出当前应用内存占用情况,如下:

技术分享
技术分享

注意很明显的/assets/fonts/fzlthjw.ttf 出现的N多次,而且每次都是2,M多,这个内存占用相当的恐怖了,很明显出现了内存泄露

那么该如何解决?

解决问题

解决的办法比较简单,因为 Typeface.createFromAsset(…)是个高消耗方法,缓存使用即可。

比如像这样:

protected static final Typeface TYPEFACE = Typeface.createFromAsset(
            application.getAssets(), "fonts/fzlthjw.ttf");  

titile.setTypeface(TYPEFACE );
price.setTypeface(TYPEFACE );

然后我们再次用monkey测试一下:

技术分享

问题得以解决

推荐方法

不过建议上面的Typeface用Manager管理起来,防止不恰当使用引起内存泄露,下面给个简单的Manager类以供参考:

import java.util.HashMap;
import java.util.Map;
import android.app.Application;
import android.content.res.AssetManager;
import android.graphics.Typeface;
public class FontManager {
    private static FontManager FONT_MANAGER;
    private AssetManager mAssetManager;
    private static final Map<String, Typeface> CACHE_FONT_MAP = new HashMap<String, Typeface>();
    private FontManager(Application application) {
        mAssetManager = application.getAssets();
    }
    public static void createInstance(Application application) {
        if (FONT_MANAGER == null) {
            synchronized (FontManager.class) {
                if (FONT_MANAGER == null) {
                    FONT_MANAGER = new FontManager(application);
                }
            }
        }
    }
    public static FontManager getInstance() {
        if (FONT_MANAGER == null) {
            throw new NullPointerException("NullPoint Exception, Please call createInstance first!");
        }
        return FONT_MANAGER;
    }
    public Typeface getFont(FontType type) {
        if (type == null) {
            return null;
        }
        final String key = type.getValue();
        Typeface typeface = null;
        switch (type) {
        case TANG_SH:
            if (CACHE_FONT_MAP.containsKey(key)) {
                return CACHE_FONT_MAP.get(key);
            } else {
                typeface = Typeface.createFromAsset(mAssetManager, "fonts/fzlthjw.ttf");
                CACHE_FONT_MAP.put(key, typeface);
            }
            break;
        default:
            break;
        }
        return typeface;
    }
    public static enum FontType {
        TANG_SH("tang_sh");
        String value;
        FontType(String value) {
            this.value = value;
        }
        public String getValue() {
            return value;
        }
    }
    // -----------------------------------------------------------------------
    // Convenient
    // -----------------------------------------------------------------------
    public static class FLFont {
        public static Typeface getFont(FontType type) {
            try {
                FontManager manager = FontManager.getInstance();
                return manager.getFont(type);
            } catch (NullPointerException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
}

调用的时候在Application中初始化一次

FontManager.createInstance(this); 

然后在使用的时候:

title.setTypeface(FLFont.getFont(FontType.TANG_SH)) 

这样就可以全局避免内存泄露。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Android 字体内存泄露

标签:android   内存泄露   字体   

原文地址:http://blog.csdn.net/linux1s1s/article/details/47045533

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!