我正在尝试在我的Android应用程序中使用Jake Wharton的DiskLruCache,但似乎无法弄清楚如何使用缓存正确地序列化和反序列化对象。在基本的命令行Java程序中使用以下代码:

DiskLruCache.Editor editor = null;
try {
    editor = diskLruCache.edit("objects");

    OutputStream timeOs = editor.newOutputStream(0);
    OutputStream dataOs = editor.newOutputStream(1);
    OutputStream timeBos = new BufferedOutputStream(timeOs);
    OutputStream dataBos = new BufferedOutputStream(dataOs);
    ObjectOutputStream timeOos = new ObjectOutputStream(timeBos);
    ObjectOutputStream dataOos = new ObjectOutputStream(dataBos);

    long createTime = System.currentTimeMillis();

    String str = "testString";

    ArrayList<String> list = new ArrayList<String>();
    list.add("item1");
    list.add("item2");

    timeOos.writeLong(createTime);

    // this works:
    dataOos.writeObject(str);
    // this does not work:
    //dataOos.writeObject(list);

    timeOos.close();
    dataOos.close();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (editor != null)
        try {
            editor.commit();
        } catch (IOException e) {
            e.printStackTrace();
        }
}
timeOos.writeLong(createTime)dataOos.writeObject(str)成功将数据写入缓存,但是用dataOos.writeObject(str)替换dataOos.writeObject(list)不起作用。我已经尝试过ArrayListHashMap,看来它们没有被序列化并写入缓存。该程序执行所有代码,然后挂起一分钟左右,然后返回,仅将journal文件保留在缓存目录中。

我不确定DiskLruCache无法处理容器对象是否会成为问题。

The full source and original post can be found here

编辑(2014-01-03):
Here's a JUnit test using the Android SDKtestStoreLong()testStoreString()testStoreArrayList()通过但testPersistArrayListSnapshot()testPersistArrayListEditor()失败。

这是一个奇怪的问题;如果我在第101行(editor.commit();)处设置了一个断点,则继续执行,将不会创建缓存文件test-store-array-list.0snapshot == null,从而使测试失败。但是,如果我在第103行(DiskLruCache.Snapshot snapshot = mDiskLruCache.get("test-store-array-list");)处设置了一个断点,则会按预期创建文件。

DiskLruCache中可能存在错误;是否有其他兼容Android的磁盘缓存库?

最佳答案

嗯,是Jake Wharton为创建此缓存库而疯狂的道具,但我发现使用起来非常不直观,我发现的所有示例都用于图像缓存。

我已经重新创建了两种可以帮助您的方法

 public void put(String key, Object object)
    {
        DiskLruCache.Editor editor = null;
        try
        {
            editor = mDiskCache.edit(key);
            if (editor == null)
            {
            return;
            }

            ObjectOutputStream out = new ObjectOutputStream(editor.newOutputStream(0));
            out.writeObject(object);
            out.close();
            editor.commit()
        }
catch()...etc

并再次拿出你的物品
    public Object get(String key)
    {
       DiskLruCache.Snapshot snapshot;

       try
       {
            snapshot = mDiskCache.get(key);
            ObjectInputStream in = new ObjectInputStream(snapshot.getInputStream(0));
            return (Object) in.readObject();

        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (ClassNotFoundException ex)
        {
            ex.printStackTrace();
        }
    }

这些是非常基本的get和put方法,您的示例代码对于将对象放入高速缓存似乎有些复杂,我认为这可能是问题所在。调用get()方法后,只需将对象强制转换为所需的任何类型,或者最好更改这些方法以将泛型用于类型安全。

09-12 23:18