【问题标题】:Caching SVG images on Android and memory usage在 Android 上缓存 SVG 图像和内存使用情况
【发布时间】:2013-02-10 15:32:41
【问题描述】:

我正在使用 SVG Android (http://code.google.com/p/svg-android/)。我在我的应用程序的几个活动中使用相同的 svg 文件。建立一个缓存来存储和检索图像是个好主意吗?

我正在使用 SparseArray 以这种方式存储 PictureDrawable(从 SVG 生成):

SVG svg = SVGParser.getSVGFromResource(resources, resourceId);
PictureDrawable pictureDrawable = svg.createPictureDrawable();
cache.put(resourceId, pictureDrawable);

在管理 PictureDrawable 对象时是否需要注意内存使用情况?我确认缓存中的最大项目数将小于 50。

【问题讨论】:

    标签: android image memory-management svg


    【解决方案1】:

    是的,这是一个非常好的主意,只有在第一次运行时,应用程序才会从 svg 为特定设备屏幕尺寸生成图像,并将它们存储在缓存中,然后一直使用这些图像。节省大量 CPU,加快 UI 加载速度。

    但是,我建议保存名称包含应用版本的缓存文件。如果您发布包含一些不同 svg 图像的更新(例如版本 2),则将使用具有不同名称的新文件而不是旧文件。

    Context.getCacheDir() 中最多可以使用 10Mb,系统会在存储空间不足时清理此文件夹。

    另外,作为一个很好的措施,每次初始化 Cache 类时,你可以做一些清理工作,即删除一些旧版本或不需要的项目。

    这是一个我主要用于从 App 缓存目录中保存和获取 Serializable 对象的类:

    public class ObjectCacheFile<T> {
        private final File mFile;
    
        public ObjectCacheFile(Context context, String name) {
            mFile = new File(context.getCacheDir(), name);
        }
    
        public File getFile() {
            return mFile;
        }
    
        public void put(T o) {
    
            try {
    
                if (!mFile.exists()) {
                    mFile.createNewFile();
                }
    
                FileOutputStream fos = new FileOutputStream(mFile);
    
                ObjectOutputStream objOut = new ObjectOutputStream(fos);
    
                try {
                    objOut.writeObject(o);
                } finally {
                    objOut.close();
                }
            } catch (IOException e) {
                Log.e(App.getLogTag(this), "error saving cache file", e);
            }
        }
    
        @SuppressWarnings("unchecked")
        public T get() {
    
            if (!mFile.exists()) {
                return null;
            }
    
            try {
                ObjectInputStream objIn = new ObjectInputStream(new FileInputStream(mFile));
                try {
                    return (T) objIn.readObject();
                } finally {
                    objIn.close();
                }
            } catch (IOException e) {
                Log.e(App.getLogTag(this), "error reading cache file", e);
            } catch (ClassNotFoundException e1) {
                Log.e(App.getLogTag(this), "cache file corrupted, deleting", e1);
                mFile.delete();
            }
    
            return null;
        }
    
    }
    

    【讨论】:

    • 谢谢。实际上我没有将缓存存储在文件中。我正在使用内存!这还是个好主意吗?
    • @Seraphim 在 RAM 中使用缓存?你可以只存储一个变量。当您将项目存储在磁盘上时,缓存会更加有用。
    • 在我的应用程序的多个地方重用同一个 PictureDrawable 有什么好处吗?
    • @Seraphim 是的,由于没有重复对象,内存消耗更少。
    • 是的,但对象不会像往常一样“收集垃圾”。通常,如果我在活动中声明变量,则在销毁活动时会清除引用。如果我保留对 SparseArray 的引用,我会得到应用程序使用的更多内存。是真的吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    相关资源
    最近更新 更多