代码之家  ›  专栏  ›  技术社区  ›  Greg Martin

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

  •  24
  • Greg Martin  · 技术社区  · 15 年前

    我有一个 ArrayList 习惯的,简单的 Serializable 我要缓存到磁盘并在重新启动时读取的对象。我的数据非常小,大约有25个对象,最多有5个列表,所以我认为sqlite会被过度杀戮。在iPhone世界里我会用 NSKeyedArchiver NSKeyedUnarchiver 效果很好。在Android上,我尝试用 FileOutputStream ObjectOutputStream 虽然结果是一样的,但表现很糟糕。在Android中,有没有更好(更快)的方法将小对象缓存到文件系统中?

    3 回复  |  直到 8 年前
        1
  •  19
  •   Bostone    15 年前

    我用bufferedwriter/bufferedreader将一些字符串数据缓存到磁盘上,这样做很快。事实上,它比将相同的数据存储到共享的引用更快。代码是这样的(请注意,当您提供缓冲区大小时,事情发生得更快)

    final BufferedWriter out = new BufferedWriter(new FileWriter(file), 1024);
    out.write(stuff);
    out.close();
    
        2
  •  4
  •   Vaishali Sutariya    10 年前
    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;  
    }
    

    从活动中呼叫

     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();
    

    不要忘记在清单文件中使用写外部存储权限。

        3
  •  3
  •   Community CDub    7 年前

    没有分析很难知道,但我猜你的糟糕性能是由使用 ObjectOutputStream .你试过自己写吗 writeObject(ObjectOutputStream) and readObject(ObjectOutputStream) methods 因为这可能有助于提高性能。

    你可以用 traceview 工具可以精确查看应用程序的运行速度。看一看 at this question for instructions on how to use traceview .