在 Android 中缓存数据的最佳方式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2004040/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:10:11  来源:igfitidea点击:

Best Way to Cache Data in Android

android

提问by Greg Martin

I have an ArrayListof custom, simple Serializableobjects I would like to cache to disk and read on re-launch. My data is very small, about 25 objects and at most 5 lists so I think SQLite would be overkill. In the iPhone world I would use NSKeyedArchiverand NSKeyedUnarchiverwhich works great. On Android I've attempted to do this with with a FileOutputStreamand ObjectOutputStreamand while the result is the same, the performance is terrible. Is there a better (read faster) way to cache small objects to the file system in Android?

我有一个ArrayList自定义的简单Serializable对象,我想缓存到磁盘并在重新启动时读取。我的数据非常小,大约有 25 个对象,最多有 5 个列表,所以我认为 SQLite 会有点矫枉过正。在 iPhone 世界中,我会使用NSKeyedArchiver并且NSKeyedUnarchiver效果很好。在 Android 上,我尝试使用FileOutputStreamand来做到这一点,ObjectOutputStream虽然结果是一样的,但性能很糟糕。有没有更好(读取更快)的方法将小对象缓存到 Android 中的文件系统?

采纳答案by Bostone

For what it worth I cache some of my String data to disk using BufferedWriter/BufferedReader and it's very fast. Matter of fact it is faster than storing the same data to SharedPreferences. The code goes something like this (note that things happen faster when you provide buffer size)

值得一提的是,我使用 BufferedWriter/BufferedReader 将一些字符串数据缓存到磁盘,而且速度非常快。事实上,它比将相同的数据存储到 SharedPreferences 更快。代码是这样的(请注意,当您提供缓冲区大小时,事情会发生得更快)

final BufferedWriter out = new BufferedWriter(new FileWriter(file), 1024);
out.write(stuff);
out.close();

回答by Vaishali Sutariya

public class MyClass implements Serializable 
{
private static final long serialVersionUID = 1L;

public String title;
public String startTime;
public String endTime;
public String day;

public boolean classEnabled;


public MyClass(String title, String startTime, boolean enable) {
    this.title = title;
    this.startTime = startTime;
    this.classEnabled = enable;
}

public boolean saveObject(MyClass obj) {   
    final File suspend_f=new File(SerializationTest.cacheDir, "test");

    FileOutputStream   fos  = null;
    ObjectOutputStream oos  = null;
    boolean            keep = true;

    try {
        fos = new FileOutputStream(suspend_f);
        oos = new ObjectOutputStream(fos);
        oos.writeObject(obj);
    } catch (Exception e) {
        keep = false;
    } finally {
        try {
            if (oos != null)   oos.close();
            if (fos != null)   fos.close();
            if (keep == false) suspend_f.delete();
    } catch (Exception e) { /* do nothing */ }
    }

    return keep;
}

public MyClass getObject(Context c) {
    final File suspend_f=new File(SerializationTest.cacheDir, "test");

    MyClass simpleClass= null;
    FileInputStream fis = null;
    ObjectInputStream is = null;

    try {
        fis = new FileInputStream(suspend_f);
        is = new ObjectInputStream(fis);
        simpleClass = (MyClass) is.readObject();
    } catch(Exception e) {
        String val= e.getMessage();
    } finally {
        try {
            if (fis != null)   fis.close();
            if (is != null)   is.close();
        } catch (Exception e) { }
    }

    return simpleClass;  
}

and calling from activity

并从活动中调用

 if(android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"MyCustomObject");
else
cacheDir= getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();

MyClass m = new MyClass("umer", "asif", true);
boolean result = m.saveObject(m);

if(result)
Toast.makeText(this, "Saved object", Toast.LENGTH_LONG).show();

else
Toast.makeText(this, "Error saving object", Toast.LENGTH_LONG).show();   

 MyClass m = new MyClass();
 MyClass c = m.getObject(this);

 if(c!= null)

 Toast.makeText(this, "Retrieved object", Toast.LENGTH_LONG).show();

  else

 Toast.makeText(this, "Error retrieving object", Toast.LENGTH_LONG).show();

dont forget to use write_external_storage permissions in manifest file.

不要忘记在清单文件中使用 write_external_storage 权限。

回答by Dave Webb

It's hard to know without profiling but my guess is your poor performance is down to using ObjectOutputStream. Have you tried writing your own writeObject(ObjectOutputStream)and readObject(ObjectOutputStream)methodsas this may help performance.

不进行分析很难知道,但我的猜测是您的性能不佳归结于使用ObjectOutputStream. 您是否尝试过编写自己的方法writeObject(ObjectOutputStream)readObject(ObjectOutputStream)方法,因为这可能有助于提高性能。

You could use the traceviewtool to see exactly where the application is running slow. Have a look at this question for instructions on how to use traceview.

您可以使用该traceview工具准确查看应用程序运行缓慢的位置。查看此问题以获取有关如何使用traceview.