Подтвердить что ты не робот

Лучший способ кэшировать данные на Android

У меня есть ArrayList пользовательских, простых Serializable объектов, которые я хотел бы кэшировать на диск и читать при повторном запуске. Мои данные очень маленькие, около 25 объектов и не более 5 списков, поэтому я думаю, что SQLite будет излишним. В мире iPhone я бы использовал NSKeyedArchiver и NSKeyedUnarchiver, который отлично работает. На Android я попытался сделать это с помощью FileOutputStream и ObjectOutputStream, и, в то время как результат тот же, производительность ужасная. Есть ли лучший (более быстрый) способ кэширования небольших объектов в файловую систему в Android?

4b9b3361

Ответ 1

Для чего стоит кешировать некоторые из моих данных String на диск с помощью BufferedWriter/BufferedReader, и это очень быстро. Фактически это быстрее, чем хранить те же данные в SharedPreferences. Код выглядит примерно так (обратите внимание, что все происходит быстрее, когда вы указываете размер буфера)

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

Ответ 2

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

Не забывайте использовать разрешения write_external_storage в файле манифеста.

Ответ 3

Трудно знать без профилирования, но я предполагаю, что ваша низкая производительность сводится к использованию ObjectOutputStream. Вы пробовали написать собственный writeObject(ObjectOutputStream) и readObject(ObjectOutputStream), поскольку это может помочь в производительности.

Вы можете использовать инструмент traceview, чтобы увидеть, где именно работает приложение. Посмотрите На этот вопрос для получения инструкций по использованию traceview.